MCP Overview
Model Context Protocol (MCP) explained: the open standard for connecting AI models to tools, data sources, and external systems.
Last updated
MCP Protocol Deep Dive
Model Context Protocol — the "USB-C of tools." Open standard for giving LLMs access to tools, data, and prompts via a unified JSON-RPC interface.
MCP solves the N×M integration problem: without it, every LLM client needs a custom connector for every tool/data source. With MCP, every tool speaks one protocol, and every client consumes it identically.
Adoption (2026): Over 97 million monthly SDK downloads. 13,000+ MCP servers on GitHub. Adopted by OpenAI, Google DeepMind, Microsoft, and all major agent frameworks. Anthropic donated MCP to the Linux Foundation's Agentic AI Foundation in December 2025. Protocol version is date-string versioned (e.g., 2025-11-25) and negotiated during the initialize handshake.
MCP vs. Function Calling: Different Layers
| Concept | Function Calling (Phase 1) | MCP (Phase 2) |
|---|---|---|
| What it does | LLM generates structured JSON specifying which function to call with what args | Standardized infrastructure for how tools are discovered, invoked, and managed |
| Who defines it | Each LLM provider (Claude, GPT, Gemini) has its own format | Open standard — any client speaks to any server |
| Scope | Single API call: "I want to call tool X with args Y" | Full lifecycle: discovery → auth → invocation → result → monitoring |
| Analogy | SQL query (the intent) | ODBC/JDBC driver (the connection layer) |
4.1 — MCP Architecture & Components
Host-Client-Server: The Three-Role Pattern
| Role | What It Is | Examples |
|---|---|---|
| Host | The LLM application the user interacts with. Contains one or more MCP clients | Claude Desktop, VS Code, Cursor, your custom app |
| Client | A connector within the host that maintains a 1:1 stateful session with a single MCP server | One client per connected MCP server. Handles capability negotiation |
| Server | A service that exposes tools, resources, and prompts. Wraps databases, APIs, file systems | Your CRM server, your Jira server, a DB query server |
What MCP Handles vs. What You Handle
| Concern | MCP Handles | You Handle |
|---|---|---|
| Protocol | JSON-RPC 2.0 message format, request/response lifecycle | Choosing transport (stdio, SSE, HTTP) |
| Discovery | tools/list, resources/list, prompts/list methods |
Which tools/resources to expose |
| Schema | JSON Schema validation for tool inputs | Writing good descriptions & schemas |
| Invocation | tools/call, resources/read dispatch |
The actual business logic inside each tool |
| Auth | OAuth 2.1 flow for remote servers (spec-defined) | Authorization logic, PII scrubbing, audit |
| Lifecycle | initialize → capabilities negotiation → operation → shutdown |
Server deployment, scaling, monitoring |
The Three Primitives in Depth
| Primitive | Direction | Control | What It Does | Real-World Example |
|---|---|---|---|---|
| Tools | Model → Server | Model-initiated (LLM decides when to call) | Functions with side effects — create, update, delete, compute | create_jira_ticket(summary, priority) |
| Resources | Server → Model | Application-controlled (host app decides when to attach) | Read-only data — files, DB records, API responses. Like GET endpoints | file://contracts/acme-2024.pdf |
| Prompts | Server → Model | User-initiated (user selects from menu) | Reusable prompt templates with arguments. Standardize common workflows | summarise_contract(jurisdiction="EU") |
MCP Message Lifecycle
JSON-RPC Under the Hood
Every MCP message is a JSON-RPC 2.0 request or response. Here's what flows over the wire when the LLM calls a tool:
// Client → Server: tool invocation request
{
"jsonrpc": "2.0",
"id": "req-42",
"method": "tools/call",
"params": {
"name": "create_jira_ticket",
"arguments": {
"summary": "Login page returns 500 on Safari",
"priority": "high"
}
}
}
// Server → Client: success response
{
"jsonrpc": "2.0",
"id": "req-42",
"result": {
"content": [{
"type": "text",
"text": "Created JIRA-1234: Login page returns 500 on Safari (Priority: High)"
}]
}
}
// Server → Client: error response
{
"jsonrpc": "2.0",
"id": "req-42",
"error": {
"code": -32603,
"message": "Jira API rate limit exceeded. Retry after 30s."
}
}