JSON-RPC 2.0
JSON-RPC 2.0 is the message format every Model Context Protocol exchange uses. Each message is a JSON object carrying a jsonrpc version string, a method name, and either an id for requests or no id for notifications. MCP defines the method names; JSON-RPC defines the envelope they travel in.
What is JSON-RPC 2.0?
JSON-RPC 2.0 is a small, long-standing specification for calling a method on a remote system using JSON. It predates MCP by well over a decade and MCP adopts it wholesale rather than inventing a message format.
A request names a method, carries optional params, and carries an id. The response carries the same id and either a result or an error.
What are the three message types?
Requests, responses, and notifications. A request has an id and expects an answer. A response echoes that id. A notification has a method but no id, and expects nothing back.
MCP uses all three. initialize and tools/list are requests. notifications/initialized, which a client sends once the handshake is agreed, is a notification, and a server that waits for a response to it will hang.
Where does this go wrong in practice?
Most often at the envelope, not the content. A server that returns valid JSON which is not a valid JSON-RPC response fails before anything MCP-specific is even considered.
Across 82 connection attempts between 20 July and 5 August 2026 we recorded 4 protocol errors, meaning the address answered and spoke something, but not this. A separate 3 answered with a web page rather than JSON at all, which is what a documentation URL does when it is mistaken for an endpoint.
Example
A tools/list request is an ordinary JSON-RPC call with no arguments:
{"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}}
The server answers with the same id and a result object containing a tools array. If it answers with a bare array, or with {"tools": [...]} and no envelope, it is not speaking JSON-RPC and a conforming client is right to reject it.