A complete technical breakdown of the Model Context Protocol: architecture, transports, message formats, and protocol flow.
┌────────────────────────────────────────────────────────────────┐
│ MCP CLIENT │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Claude │ │ Cursor │ │ Windsurf │ │
│ │ Desktop │ │ │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ Capabilities: │
│ • Sends requests via JSON-RPC 2.0 │
│ • Discovers server capabilities │
│ • Invokes tools and reads resources │
│ • Renders prompts to user │
│ │
└────────────────────────────────────────────────────────────────┘
↕
MCP PROTOCOL
(JSON-RPC 2.0 over stdio or SSE)
↕
┌────────────────────────────────────────────────────────────────┐
│ MCP SERVER │
│ │
│ Exposes 3 Core Primitives: │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ TOOLS │ │ RESOURCES │ │ PROMPTS │ │
│ ├──────────────┤ ├──────────────┤ ├──────────────┤ │
│ │ Functions │ │ Data sources │ │ Templates │ │
│ │ AI can call │ │ AI can read │ │ AI can use │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ Examples: │
│ • GitHub: create_issue(), list_prs(), search_code() │
│ • Postgres: run_query(), list_tables(), describe_schema() │
│ • Filesystem: read_file(), write_file(), search_files() │
│ │
└────────────────────────────────────────────────────────────────┘
↕
EXTERNAL SYSTEMS
(Databases, APIs, File Systems, etc)
MCP uses JSON-RPC 2.0 as its message format. This is a lightweight, language-agnostic protocol for remote procedure calls.
Example Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_files",
"arguments": {
"pattern": "*.tsx",
"path": "/src"
}
}
}Example Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "Found 42 files matching *.tsx in /src"
}
]
}
}MCP supports two transport mechanisms for sending JSON-RPC messages:
Standard input/output streams
Server-Sent Events over HTTP
Tools are functions that the AI can execute. Each tool has a name, description, and typed parameters defined with JSON Schema.
Tool Definition Example:
{
"name": "create_github_issue",
"description": "Creates a new issue in a GitHub repository",
"inputSchema": {
"type": "object",
"properties": {
"repo": {
"type": "string",
"description": "Repository name (owner/repo)"
},
"title": {
"type": "string",
"description": "Issue title"
},
"body": {
"type": "string",
"description": "Issue description"
},
"labels": {
"type": "array",
"items": { "type": "string" },
"description": "Labels to apply"
}
},
"required": ["repo", "title", "body"]
}
}TOOL INVOCATION FLOW:
tools/list requesttools/call with argumentsResources are data sources that the AI can access. Each resource has a URI and can optionally support subscriptions for updates.
Resource Definition Example:
{
"uri": "file:///Users/you/project/README.md",
"name": "README.md",
"description": "Project readme file",
"mimeType": "text/markdown"
}Resource Read Request:
{
"jsonrpc": "2.0",
"method": "resources/read",
"params": {
"uri": "file:///Users/you/project/README.md"
}
}KEY FEATURES:
{user_id}Prompts are pre-built templates that servers provide. Users can select them from the client UI, fill in arguments, and the prompt is sent to the AI.
Prompt Definition Example:
{
"name": "git-commit",
"description": "Generate a conventional commit message",
"arguments": [
{
"name": "changes",
"description": "Git diff output",
"required": true
}
]
}USE CASES:
Client starts the MCP server process (stdio) or connects to HTTP endpoint (SSE)
Client sends initialize request with its capabilities
{
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"roots": { "listChanged": true },
"sampling": {}
},
"clientInfo": {
"name": "Claude Desktop",
"version": "1.0.0"
}
}
}Server declares what it supports (tools, resources, prompts)
{
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {},
"resources": { "subscribe": true },
"prompts": {}
},
"serverInfo": {
"name": "filesystem-server",
"version": "1.0.0"
}
}
}Confirms handshake complete, connection ready
Client can now list tools, read resources, invoke prompts
MCP uses standardized JSON-RPC error codes. Servers return detailed error objects:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32602,
"message": "Invalid params",
"data": {
"details": "Missing required parameter 'repo'",
"expected": {
"repo": "string",
"title": "string",
"body": "string"
}
}
}
}STANDARD ERROR CODES
-32700 Parse error-32600 Invalid request-32601 Method not found-32602 Invalid params-32603 Internal errorCUSTOM ERROR CODES
-32000 Tool execution failed-32001 Resource not found-32002 Permission denied-32003 Rate limit exceeded