2 minute read

What MCP is for

The Model Context Protocol (MCP) is an open specification, released by Anthropic in November 2024, that defines a single interface between AI models and external systems. A client (an agent) and a server (a tool, database, or API wrapper) exchange protocol versions and capabilities at connect time, then communicate through four primitives: tools, resources, prompts, and notifications. That structure is JSON-RPC 2.0.

Why JSON-RPC 2.0 over plain JSON

Plain JSON over HTTP gives you a body and a status code. Nothing defines the method name, nothing links a response to the request that produced it, and there is no agreed error shape.

JSON-RPC 2.0 fixes each of those. Every message carries jsonrpc: "2.0", a method, params, and an id that correlates responses with requests. A server can reply asynchronously and out of order, and can issue its own calls back to the client, which is what lets a long-running tool stream progress while another call completes.

Here is a minimal request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": { "name": "get_weather", "arguments": { "city": "São Paulo" } }
}

And the matching response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": { "temp": 26.1, "unit": "C" }
}

Notifications are JSON-RPC messages without an id; the sender expects no reply. MCP uses them for progress and log messages. Batch requests send several calls in one array and receive the responses together. Both map directly to agent workloads, where a model issues several tool calls in a row.

The transports: stdio and Streamable HTTP

JSON-RPC defines message framing independently of transport, so the same logical message moves over different channels. MCP specifies two.

  • stdio: the client spawns the server as a child process and exchanges JSON-RPC messages over standard input and output. No HTTP stack, no serialization boundary. The default for local servers.
  • Streamable HTTP: a single HTTP connection the server can stream incremental responses over. It replaced the earlier HTTP + SSE transport, which the spec deprecated in March 2025. The server can push updates over the same connection, which matters for tools that run for seconds rather than milliseconds.

The transport changes the deployment model, not the messages. The same tools/call payload works over stdio locally and over Streamable HTTP remotely.

The data layer: tools, resources, and capability negotiation

The data layer defines what the messages can carry. At connect time, client and server exchange protocol versions and capabilities. The server then publishes its surface:

  • tools: functions the model can call, each described by name, description, and an input JSON Schema
  • resources: readable data surfaces, identified by URI and MIME type
  • prompts: reusable prompt templates the client can request
  • notifications: server-initiated events the client can register for

This is what makes the protocol composable. A model never needs per-API glue: the schema of every tool arrives during the handshake, so a client can construct valid arguments and validate the result without knowing anything about the underlying service.

Errors are part of the contract

JSON-RPC 2.0 reserves a base set of error codes, and MCP adds its own on top. Every failed call returns an object with code, message, and optional diagnostic data. When an agent chains several tool calls, a typed error lets it branch on the failure mode instead of guessing from a bare HTTP status.