What are MCP's standard JSON-RPC error codes, and how do custom errors extend them?

4 minintermediatemcpjson-rpcerror-codes

Quick Answer

MCP reuses JSON-RPC 2.0's standard error codes for protocol-level failures: -32700 (Parse error — invalid JSON), -32600 (Invalid Request), -32601 (Method not found), -32602 (Invalid params), and -32603 (Internal error). These live in the top-level error object of a JSON-RPC response, distinct from tool-execution failures (which use isError: true inside a normal result, as covered under tool error handling). Implementations are free to define their own error codes for domain-specific protocol failures, and the convention (inherited from JSON-RPC) is to use codes in the range -32000 to -32099 (the "server error" reserved range) for these custom, implementation-defined errors, keeping them clearly separate from the standard codes.

Detailed Answer

Getting error codes right matters because a client's error-handling logic often branches on the numeric code, not just the message string.

Standard codes

CodeMeaning
-32700Parse error — the message wasn't valid JSON
-32600Invalid Request — valid JSON, but not a valid JSON-RPC request object
-32601Method not found — no handler for the requested method name
-32602Invalid params — the method exists, but params doesn't match what it expects
-32603Internal error — an unexpected failure inside the server while handling an otherwise-valid request
{"jsonrpc": "2.0", "id": 4, "error": {
  "code": -32601,
  "message": "Method not found: tools/execute"
}}

Custom, implementation-defined codes

{"jsonrpc": "2.0", "id": 4, "error": {
  "code": -32001,
  "message": "Rate limit exceeded",
  "data": {"retryAfterMs": 5000}
}}

The -32000 to -32099 range is reserved by the JSON-RPC spec for "server error" — implementation-specific codes outside the standard set. Use a code in this range for a custom error, rather than inventing an arbitrary number or colliding with a standard code. That keeps a server's errors unambiguous to any spec-aware client, even one that doesn't recognize the specific custom code.

The optional data field

Any error object can carry an optional data field with extra structured detail beyond the human-readable message, like the retryAfterMs above. Clients that understand a particular custom error code can use data programmatically — actually waiting before retrying, say. Clients that don't recognize the code can still fall back to showing message to the user.

The important boundary to remember

None of this applies to a tool that runs but fails at the business-logic level. That's still isError: true in a normal result, not a JSON-RPC error. These error codes are strictly for failures in handling the request itself — bad method, bad params, internal crash — not failures in whatever the request asked the server to do.

Related Resources