MCP uses JSON-RPC 2.0: what does it add beyond raw RPC?
MCP is built on JSON-RPC 2.0. Does that make it 'just RPC'? What does MCP add beyond raw JSON-RPC?
JSON-RPC is only the message envelope. MCP adds the semantics: three typed primitives, capability negotiation, a consent model, named methods, and a shared ecosystem.
JSON-RPC is like the postal system. It tells you how to put a letter in an envelope, address it, and get a reply back. But it says nothing about what you write inside or what the words mean. Two people could both use the post and still fail to understand each other if one writes in French and the other in Japanese. MCP is the agreed language and etiquette inside those envelopes. It says: first introduce yourself and list what you can do. Here is how you ask for a tool versus a file. Here is when to check with the human before acting. Because everyone agrees on that shared language, any writer can talk to any reader without a private dictionary per pair.
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 is built on JSON-RPC, which tempts people to say "MCP is basically just RPC." That framing misses the layering: JSON-RPC and MCP sit at different layers and do entirely different jobs.
JSON-RPC 2.0 is a message-framing convention. It tells two parties how to package a remote call and route the reply. It is intentionally generic and says nothing about what the calls mean. MCP is an application-layer protocol that supplies those missing meanings: capability negotiation, a typed set of primitives, a fixed namespace, a consent model, and a shared ecosystem of implementations.
What JSON-RPC 2.0 actually specifies
JSON-RPC 2.0 is one of the smallest useful protocols in wide use. A request is a JSON object with a method string, an optional params value, and an id that ties the response back to the request. A response carries either a result or an error object with a numeric code and a message. There are notifications, which are requests with no id that expect no reply, and batching, which is an array of requests. That is almost the entire specification.
JSON-RPC defines no methods of its own. It does not know what getWeather or tools/call mean, whether a method has side effects, or how a client should discover the methods a server supports. It defines no capability negotiation, no versioning, and no authorization. It is pure plumbing: correlation, dispatch, and a uniform error envelope.
The boundary is sharp. JSON-RPC answers three questions and only three. How do I package a call so the other side can route it? How do I match a reply to the call that produced it? How do I signal a transport or dispatch failure in a uniform way? Everything past that is left to the layer above. The spec is content-neutral on purpose. That is why the same JSON-RPC framing carries Language Server Protocol traffic, Ethereum node calls, and MCP messages without modification.
This minimalism is a feature, not a flaw. JSON-RPC is meant to be a substrate that higher layers build on, the same way TCP is a substrate that HTTP builds on. Nobody calls HTTP "just TCP," because the interesting semantics (methods, status codes, headers, content negotiation) live in the layer above. The common mistake is assuming the substrate is the whole protocol stack.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
| Concern | Raw JSON-RPC 2.0 | MCP on top |
|---|---|---|
| What it defines | Message framing only | Application-layer semantics |
| Discovery | None; you invent it | server/discover plus per-request capability negotiation |
| Method names | Arbitrary, per app | Fixed: tools/list, tools/call, resources/read |
| Primitives | None | Tools, resources, prompts |
| Consent model | None | Host-mediated per-call approval |
| Interop | Per-pair custom glue | One server runs in any host |
Real products, models, and research that use this idea.
- Claude Code connects to each configured MCP server, then calls tools/list to build its catalog before the first user turn.
- The MCP project's reference servers, such as the filesystem and Git servers, all speak the same tools/call method, so any host reuses them unchanged.
What an interviewer would ask next. Try answering before peeking at the approach.
QWalk me through what each MCP request's _meta carries and what server/discover returns, field by field.
Each request's _meta carries the protocol version and the client's capabilities. server/discover returns the server's supported versions, capabilities and identity. A request with an unsupported version gets an error listing the versions the server supports.
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.
Saying MCP is just JSON-RPC with a logo. JSON-RPC frames messages; MCP defines what the messages mean, and that is its main value.
60 second bullets to scan on the way to the call.
What JSON-RPC 2.0 actually standardizes and where it stops
Per-request capability negotiation and server/discover
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.