Lesson 5 - Step 3 of 6

The tools/list Method

Learn how to handle tools/list requests and return your available tools.

How Clients Discover Tools

When a client connects to your MCP server, one of the first things it does (after initialization) is request a list of available tools. This is done via the tools/list method.

text
Client                              Server
  |                                    |
  |--- initialize ------------------>  |
  |<-- initialize response ----------  |
  |--- notifications/initialized --->  |
  |                                    |
  |--- tools/list ------------------>  |  <-- Client requests tools
  |<-- list of tools ----------------  |
  |                                    |

The tools/list Request

The request is simple — it has no required parameters:

json
{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/list",
    "params": {}
}
Optional: Pagination

The tools/list method supports an optional cursor parameter for pagination. This is useful if you have many tools, but most servers can return all tools in a single response.

The tools/list Response

Your server must respond with a tools array containing all available tool definitions:

json
{
    "jsonrpc": "2.0",
    "id": 2,
    "result": {
        "tools": [
            {
                "name": "add",
                "description": "Add two numbers together",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "a": {"type": "number", "description": "First number"},
                        "b": {"type": "number", "description": "Second number"}
                    },
                    "required": ["a", "b"]
                }
            },
            {
                "name": "subtract",
                "description": "Subtract the second number from the first",
                "inputSchema": {
                    "type": "object",
                    "properties": {
                        "a": {"type": "number", "description": "Number to subtract from"},
                        "b": {"type": "number", "description": "Number to subtract"}
                    },
                    "required": ["a", "b"]
                }
            }
        ]
    }
}

Implementing tools/list in Python

Here's how to implement the tools/list handler in your MCP server:

python
"""
mcp_server.py - MCP server with tools/list implementation.
"""

import json

# Define your tools
TOOLS = [
    {
        "name": "add",
        "description": "Add two numbers together and return the sum",
        "inputSchema": {
            "type": "object",
            "properties": {
                "a": {"type": "number", "description": "First number"},
                "b": {"type": "number", "description": "Second number"}
            },
            "required": ["a", "b"]
        }
    },
    {
        "name": "subtract",
        "description": "Subtract the second number from the first",
        "inputSchema": {
            "type": "object",
            "properties": {
                "a": {"type": "number", "description": "Number to subtract from"},
                "b": {"type": "number", "description": "Number to subtract"}
            },
            "required": ["a", "b"]
        }
    },
    {
        "name": "multiply",
        "description": "Multiply two numbers and return the product",
        "inputSchema": {
            "type": "object",
            "properties": {
                "a": {"type": "number", "description": "First number"},
                "b": {"type": "number", "description": "Second number"}
            },
            "required": ["a", "b"]
        }
    }
]


def handle_tools_list(request_id, params):
    """
    Handle the tools/list method.

    Args:
        request_id: The JSON-RPC request ID
        params: Request parameters (may contain cursor for pagination)

    Returns:
        JSON-RPC response with list of tools
    """
    # For simple servers, ignore pagination and return all tools
    return {
        "jsonrpc": "2.0",
        "id": request_id,
        "result": {
            "tools": TOOLS
        }
    }


def handle_request(request):
    """Route incoming requests to the appropriate handler."""
    method = request.get("method")
    request_id = request.get("id")
    params = request.get("params", {})

    if method == "tools/list":
        return handle_tools_list(request_id, params)

    # ... handle other methods ...

    # Method not found
    return {
        "jsonrpc": "2.0",
        "id": request_id,
        "error": {
            "code": -32601,
            "message": f"Method not found: {method}"
        }
    }

Pagination Support (Optional)

If you have many tools, you can implement pagination using cursors:

python
import base64

def handle_tools_list_paginated(request_id, params):
    """
    Handle tools/list with pagination support.
    """
    PAGE_SIZE = 10

    # Decode cursor to get starting index
    cursor = params.get("cursor")
    if cursor:
        try:
            start_index = int(base64.b64decode(cursor).decode())
        except:
            start_index = 0
    else:
        start_index = 0

    # Get page of tools
    end_index = start_index + PAGE_SIZE
    page_tools = TOOLS[start_index:end_index]

    # Create next cursor if there are more tools
    next_cursor = None
    if end_index < len(TOOLS):
        next_cursor = base64.b64encode(str(end_index).encode()).decode()

    result = {"tools": page_tools}
    if next_cursor:
        result["nextCursor"] = next_cursor

    return {
        "jsonrpc": "2.0",
        "id": request_id,
        "result": result
    }
Keep It Simple

Most MCP servers have fewer than 100 tools. Unless you're building a server with many tools, you can skip pagination and return all tools in a single response.

Testing tools/list

You can test your implementation with curl:

bash
curl -X POST http://localhost:8080 \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list",
    "params": {}
  }'

Expected response:

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "add",
        "description": "Add two numbers together and return the sum",
        "inputSchema": { ... }
      },
      ...
    ]
  }
}