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 entirely. 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 just 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 humble, decades-old standard: JSON-RPC 2.0. Every message a host and server exchange, every tool call, every resource read, every progress event, is a JSON-RPC object. 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 battle-tested envelope so existing JSON-RPC libraries, debuggers, and mental models carry straight over.
The question asks you to complete a request structure, which is exactly the kind of thing an interviewer uses to check whether you have actually read a packet capture or just skimmed a blog post. The four fields are not arbitrary. Each one answers a specific 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, and how should I label the reply so you can find it again.
This deep dive walks the full envelope: the request shape and its four fields, the response shape and its result or error rule, the notification shape and why omitting one field changes everything, the concurrency concern that makes the id field load-bearing in production, and finally why MCP picked JSON-RPC at all and what that decision buys the ecosystem.
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, a frequent trip-up for people who guess "version".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. Critically, 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.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. The spec allows null, but using null is discouraged because it collides with the way some implementations represent an unidentifiable error.
That is the entire request. A tools/call looks like { "jsonrpc": "2.0", "id": 7, "method": "tools/call", "params": { "name": "search", "arguments": {} } }. Four keys, no surprises, and the same four keys appear whether the call is the very first initialize handshake or the thousandth tool invocation in a long session.
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" } } }
// success response
{ "jsonrpc": "2.0", "id": 7, "result": { "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": 7, "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 at session start.
- 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; 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.