Fixing "Method not found (-32601)" JSON-RPC errors
Kashish Hora
Co-founder of AgentCat
The Quick Answer
The JSON-RPC error -32601 "Method not found" occurs when calling an unimplemented MCP method. Debug by checking server capabilities and method names:
# List available methods using MCP inspector$npx @modelcontextprotocol/inspector "node /path/to/your/server.js"
// Verify method exists in server capabilities
{
"capabilities": {
"tools": {}, // Present: tools/list and tools/call are served
// "resources" omitted -> resource methods return -32601
// "prompts" omitted -> prompt methods return -32601
}
}This error means your server received the request but doesn't implement that specific method. Check which capabilities your server advertises in its server/discover response.
Prerequisites
- MCP server running (any language/framework)
- Client configured to connect (Claude Desktop, custom client, etc.)
- Basic understanding of JSON-RPC protocol
- Access to server logs for debugging
Understanding the Error
The -32601 error is a standard JSON-RPC error code indicating the requested method doesn't exist on the server. In MCP context, this typically happens when clients call methods the server hasn't implemented.
MCP servers don't need to implement every possible method. As of the 2026-07-28 spec revision, a server advertises what it supports in a single place: its server/discover response, which every server must implement and which returns the server's capabilities and supported protocol versions. (Revisions through 2025-11-25 declared the same capabilities once, in the initialize handshake that 2026-07-28 removed.) The io.modelcontextprotocol/clientCapabilities block each request carries in _meta is a different thing: it's the client declaring what it supports (roots, sampling, elicitation), not the server declaring anything. The server only consults it to decide whether it's allowed to send certain server-initiated MRTR requests back to that client — asking for something the client didn't declare there gets MissingRequiredClientCapabilityError (-32021), not -32601. When a client calls a method outside what the server supports, the server responds with -32601.
On Streamable HTTP the current revision also pins the HTTP status: an unknown method returns 404 Not Found with the -32601 JSON-RPC error in the body, so a bare 404 from an MCP endpoint is usually this error rather than a bad URL.
// Standard JSON-RPC error response
{
"jsonrpc": "2.0",
"id": 123,
"error": {
"code": -32601,
"message": "Method not found",
"data": {
"method": "resources/list" // The method that wasn't found
}
}
}The error structure follows JSON-RPC 2.0 specification exactly. The code field always contains -32601 for method not found errors, while message provides human-readable context.
Debugging Steps
Start debugging by identifying exactly which method is failing and why your server doesn't support it.
1. Enable Verbose Logging
// Add detailed logging to your MCP server
server.on('request', (method, params) => {
console.log(`Received request: ${method}`, params);
});
server.on('error', (error) => {
console.error('Server error:', error);
});2. Check Server Capabilities
// Ensure your server advertises correct capabilities
const server = new Server({
name: 'my-mcp-server',
version: '1.0.0',
capabilities: {
tools: {}, // Enable tool methods
resources: {}, // Enable resource methods
prompts: {} // Enable prompt methods
}
});Capabilities control which method groups your server supports. If a capability is false or missing, all methods in that group will return -32601.
3. Verify Method Implementation
// Common MCP methods that must be implemented
server.setRequestHandler(ListToolsRequestSchema, async () => {
return { tools: [...] };
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
// Handle tool execution
});
// If you advertise resources capability, implement these:
server.setRequestHandler(ListResourcesRequestSchema, async () => {
return { resources: [...] };
});4. Use MCP Inspector
# Interactive debugging tool for MCP servers$npx @modelcontextprotocol/inspector "node server.js"# For Python servers$npx @modelcontextprotocol/inspector "python server.py"
The inspector shows all available methods and lets you test them interactively. If a method returns -32601 here, it's definitely not implemented.
Common Causes and Solutions
Missing Handler Registration
The most common cause is forgetting to register a handler for a specific method. Each MCP method needs explicit handler registration.
// Wrong: Capability enabled but handler missing
const server = new Server({
capabilities: { tools: {} }
});
// No tool handlers registered = -32601 errors
// Correct: Register all required handlers
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "get_data",
description: "Retrieves data",
inputSchema: { type: "object", properties: {} }
}
]
};
});Incorrect Method Names
MCP method names follow specific patterns. Using wrong names causes -32601 errors.
// Wrong method names
"method": "list_tools" // Should be "tools/list"
"method": "callTool" // Should be "tools/call"
"method": "getResources" // Should be "resources/list"
// Correct MCP method names
"method": "tools/list"
"method": "tools/call"
"method": "resources/list"
"method": "resources/read"
"method": "prompts/list"
"method": "prompts/get"Client-Server Version Mismatch
Different MCP spec revisions support different methods. Ensure compatible versions between client and server.
// Check versions in package.json
{
"dependencies": {
"@modelcontextprotocol/sdk": "^1.0.0" // Use consistent versions
}
}This got sharper with 2026-07-28, which removed initialize, ping, logging/setLevel, and resources/subscribe/unsubscribe. On stdio, a client built against an older revision calling any of those against a server that only implements the current one gets an implementation-defined error — commonly -32601 (unknown method) or -32602 (the request is also missing the required _meta fields). On Streamable HTTP the mismatch never reaches JSON-RPC at all: the request is missing the required headers, so the server rejects it at the transport layer with 400 Bad Request (-32020 HeaderMismatch) instead. The fix isn't a method rename: serve both eras, which the Tier-1 SDKs do for you, since most shipping clients still speak 2025-11-25 or earlier.
Capability Mismatch
Servers must explicitly enable capabilities for method groups to work. Under 2026-07-28 that declaration lives in the server/discover result, and capabilities are nested objects rather than booleans: a group is supported if its key is present at all.
# Python MCP server example: server/discover is where capabilities are declared
async def handle_server_discover(params):
return {
"resultType": "complete",
"supportedVersions": ["2026-07-28"],
"capabilities": {
"tools": {}, # Present: tools/list and tools/call are served
# "resources" omitted -> resource methods return -32601
# "prompts" omitted -> prompt methods return -32601
},
"ttlMs": 3600000,
"cacheScope": "public",
}One Python-specific wrinkle worth flagging: -32601 for an unimplemented method is current behavior as of mcp 2.0.0 (the current PyPI release), which is what aligns it with the spec and the TypeScript SDK. Under mcp<2, the official Python SDK actually returned -32602 for a call to a genuinely unknown method, not -32601 — so if you're debugging this exact symptom against an older mcp install, look for -32602 instead.
Examples
Example 1: Minimal Server with Proper Error Handling
Here's a minimal MCP server that correctly handles method requests and avoids -32601 errors:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
ListToolsRequestSchema,
CallToolRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
const server = new Server({
name: 'debug-server',
version: '1.0.0',
capabilities: {
tools: {} // Only enable what we implement
}
});
// Implement all methods for enabled capabilities
server.setRequestHandler(ListToolsRequestSchema, async () => {
console.log('Handling tools/list request');
return {
tools: [{
name: 'echo',
description: 'Echoes input back',
inputSchema: {
type: 'object',
properties: {
message: { type: 'string' }
}
}
}]
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
console.log('Handling tools/call request:', request.params.name);
if (request.params.name === 'echo') {
return {
content: [
{
type: 'text',
text: `Echo: ${request.params.arguments?.message || 'No message'}`
}
]
};
}
throw new Error(`Unknown tool: ${request.params.name}`);
});
// ... error handling and transport setupThis server only enables the tools capability and implements both required tool methods. Resource and prompt methods will correctly return -32601 since those capabilities are disabled.
Example 2: Debugging Client Requests
When debugging -32601 errors from a client, add comprehensive logging:
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
const client = new Client({
name: 'debug-client',
version: '1.0.0'
});
// Wrap requests with error handling
async function safeRequest(method: string, params?: any) {
try {
console.log(`Calling ${method} with params:`, params);
const result = await client.request({ method, params });
console.log(`Success:`, result);
return result;
} catch (error: any) {
if (error.code === -32601) {
console.error(`Method '${method}' not found on server`);
console.error('Available capabilities:', client.serverCapabilities);
} else {
console.error(`Request failed:`, error);
}
throw error;
}
}
// Test various methods
await safeRequest('tools/list');
await safeRequest('resources/list'); // May fail with -32601
await safeRequest('prompts/list'); // May fail with -32601Production implementations would include retry logic, fallback behavior, and user-friendly error messages. The logging shown here helps identify exactly which methods are failing during development.
Example 3: Custom Error Handling
Implement custom error responses with additional debugging information:
from mcp.server import Server
from mcp.server.models import InitializationOptions
import json
class DebugServer(Server):
async def handle_request(self, request):
try:
# Log all incoming requests
print(f"Received: {request.method}")
# Check if method is implemented
if not hasattr(self, f"handle_{request.method.replace('/', '_')}"):
return {
"jsonrpc": "2.0",
"id": request.id,
"error": {
"code": -32601,
"message": "Method not found",
"data": {
"method": request.method,
"available_methods": self.get_available_methods(),
"hint": "Check server capabilities"
}
}
}
# Process normally
return await super().handle_request(request)
except Exception as e:
print(f"Error handling {request.method}: {e}")
raise
def get_available_methods(self):
"""List all implemented methods based on capabilities"""
# server/discover is the one method every server must implement.
# (initialize and ping were removed in 2026-07-28; they exist only
# on legacy-era servers, which you'd add here when serving both eras.)
methods = ["server/discover"]
if self.capabilities.get("tools"):
methods.extend(["tools/list", "tools/call"])
if self.capabilities.get("resources"):
methods.extend(["resources/list", "resources/read"])
return methodsThis enhanced error handling provides clients with helpful debugging information when methods fail. The response includes available methods and hints about checking capabilities.
Related Guides
Understanding the JSON-RPC protocol and how it's used in MCP
How MCP uses JSON-RPC 2.0 for every client-server message: request, response, and notification shapes, the per-request metadata that replaced the initialize handshake, core methods, and the real error codes.
Debugging message serialization errors in MCP protocol
Debug and fix MCP message serialization errors with proven troubleshooting techniques.
Building an MCP server in TypeScript
Build an MCP server with the TypeScript SDK: the @modelcontextprotocol/sdk 1.x McpServer API pinned to 1.30.0, registerTool with structured output, and both transports (stdio and Streamable HTTP), plus a note on the newer split @modelcontextprotocol/server 2.0 line for the 2026-07-28 spec revision.