Prompt Server Example
Version: v1.4.0+
Features: Prompts, System/User Messages, Dynamic Arguments
Complexity: Beginner
Overview
A simple MCP server demonstrating prompt templates with:
- ✅ System messages - Define AI behavior and context
- ✅ User messages - Templated prompts with placeholders
- ✅ Dynamic arguments - Inject values at runtime
- ✅ Argument schemas - Type-safe parameter definitions
- ✅ Enum arguments - Constrained values (e.g., “Good”, “Naughty”)
Perfect for:
- Learning prompt template patterns
- Understanding system vs user messages
- Creating reusable AI prompts
- Standardizing prompt formats
Quick Start
Run the Server
cd Examples/PromptMcpServer
dotnet run
Server starts at: http://localhost:5000
Test Prompts
# List all prompts
curl -X POST http://localhost:5000/mcp \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2025-11-25" \
-d '{
"jsonrpc": "2.0",
"method": "prompts/list",
"id": 1
}'
# Get a prompt with arguments
curl -X POST http://localhost:5000/mcp \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2025-11-25" \
-d '{
"jsonrpc": "2.0",
"method": "prompts/get",
"params": {
"name": "santa_report_prompt",
"arguments": {
"name": "Alice",
"behavior": "Good"
}
},
"id": 2
}'
Available Prompts
santa_report_prompt
A whimsical prompt for sending reports to Santa Claus.
Arguments:
name(string, required) - Name of the childbehavior(enum, required) - Behavior: “Good” or “Naughty”
System message:
“You are a very helpful assistant for Santa Claus.”
User message template:
$”Send a letter to Santa Claus and tell him that {args.Name} has behaved {args.Behavior}.”
Example usage:
curl -X POST http://localhost:5000/mcp \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2025-11-25" \
-d '{
"jsonrpc": "2.0",
"method": "prompts/get",
"params": {
"name": "santa_report_prompt",
"arguments": {
"name": "Bob",
"behavior": "Naughty"
}
},
"id": 1
}'
Response:
{
"jsonrpc": "2.0",
"result": {
"description": "A prompt that reports to Santa Claus",
"messages": [
{
"role": "system",
"content": {
"type": "text",
"text": "You are a very helpful assistant for Santa Claus."
}
},
{
"role": "user",
"content": {
"type": "text",
"text": "Send a letter to Santa Claus and tell him that Bob has behaved Naughty."
}
}
]
},
"id": 1
}
Code Implementation
Prompt Definition
using Mcp.Gateway.Tools;
public class SimplePrompt
{
public record SantaReportPromptRequest(
[property: JsonPropertyName("name")]
[property: DisplayName("Child's Name")] // title
[property: Description("Name of the child")] string Name,
[property: JsonPropertyName("behavior")]
[property: DisplayName("Child's Behavior")] // title
[property: Description("Behavior of the child (e.g., Good, Naughty)")] BehaviorEnum Behavior);
public enum BehaviorEnum
{
Good,
Naughty
}
[McpPrompt(Description = "Report to Santa Claus")]
public JsonRpcMessage SantaReportPrompt(TypedJsonRpc<SantaReportPromptRequest> request)
{
var args = request.GetParams()
?? throw new ToolInvalidParamsException(
"Parameters 'name' and 'behavior' are required and must be strings.");
return ToolResponse.Success(
request.Id,
new PromptResponse
{
Description = "A prompt that reports to Santa Claus",
Messages = [
new(
PromptRole.System,
new TextContent {
Text = "You are a very helpful assistant for Santa Claus."
}),
new (
PromptRole.User,
new TextContent {
Text = $"Send a letter to Santa Claus and tell him that {args.Name} has behaved {args.Behavior}."
})
]
}
);
}
}
Key Components
1. McpPrompt Attribute
[McpPrompt(Description = "Report to Santa Claus")]
- Marks the method as a prompt
- Optional description for AI clients
2. PromptResponse Structure
new PromptResponse
{
Description = "...", // Human-readable description
Messages = [...], // System and user messages
}
3. System Message
new PromptMessage(
PromptRole.System,
new TextContent {
Text = "You are a very helpful assistant for Santa Claus."
})
- Sets AI behavior and context
- Always processed first by LLMs
4. User Message with Placeholders
new PromptMessage(
PromptRole.User,
new TextContent {
Text = $"Send a letter to Santa Claus and tell him that {args.Name} has behaved {args.Behavior}."
})
- Template with
{args.Name}and{args.Behavior}placeholders
Prompt + Tool Combination
The example also includes a tool in the same class:
public record LetterToSantaRequest(
[property: Description("Name of the child")]
string Name,
[property: Description("Behavior of the child")]
BehaviorEnum Behavior,
[property: Description("Email address to Santa Claus")]
string? SantaEmailAddress);
public enum BehaviorEnum
{
Good,
Naughty
}
[McpTool(Description = "Send letter to Santa Claus")]
public JsonRpcMessage LetterToSanta(TypedJsonRpc<LetterToSantaRequest> request)
{
var args = request.GetParams()
?? throw new ToolInvalidParamsException(
"Parameters 'name' and 'behavior' are required.");
// Send letter logic here...
return ToolResponse.Success(request.Id, new { sent = true });
}
Pattern: Prompts and tools can coexist in the same class!
- Prompt: Generates AI instructions
- Tool: Executes actual operations
Testing Prompts
Test prompts/list
curl -X POST http://localhost:5000/mcp \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2025-11-25" \
-d '{
"jsonrpc": "2.0",
"method": "prompts/list",
"id": 1
}'
Response:
{
"jsonrpc": "2.0",
"result": {
"prompts": [
{
"name": "santa_report_prompt",
"description": "Report to Santa Claus",
"arguments": [
{
"name": "name",
"description": "Name of the child",
"required": true
},
{
"name": "behavior",
"description": "Behavior of the child (e.g., Good, Naughty)",
"required": true
}
]
}
]
},
"id": 1
}
Test prompts/get
curl -X POST http://localhost:5000/mcp \
-H "Content-Type: application/json" \
-H "MCP-Protocol-Version: 2025-11-25" \
-d '{
"jsonrpc": "2.0",
"method": "prompts/get",
"params": {
"name": "santa_report_prompt",
"arguments": {
"name": "Charlie",
"behavior": "Good"
}
},
"id": 2
}'
Response:
{
"jsonrpc": "2.0",
"result": {
"description": "A prompt that reports to Santa Claus",
"messages": [
{
"role": "system",
"content": {
"type": "text",
"text": "You are a very helpful assistant for Santa Claus."
}
},
{
"role": "user",
"content": {
"type": "text",
"text": "Send a letter to Santa Claus and tell him that Charlie has behaved Good."
}
}
]
},
"id": 2
}
JavaScript Client Example
// 1. List all prompts
async function listPrompts() {
const response = await fetch('http://localhost:5000/mcp', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'MCP-Protocol-Version': '2025-11-25'
},
body: JSON.stringify({
jsonrpc: '2.0',
method: 'prompts/list',
id: 1
})
});
const result = await response.json();
console.log('Available prompts:', result.result.prompts);
return result.result.prompts;
}
// 2. Get prompt with arguments
async function getPrompt(name, args) {
const response = await fetch('http://localhost:5000/mcp', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'MCP-Protocol-Version': '2025-11-25'
},
body: JSON.stringify({
jsonrpc: '2.0',
method: 'prompts/get',
params: { name, arguments: args },
id: 2
})
});
const result = await response.json();
return result.result;
}
// 3. Use the prompt
const prompt = await getPrompt('santa_report_prompt', {
name: 'Alice',
behavior: 'Good'
});
console.log('System message:', prompt.messages[0].content);
console.log('User message:', prompt.messages[1].content);
// 4. Send to LLM (e.g., OpenAI)
const completion = await openai.chat.completions.create({
model: 'gpt-4',
messages: prompt.messages.map(m => ({
role: m.role,
content: m.content
}))
});
console.log('AI response:', completion.choices[0].message.content);
Integration Tests
The PromptMcpServerTests project includes comprehensive tests:
cd Examples/PromptMcpServerTests
dotnet test
Best Practices
1. Clear System Messages
// ✅ GOOD - Specific role and behavior
new PromptMessage(
PromptRole.System,
new TextContent {
Text = "You are an experienced Python developer. Focus on PEP 8 style and performance."
})
// ❌ BAD - Too vague
new PromptMessage(
PromptRole.System,
new TextContent {
Text = "You are helpful."
})
Use Cases
1. Standardized AI Instructions
Create consistent prompts across your organization:
- Code reviews with company standards
- Documentation following style guide
- SQL queries with security policies
2. Template Library
Build reusable prompt templates:
- Marketing copy generation
- Technical support responses
- Data analysis instructions
3. Multi-Language Support
Define prompts once, use in multiple languages:
"Translate '' from to "
4. Context-Aware Prompts
Inject runtime context:
"Using project context , review this file: <h1 id="pagination-server-example">Pagination Server Example</h1>
<p><strong>Version:</strong> v1.7.0+<br />
<strong>Features:</strong> Pagination, Tools, Prompts, Resources<br />
<strong>Complexity:</strong> Beginner</p>
<h2 id="overview">Overview</h2>
<p>A test server for demonstrating MCP pagination with:</p>
<ul>
<li>✅ <strong>120 mock tools</strong> - Test <code class="language-plaintext highlighter-rouge">tools/list</code> pagination</li>
<li>✅ <strong>120 mock prompts</strong> - Test <code class="language-plaintext highlighter-rouge">prompts/list</code> pagination</li>
<li>✅ <strong>120 mock resources</strong> - Test <code class="language-plaintext highlighter-rouge">resources/list</code> pagination</li>
<li>✅ <strong>Cursor-based pagination</strong> - Efficient pagination pattern</li>
</ul>
<p>Perfect for:</p>
<ul>
<li>Testing pagination implementation</li>
<li>Understanding cursor-based pagination</li>
<li>Load testing with many tools/prompts/resources</li>
<li>Client-side pagination testing</li>
</ul>
<h2 id="quick-start">Quick Start</h2>
<h3 id="run-the-server">Run the Server</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd </span>Examples/PaginationMcpServer
dotnet run
</code></pre></div></div>
<p>Server starts at: <code class="language-plaintext highlighter-rouge">http://localhost:5000</code></p>
<h3 id="test-pagination">Test Pagination</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># List first page of tools (default page size: 50)</span>
curl <span class="nt">-X</span> POST http://localhost:5000/rpc <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"MCP-Protocol-Version: 2025-11-25"</span> <span class="se">\</span>
<span class="nt">-d</span> <span class="s1">'{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 1
}'</span>
<span class="c"># List second page with cursor</span>
curl <span class="nt">-X</span> POST http://localhost:5000/rpc <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"MCP-Protocol-Version: 2025-11-25"</span> <span class="se">\</span>
<span class="nt">-d</span> <span class="s1">'{
"jsonrpc": "2.0",
"method": "tools/list",
"params": {
"cursor": "50"
},
"id": 2
}'</span>
</code></pre></div></div>
<h2 id="available-collections">Available Collections</h2>
<h3 id="tools-120-mock-tools">Tools (120 mock tools)</h3>
<ul>
<li><code class="language-plaintext highlighter-rouge">mock_tool_001</code> through <code class="language-plaintext highlighter-rouge">mock_tool_120</code></li>
<li>Each tool returns its index: <code class="language-plaintext highlighter-rouge">{ "index": 1 }</code></li>
<li>Perfect for testing <code class="language-plaintext highlighter-rouge">tools/list</code> pagination</li>
</ul>
<h3 id="prompts-120-mock-prompts">Prompts (120 mock prompts)</h3>
<ul>
<li><code class="language-plaintext highlighter-rouge">mock_prompt_001</code> through <code class="language-plaintext highlighter-rouge">mock_prompt_120</code></li>
<li>Each prompt has a description and arguments</li>
<li>Perfect for testing <code class="language-plaintext highlighter-rouge">prompts/list</code> pagination</li>
</ul>
<h3 id="resources-120-mock-resources">Resources (120 mock resources)</h3>
<ul>
<li><code class="language-plaintext highlighter-rouge">mock://resource/001</code> through <code class="language-plaintext highlighter-rouge">mock://resource/120</code></li>
<li>Each resource returns mock data</li>
<li>Perfect for testing <code class="language-plaintext highlighter-rouge">resources/list</code> pagination</li>
</ul>
<h2 id="pagination-behavior">Pagination Behavior</h2>
<h3 id="default-page-size">Default Page Size</h3>
<p><strong>50 items per page</strong> (MCP protocol default)</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"jsonrpc"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2.0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"method"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tools/list"</span><span class="p">,</span><span class="w">
</span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p><strong>Response:</strong></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"jsonrpc"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2.0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"result"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"tools"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mock_tool_001"</span><span class="p">,</span><span class="w"> </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Mock tool 001"</span><span class="w"> </span><span class="p">},</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mock_tool_002"</span><span class="p">,</span><span class="w"> </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Mock tool 002"</span><span class="w"> </span><span class="p">},</span><span class="w">
</span><span class="err">...</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mock_tool_050"</span><span class="p">,</span><span class="w"> </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Mock tool 050"</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="p">],</span><span class="w">
</span><span class="nl">"nextCursor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"50"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h3 id="second-page">Second Page</h3>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"jsonrpc"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2.0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"method"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tools/list"</span><span class="p">,</span><span class="w">
</span><span class="nl">"params"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"cursor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"50"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p><strong>Response:</strong></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"jsonrpc"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2.0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"result"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"tools"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mock_tool_051"</span><span class="p">,</span><span class="w"> </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Mock tool 051"</span><span class="w"> </span><span class="p">},</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mock_tool_052"</span><span class="p">,</span><span class="w"> </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Mock tool 052"</span><span class="w"> </span><span class="p">},</span><span class="w">
</span><span class="err">...</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mock_tool_100"</span><span class="p">,</span><span class="w"> </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Mock tool 100"</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="p">],</span><span class="w">
</span><span class="nl">"nextCursor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"100"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<h3 id="last-page">Last Page</h3>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"jsonrpc"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2.0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"method"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tools/list"</span><span class="p">,</span><span class="w">
</span><span class="nl">"params"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"cursor"</span><span class="p">:</span><span class="w"> </span><span class="s2">"100"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p><strong>Response:</strong></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"jsonrpc"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2.0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"result"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"tools"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mock_tool_101"</span><span class="p">,</span><span class="w"> </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Mock tool 101"</span><span class="w"> </span><span class="p">},</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mock_tool_102"</span><span class="p">,</span><span class="w"> </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Mock tool 102"</span><span class="w"> </span><span class="p">},</span><span class="w">
</span><span class="err">...</span><span class="w">
</span><span class="p">{</span><span class="w"> </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"mock_tool_120"</span><span class="p">,</span><span class="w"> </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Mock tool 120"</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="p">],</span><span class="w">
</span><span class="nl">"nextCursor"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p><strong>Note:</strong> <code class="language-plaintext highlighter-rouge">nextCursor: null</code> indicates no more pages!</p>
<h2 id="testing-all-collections">Testing All Collections</h2>
<h3 id="test-tools-pagination">Test Tools Pagination</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Page 1</span>
curl <span class="nt">-X</span> POST http://localhost:5000/rpc <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"MCP-Protocol-Version: 2025-11-25"</span> <span class="se">\</span>
<span class="nt">-d</span> <span class="s1">'{"jsonrpc":"2.0","method":"tools/list","id":1}'</span>
<span class="c"># Page 2</span>
curl <span class="nt">-X</span> POST http://localhost:5000/rpc <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"MCP-Protocol-Version: 2025-11-25"</span> <span class="se">\</span>
<span class="nt">-d</span> <span class="s1">'{"jsonrpc":"2.0","method":"tools/list","params":{"cursor":"50"},"id":2}'</span>
<span class="c"># Page 3 (last page)</span>
curl <span class="nt">-X</span> POST http://localhost:5000/rpc <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"MCP-Protocol-Version: 2025-11-25"</span> <span class="se">\</span>
<span class="nt">-d</span> <span class="s1">'{"jsonrpc":"2.0","method":"tools/list","params":{"cursor":"100"},"id":3}'</span>
</code></pre></div></div>
<h3 id="test-prompts-pagination">Test Prompts Pagination</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Same pattern as tools</span>
curl <span class="nt">-X</span> POST http://localhost:5000/rpc <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"MCP-Protocol-Version: 2025-11-25"</span> <span class="se">\</span>
<span class="nt">-d</span> <span class="s1">'{"jsonrpc":"2.0","method":"prompts/list","id":1}'</span>
</code></pre></div></div>
<h3 id="test-resources-pagination">Test Resources Pagination</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Same pattern as tools</span>
curl <span class="nt">-X</span> POST http://localhost:5000/rpc <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"MCP-Protocol-Version: 2025-11-25"</span> <span class="se">\</span>
<span class="nt">-d</span> <span class="s1">'{"jsonrpc":"2.0","method":"resources/list","id":1}'</span>
</code></pre></div></div>
<h2 id="javascript-client-example">JavaScript Client Example</h2>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Fetch all tools using pagination</span>
<span class="k">async</span> <span class="kd">function</span> <span class="nf">fetchAllTools</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">cursor</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">allTools</span> <span class="o">=</span> <span class="p">[];</span>
<span class="kd">let</span> <span class="nx">pageNumber</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">do</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Fetching page </span><span class="p">${</span><span class="nx">pageNumber</span><span class="p">}</span><span class="s2">...`</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">fetch</span><span class="p">(</span><span class="dl">'</span><span class="s1">http://localhost:5000/rpc</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
<span class="na">method</span><span class="p">:</span> <span class="dl">'</span><span class="s1">POST</span><span class="dl">'</span><span class="p">,</span>
<span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">'</span><span class="s1">Content-Type</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">application/json</span><span class="dl">'</span><span class="p">,</span>
<span class="dl">'</span><span class="s1">MCP-Protocol-Version</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">2025-11-25</span><span class="dl">'</span>
<span class="p">},</span>
<span class="na">body</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">({</span>
<span class="na">jsonrpc</span><span class="p">:</span> <span class="dl">'</span><span class="s1">2.0</span><span class="dl">'</span><span class="p">,</span>
<span class="na">method</span><span class="p">:</span> <span class="dl">'</span><span class="s1">tools/list</span><span class="dl">'</span><span class="p">,</span>
<span class="na">params</span><span class="p">:</span> <span class="nx">cursor</span> <span class="p">?</span> <span class="p">{</span> <span class="nx">cursor</span> <span class="p">}</span> <span class="p">:</span> <span class="p">{},</span>
<span class="na">id</span><span class="p">:</span> <span class="nx">pageNumber</span>
<span class="p">})</span>
<span class="p">});</span>
<span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">response</span><span class="p">.</span><span class="nf">json</span><span class="p">();</span>
<span class="kd">const</span> <span class="nx">tools</span> <span class="o">=</span> <span class="nx">result</span><span class="p">.</span><span class="nx">result</span><span class="p">.</span><span class="nx">tools</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">nextCursor</span> <span class="o">=</span> <span class="nx">result</span><span class="p">.</span><span class="nx">result</span><span class="p">.</span><span class="nx">nextCursor</span><span class="p">;</span>
<span class="nx">allTools</span><span class="p">.</span><span class="nf">push</span><span class="p">(...</span><span class="nx">tools</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">` → Got </span><span class="p">${</span><span class="nx">tools</span><span class="p">.</span><span class="nx">length</span><span class="p">}</span><span class="s2"> tools (total: </span><span class="p">${</span><span class="nx">allTools</span><span class="p">.</span><span class="nx">length</span><span class="p">}</span><span class="s2">)`</span><span class="p">);</span>
<span class="nx">cursor</span> <span class="o">=</span> <span class="nx">nextCursor</span><span class="p">;</span>
<span class="nx">pageNumber</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span> <span class="k">while </span><span class="p">(</span><span class="nx">cursor</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`\nTotal tools: </span><span class="p">${</span><span class="nx">allTools</span><span class="p">.</span><span class="nx">length</span><span class="p">}</span><span class="s2">`</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">allTools</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// Run it</span>
<span class="nf">fetchAllTools</span><span class="p">().</span><span class="nf">then</span><span class="p">(</span><span class="nx">tools</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">All tools fetched:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">tools</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">First tool:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">tools</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Last tool:</span><span class="dl">'</span><span class="p">,</span> <span class="nx">tools</span><span class="p">[</span><span class="nx">tools</span><span class="p">.</span><span class="nx">length</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]);</span>
<span class="p">});</span>
</code></pre></div></div>
<p><strong>Expected output:</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Fetching page 1...
→ Got 50 tools (total: 50)
Fetching page 2...
→ Got 50 tools (total: 100)
Fetching page 3...
→ Got 20 tools (total: 120)
Total tools: 120
All tools fetched: 120
First tool: { name: 'mock_tool_001', description: 'Mock tool 001' }
Last tool: { name: 'mock_tool_120', description: 'Mock tool 120' }
</code></pre></div></div>
<h2 id="testing-pagination-logic">Testing Pagination Logic</h2>
<p>The PaginationMcpServer is perfect for testing pagination edge cases:</p>
<h3 id="test-cases">Test Cases</h3>
<ol>
<li><strong>First Page</strong> - No cursor
<ul>
<li>Should return first 50 items</li>
<li>Should include <code class="language-plaintext highlighter-rouge">nextCursor: "50"</code></li>
</ul>
</li>
<li><strong>Middle Page</strong> - Cursor: “50”
<ul>
<li>Should return items 51-100</li>
<li>Should include <code class="language-plaintext highlighter-rouge">nextCursor: "100"</code></li>
</ul>
</li>
<li><strong>Last Page</strong> - Cursor: “100”
<ul>
<li>Should return items 101-120 (only 20 items)</li>
<li>Should include <code class="language-plaintext highlighter-rouge">nextCursor: null</code></li>
</ul>
</li>
<li><strong>Empty Page</strong> - Cursor beyond last item
<ul>
<li>Should return empty array</li>
<li>Should include <code class="language-plaintext highlighter-rouge">nextCursor: null</code></li>
</ul>
</li>
</ol>
<h3 id="integration-tests">Integration Tests</h3>
<p>The PaginationMcpServerTests project includes comprehensive tests:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd </span>Examples/PaginationMcpServerTests
dotnet <span class="nb">test</span>
</code></pre></div></div>
<p><strong>Test coverage:</strong></p>
<ul>
<li>✅ First page pagination</li>
<li>✅ Middle page pagination</li>
<li>✅ Last page pagination</li>
<li>✅ Empty page handling</li>
<li>✅ Invalid cursor handling</li>
<li>✅ All three collections (tools, prompts, resources)</li>
</ul>
<h2 id="code-examples">Code Examples</h2>
<h3 id="server-side-mock-tools">Server-Side Mock Tools</h3>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">partial</span> <span class="k">class</span> <span class="nc">MockTools</span>
<span class="p">{</span>
<span class="p">[</span><span class="nf">McpTool</span><span class="p">(</span><span class="s">"mock_tool_001"</span><span class="p">,</span> <span class="n">Description</span> <span class="p">=</span> <span class="s">"Mock tool 001"</span><span class="p">)]</span>
<span class="k">public</span> <span class="n">JsonRpcMessage</span> <span class="nf">Tool001</span><span class="p">(</span><span class="n">JsonRpcMessage</span> <span class="n">r</span><span class="p">)</span>
<span class="p">=></span> <span class="n">ToolResponse</span><span class="p">.</span><span class="nf">Success</span><span class="p">(</span><span class="n">r</span><span class="p">.</span><span class="n">Id</span><span class="p">,</span> <span class="k">new</span> <span class="p">{</span> <span class="n">index</span> <span class="p">=</span> <span class="m">1</span> <span class="p">});</span>
<span class="p">[</span><span class="nf">McpTool</span><span class="p">(</span><span class="s">"mock_tool_002"</span><span class="p">,</span> <span class="n">Description</span> <span class="p">=</span> <span class="s">"Mock tool 002"</span><span class="p">)]</span>
<span class="k">public</span> <span class="n">JsonRpcMessage</span> <span class="nf">Tool002</span><span class="p">(</span><span class="n">JsonRpcMessage</span> <span class="n">r</span><span class="p">)</span>
<span class="p">=></span> <span class="n">ToolResponse</span><span class="p">.</span><span class="nf">Success</span><span class="p">(</span><span class="n">r</span><span class="p">.</span><span class="n">Id</span><span class="p">,</span> <span class="k">new</span> <span class="p">{</span> <span class="n">index</span> <span class="p">=</span> <span class="m">2</span> <span class="p">});</span>
<span class="c1">// ... 118 more tools ...</span>
<span class="p">[</span><span class="nf">McpTool</span><span class="p">(</span><span class="s">"mock_tool_120"</span><span class="p">,</span> <span class="n">Description</span> <span class="p">=</span> <span class="s">"Mock tool 120"</span><span class="p">)]</span>
<span class="k">public</span> <span class="n">JsonRpcMessage</span> <span class="nf">Tool120</span><span class="p">(</span><span class="n">JsonRpcMessage</span> <span class="n">r</span><span class="p">)</span>
<span class="p">=></span> <span class="n">ToolResponse</span><span class="p">.</span><span class="nf">Success</span><span class="p">(</span><span class="n">r</span><span class="p">.</span><span class="n">Id</span><span class="p">,</span> <span class="k">new</span> <span class="p">{</span> <span class="n">index</span> <span class="p">=</span> <span class="m">120</span> <span class="p">});</span>
<span class="p">}</span>
</code></pre></div></div>
<p><strong>Why partial class?</strong></p>
<ul>
<li>Split into 3 files for better organization</li>
<li>Part1.cs: Tools 001-040</li>
<li>Part2.cs: Tools 041-080</li>
<li>Part3.cs: Tools 081-120</li>
</ul>
<h3 id="server-side-mock-prompts">Server-Side Mock Prompts</h3>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">MockPrompts</span>
<span class="p">{</span>
<span class="p">[</span><span class="nf">McpPrompt</span><span class="p">(</span><span class="s">"mock_prompt_001"</span><span class="p">,</span>
<span class="n">Description</span> <span class="p">=</span> <span class="s">"Mock prompt 001"</span><span class="p">,</span>
<span class="n">Arguments</span> <span class="p">=</span> <span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="s">"arg1"</span><span class="p">,</span> <span class="s">"arg2"</span> <span class="p">})]</span>
<span class="k">public</span> <span class="n">JsonRpcMessage</span> <span class="nf">Prompt001</span><span class="p">(</span><span class="n">JsonRpcMessage</span> <span class="n">r</span><span class="p">)</span>
<span class="p">=></span> <span class="n">ToolResponse</span><span class="p">.</span><span class="nf">Success</span><span class="p">(</span><span class="n">r</span><span class="p">.</span><span class="n">Id</span><span class="p">,</span> <span class="k">new</span>
<span class="p">{</span>
<span class="n">description</span> <span class="p">=</span> <span class="s">"Mock prompt 001"</span><span class="p">,</span>
<span class="n">arguments</span> <span class="p">=</span> <span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="s">"arg1"</span><span class="p">,</span> <span class="s">"arg2"</span> <span class="p">}</span>
<span class="p">});</span>
<span class="c1">// ... 119 more prompts ...</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="server-side-mock-resources">Server-Side Mock Resources</h3>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">MockResources</span>
<span class="p">{</span>
<span class="p">[</span><span class="nf">McpResource</span><span class="p">(</span><span class="s">"mock://resource/001"</span><span class="p">,</span>
<span class="n">Name</span> <span class="p">=</span> <span class="s">"Mock Resource 001"</span><span class="p">,</span>
<span class="n">Description</span> <span class="p">=</span> <span class="s">"Mock resource for testing"</span><span class="p">,</span>
<span class="n">MimeType</span> <span class="p">=</span> <span class="s">"text/plain"</span><span class="p">)]</span>
<span class="k">public</span> <span class="n">JsonRpcMessage</span> <span class="nf">Resource001</span><span class="p">(</span><span class="n">JsonRpcMessage</span> <span class="n">r</span><span class="p">)</span>
<span class="p">=></span> <span class="n">ToolResponse</span><span class="p">.</span><span class="nf">Success</span><span class="p">(</span><span class="n">r</span><span class="p">.</span><span class="n">Id</span><span class="p">,</span> <span class="k">new</span> <span class="nf">ResourceContent</span><span class="p">(</span>
<span class="n">Uri</span><span class="p">:</span> <span class="s">"mock://resource/001"</span><span class="p">,</span>
<span class="n">MimeType</span><span class="p">:</span> <span class="s">"text/plain"</span><span class="p">,</span>
<span class="n">Text</span><span class="p">:</span> <span class="s">"Mock resource 001 content"</span>
<span class="p">));</span>
<span class="c1">// ... 119 more resources ...</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="performance">Performance</h2>
<h3 id="pagination-overhead">Pagination Overhead</h3>
<p><strong>Negligible performance impact:</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Without pagination: ~5ms (all 120 tools)
With pagination: ~2ms per page (50 tools)
</code></pre></div></div>
<p><strong>Memory:</strong></p>
<ul>
<li>Each page: ~50 KB</li>
<li>Full dataset: ~150 KB</li>
<li>3 pages total: Same memory as full dataset</li>
</ul>
<h3 id="load-testing">Load Testing</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Test 100 concurrent requests</span>
<span class="k">for </span>i <span class="k">in</span> <span class="o">{</span>1..100<span class="o">}</span><span class="p">;</span> <span class="k">do
</span>curl <span class="nt">-X</span> POST http://localhost:5000/rpc <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="se">\</span>
<span class="nt">-H</span> <span class="s2">"MCP-Protocol-Version: 2025-11-25"</span> <span class="se">\</span>
<span class="nt">-d</span> <span class="s1">'{"jsonrpc":"2.0","method":"tools/list","id":'</span><span class="nv">$i</span><span class="s1">'}'</span> &
<span class="k">done
</span><span class="nb">wait</span>
</code></pre></div></div>
<h2 id="best-practices">Best Practices</h2>
<h3 id="1-always-check-nextcursor">1. Always Check nextCursor</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// ✅ GOOD</span>
<span class="k">if </span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">nextCursor</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// More pages available</span>
<span class="nf">fetchNextPage</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">nextCursor</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// ❌ BAD</span>
<span class="k">if </span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">nextCursor</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// This fails when nextCursor is "" or 0</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="2-track-progress">2. Track Progress</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">totalFetched</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">pageNumber</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">do</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">fetchPage</span><span class="p">(</span><span class="nx">cursor</span><span class="p">);</span>
<span class="nx">totalFetched</span> <span class="o">+=</span> <span class="nx">result</span><span class="p">.</span><span class="nx">tools</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Page </span><span class="p">${</span><span class="nx">pageNumber</span><span class="p">}</span><span class="s2">: </span><span class="p">${</span><span class="nx">result</span><span class="p">.</span><span class="nx">tools</span><span class="p">.</span><span class="nx">length</span><span class="p">}</span><span class="s2"> items (total: </span><span class="p">${</span><span class="nx">totalFetched</span><span class="p">}</span><span class="s2">)`</span><span class="p">);</span>
<span class="nx">cursor</span> <span class="o">=</span> <span class="nx">result</span><span class="p">.</span><span class="nx">nextCursor</span><span class="p">;</span>
<span class="nx">pageNumber</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span> <span class="k">while </span><span class="p">(</span><span class="nx">cursor</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">);</span>
</code></pre></div></div>
<h3 id="3-handle-errors">3. Handle Errors</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">fetchPage</span><span class="p">(</span><span class="nx">cursor</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
<span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if </span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">code</span> <span class="o">===</span> <span class="o">-</span><span class="mi">32602</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Invalid cursor - start from beginning</span>
<span class="k">return</span> <span class="nf">fetchPage</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<h2 id="common-use-cases">Common Use Cases</h2>
<h3 id="1-fetch-all-items">1. Fetch All Items</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span> <span class="kd">function</span> <span class="nf">fetchAll</span><span class="p">(</span><span class="nx">method</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">cursor</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">items</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">do</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">fetch</span><span class="p">(</span><span class="dl">'</span><span class="s1">http://localhost:5000/rpc</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
<span class="na">method</span><span class="p">:</span> <span class="dl">'</span><span class="s1">POST</span><span class="dl">'</span><span class="p">,</span>
<span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">'</span><span class="s1">Content-Type</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">application/json</span><span class="dl">'</span><span class="p">,</span>
<span class="dl">'</span><span class="s1">MCP-Protocol-Version</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">2025-11-25</span><span class="dl">'</span>
<span class="p">},</span>
<span class="na">body</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nf">stringify</span><span class="p">({</span>
<span class="na">jsonrpc</span><span class="p">:</span> <span class="dl">'</span><span class="s1">2.0</span><span class="dl">'</span><span class="p">,</span>
<span class="nx">method</span><span class="p">,</span>
<span class="na">params</span><span class="p">:</span> <span class="nx">cursor</span> <span class="p">?</span> <span class="p">{</span> <span class="nx">cursor</span> <span class="p">}</span> <span class="p">:</span> <span class="p">{},</span>
<span class="na">id</span><span class="p">:</span> <span class="nb">Date</span><span class="p">.</span><span class="nf">now</span><span class="p">()</span>
<span class="p">})</span>
<span class="p">});</span>
<span class="kd">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">result</span><span class="p">.</span><span class="nf">json</span><span class="p">();</span>
<span class="kd">const</span> <span class="nx">key</span> <span class="o">=</span> <span class="nx">method</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="dl">'</span><span class="s1">/</span><span class="dl">'</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span> <span class="c1">// 'tools', 'prompts', 'resources'</span>
<span class="nx">items</span><span class="p">.</span><span class="nf">push</span><span class="p">(...</span><span class="nx">data</span><span class="p">.</span><span class="nx">result</span><span class="p">[</span><span class="nx">key</span><span class="p">]);</span>
<span class="nx">cursor</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">result</span><span class="p">.</span><span class="nx">nextCursor</span><span class="p">;</span>
<span class="p">}</span> <span class="k">while </span><span class="p">(</span><span class="nx">cursor</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">items</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// Usage</span>
<span class="kd">const</span> <span class="nx">tools</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">fetchAll</span><span class="p">(</span><span class="dl">'</span><span class="s1">tools/list</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">prompts</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">fetchAll</span><span class="p">(</span><span class="dl">'</span><span class="s1">prompts/list</span><span class="dl">'</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">resources</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">fetchAll</span><span class="p">(</span><span class="dl">'</span><span class="s1">resources/list</span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>
<h3 id="2-lazy-loading">2. Lazy Loading</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PaginatedList</span> <span class="p">{</span>
<span class="nf">constructor</span><span class="p">(</span><span class="nx">method</span><span class="p">)</span> <span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">method</span> <span class="o">=</span> <span class="nx">method</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">items</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">this</span><span class="p">.</span><span class="nx">cursor</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">hasMore</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">async</span> <span class="nf">loadMore</span><span class="p">()</span> <span class="p">{</span>
<span class="k">if </span><span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">hasMore</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">fetchPage</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">method</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">cursor</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">items</span><span class="p">.</span><span class="nf">push</span><span class="p">(...</span><span class="nx">result</span><span class="p">.</span><span class="nx">items</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">cursor</span> <span class="o">=</span> <span class="nx">result</span><span class="p">.</span><span class="nx">nextCursor</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="nx">hasMore</span> <span class="o">=</span> <span class="nx">result</span><span class="p">.</span><span class="nx">nextCursor</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">;</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">items</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// Usage</span>
<span class="kd">const</span> <span class="nx">toolsList</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PaginatedList</span><span class="p">(</span><span class="dl">'</span><span class="s1">tools/list</span><span class="dl">'</span><span class="p">);</span>
<span class="k">await</span> <span class="nx">toolsList</span><span class="p">.</span><span class="nf">loadMore</span><span class="p">();</span> <span class="c1">// Load page 1</span>
<span class="k">await</span> <span class="nx">toolsList</span><span class="p">.</span><span class="nf">loadMore</span><span class="p">();</span> <span class="c1">// Load page 2</span>
</code></pre></div></div>
<h3 id="3-search-with-pagination">3. Search with Pagination</h3>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span> <span class="kd">function</span> <span class="nf">searchTools</span><span class="p">(</span><span class="nx">query</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">let</span> <span class="nx">cursor</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
<span class="kd">let</span> <span class="nx">matches</span> <span class="o">=</span> <span class="p">[];</span>
<span class="k">do</span> <span class="p">{</span>
<span class="kd">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">fetchPage</span><span class="p">(</span><span class="dl">'</span><span class="s1">tools/list</span><span class="dl">'</span><span class="p">,</span> <span class="nx">cursor</span><span class="p">);</span>
<span class="c1">// Filter locally (server-side filtering is better!)</span>
<span class="kd">const</span> <span class="nx">pageMatches</span> <span class="o">=</span> <span class="nx">result</span><span class="p">.</span><span class="nx">tools</span><span class="p">.</span><span class="nf">filter</span><span class="p">(</span><span class="nx">tool</span> <span class="o">=></span>
<span class="nx">tool</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nf">includes</span><span class="p">(</span><span class="nx">query</span><span class="p">)</span> <span class="o">||</span>
<span class="nx">tool</span><span class="p">.</span><span class="nx">description</span><span class="p">.</span><span class="nf">includes</span><span class="p">(</span><span class="nx">query</span><span class="p">)</span>
<span class="p">);</span>
<span class="nx">matches</span><span class="p">.</span><span class="nf">push</span><span class="p">(...</span><span class="nx">pageMatches</span><span class="p">);</span>
<span class="nx">cursor</span> <span class="o">=</span> <span class="nx">result</span><span class="p">.</span><span class="nx">nextCursor</span><span class="p">;</span>
<span class="p">}</span> <span class="k">while </span><span class="p">(</span><span class="nx">cursor</span> <span class="o">!==</span> <span class="kc">null</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">matches</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// Usage</span>
<span class="kd">const</span> <span class="nx">toolsWithMock</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">searchTools</span><span class="p">(</span><span class="dl">'</span><span class="s1">mock</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="s2">`Found </span><span class="p">${</span><span class="nx">toolsWithMock</span><span class="p">.</span><span class="nx">length</span><span class="p">}</span><span class="s2"> tools matching 'mock'`</span><span class="p">);</span>
</code></pre></div></div>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="/mcp.gateway/features/pagination/">Pagination Feature</a> - Complete pagination guide</li>
<li><a href="/mcp.gateway/api/tools/">Tools API</a> - Tools API reference</li>
<li><a href="/mcp.gateway/api/resources/">Resources API</a> - Resources API reference</li>
</ul>
"
See Also
- Prompts API - Complete Prompts API reference
- Tools API - Combine prompts with tools
- Getting Started - Quick start guide