What MCP is and why it exists
The Model Context Protocol (MCP) is an open standard for connecting AI assistants to external tools, data sources, and services. Before MCP, every assistant had its own bespoke way of defining tools; MCP gives the ecosystem one shared protocol so a tool server written once can plug into any MCP-compatible client.
Under the hood, MCP is JSON-RPC 2.0 — a lightweight, well-established remote procedure call format that uses JSON for every message.
JSON-RPC 2.0 in 60 seconds
Every JSON-RPC request is a JSON object with four fields:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": { "name": "get_weather", "arguments": { "city": "Tokyo" } }
}And every response echoes the id with either a result or an error:
{
"jsonrpc": "2.0",
"id": 1,
"result": { "content": [{ "type": "text", "text": "18°C, clear" }] }
}{
"jsonrpc": "2.0",
"id": 1,
"error": { "code": -32602, "message": "Invalid params: city is required" }
}The id correlates requests with responses so multiple calls can be in flight at once. Notifications (no response expected) simply omit the id.
The MCP building blocks
An MCP server exposes three kinds of capabilities, each described and exchanged as JSON:
| Primitive | Purpose | Example |
|---|---|---|
| Tools | Actions the model can invoke | create_issue, run_query |
| Resources | Readable data the model can pull in | a file, a database row, a URL |
| Prompts | Reusable prompt templates | "summarize this PR" |
A client discovers tools by calling tools/list, which returns each tool's name, description, and a JSON Schema for its arguments — exactly the same schema concept used in function calling:
{
"name": "create_issue",
"description": "Create a tracker issue.",
"inputSchema": {
"type": "object",
"properties": {
"title": { "type": "string" },
"labels": { "type": "array", "items": { "type": "string" } }
},
"required": ["title"]
}
}A typical session
- Client and server initialize, exchanging supported capabilities.
- Client calls
tools/listto discover what the server offers. - The model decides to use a tool; the client sends
tools/callwith JSON arguments. - The server executes and returns a JSON
result. - The result is fed back to the model, which continues the conversation.
Because every message is JSON, you can inspect and debug an MCP session by reading the raw traffic — paste a captured message into a JSON formatter to see its structure clearly.
Transports
MCP messages travel over a transport — commonly stdio (for local servers launched as a subprocess) or HTTP with Server-Sent Events (for remote servers). The transport only moves JSON-RPC frames; the protocol semantics stay identical regardless of transport.
Why this matters for developers
- Write once, reuse everywhere. An MCP tool server works with any compatible client.
- Schemas are the contract. The same JSON Schema discipline from function calling applies — clear descriptions and tight types make tools reliable.
- It is debuggable. Plain JSON-RPC means you can log, replay, and validate every message.