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 child
  • behavior (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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</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">=&gt;</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> &amp;
<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">=&gt;</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