Complete the JSON-RPC 2.0 request structure used by MCP
Every MCP request is a JSON-RPC 2.0 envelope: jsonrpc set to "2.0", a method name, params for arguments, and an id for correlation that notifications omit.
Think of mailing a letter that needs a reply. You write it on standard letterhead so the recipient knows the format. That is the jsonrpc "2.0" field. You say what you want done. That is the method. You enclose the details. That is params. And you stamp a tracking number so the reply can be matched back to your letter. That is the id. If you do not need a reply, like dropping off a notice, you skip the tracking number. The recipient mails back a matching letter carrying either a result or an error, stamped with the same tracking number so you know which request it answers. MCP sends these letters between the host app and the tool server.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
MCP gets a lot of attention for its three primitives (tools, resources, and prompts). But underneath all of them sits one simple, decades-old standard: JSON-RPC 2.0. Every message a host and server exchange is a JSON-RPC object: every tool call, every resource read, every progress event. If you can draw that object from memory, you understand the MCP wire format. The protocol designers made a deliberate choice here. Rather than design a fresh framing, they reused a proven envelope. Existing JSON-RPC libraries, debuggers, and mental models carry straight over.
The four fields are not arbitrary. Each one answers a question the receiver needs answered to act on the message. Which spec are we speaking? What operation do you want? What arguments come with it? How should I label the reply so you can find it again?
The four fields of a request
A JSON-RPC 2.0 request is a single JSON object with four members, and each one has a job.
jsonrpcis the literal string "2.0". It is a version marker, not a number, and it tells the receiver which version of the spec governs this message. A receiver that sees anything else, including the bare number 2.0 or a missing field, should reject the message. The field name is exactlyjsonrpc. People who guess "version" often get this wrong.methodis a string naming the operation to invoke. In MCP this is a namespaced verb liketools/call,resources/read, orprompts/get. The server routes on this string, dispatching to the handler registered under that name. An unknown method comes back as the reserved error -32601.paramsis a structured value, almost always an object, carrying the arguments for the method. Arguments live here, nested, never at the top level of the request. For a tool call the params object itself holds anameand anargumentsobject, so the tool's own inputs are nested two levels deep. In MCP, params also holds a_metaobject that carries the protocol version and the client capabilities on every request.idis a number or string the sender chooses to identify this request. The receiver must echo it back in the response so the sender can match reply to call. Base JSON-RPC allows a null id, but MCP forbids it: an MCP request id must be a string or an integer.
That is the entire request. A tools/call looks like { "jsonrpc": "2.0", "id": 7, "method": "tools/call", "params": { "name": "search", "arguments": {}, "_meta": { "io.modelcontextprotocol/protocolVersion": "2026-07-28", "io.modelcontextprotocol/clientCapabilities": {} } } }. It has four keys and no surprises. The same four keys appear whether the call is a first server/discover request or the thousandth tool invocation.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
// request (expects a response)
{ "jsonrpc": "2.0", "id": 7, "method": "tools/call",
"params": { "name": "search", "arguments": { "q": "mcp" },
"_meta": { "io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {},
"progressToken": "p7" } } }
// success response
{ "jsonrpc": "2.0", "id": 7, "result": { "resultType": "complete", "content": [] } }
// error response
{ "jsonrpc": "2.0", "id": 7, "error": { "code": -32602, "message": "Invalid params" } }
// notification (no id, no response)
{ "jsonrpc": "2.0", "method": "notifications/progress",
"params": { "progressToken": "p7", "progress": 0.5 } }| Field | Request | Response | Notification |
|---|---|---|---|
| jsonrpc | "2.0" (required) | "2.0" (required) | "2.0" (required) |
| method | Required, names op | Absent | Required, names event |
| params | Arguments object | Absent | Event payload |
| id | Required, correlates | Echoes request id | Omitted (the signal) |
| result / error | Absent | Exactly one present | Absent |
Real products, models, and research that use this idea.
- Claude Code and Claude Desktop exchange these exact JSON-RPC envelopes with every registered MCP server over stdio or HTTP.
- The mcp-inspector debugging tool prints raw request and response objects so you can see the jsonrpc, method, params, and id fields on the wire.
What an interviewer would ask next. Try answering before peeking at the approach.
QHow does a client correlate responses when several requests are in flight at once?
Keep a pending map keyed by id, and match each incoming response by its echoed id. Reject duplicate or unknown ids, since full-duplex transports may reorder replies.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Forgetting that omitting id turns a request into a notification, or putting arguments at the top level instead of nesting them under params.
60 second bullets to scan on the way to the call.
The four fields of a JSON-RPC request
Why jsonrpc is the literal string two point zero
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.