目录
一、协议本质:JSON-RPC 2.0 + 约定
核心组成
1. JSON-RPC 2.0 基础
二、协议消息全集(核心内容)
1. 初始化消息(初始化握手)
2. 工具相关消息
3. 资源相关消息
4. 通知消息(服务器主动推送)
三、协议传输层
支持两种传输方式
STDIO 通信示例
四、协议中的核心概念
1. 工具(Tools)规范
2. 资源(Resources)规范
3. 内容(Content)类型
五、完整通信流程示例
完整会话示例
六、协议的错误处理
错误响应格式
常见错误码
七、协议扩展性
扩展字段
能力协商
八、实际实现示例
Python 实现片段
完整通信追踪
九、协议设计哲学
为什么这样设计?
与其他协议对比
十、总结:MCP 协议是什么
MCP 协议是Model Context Protocol 的规范,定义了 LLM 与工具之间的标准通信方式。
一、协议本质:JSON-RPC 2.0 + 约定
核心组成
MCP 协议 = JSON-RPC 2.0 基础协议 + 特定消息约定 + 传输约定1. JSON-RPC 2.0 基础
每个消息都是这样的 JSON:
{ "jsonrpc": "2.0", // 必填,版本标识 "id": 1, // 请求ID,用于匹配响应 "method": "tools/list", // 方法名 "params": {...} // 参数 }响应格式:
{ "jsonrpc": "2.0", "id": 1, // 与请求的 id 对应 "result": {...} // 成功结果 // 或 "error": {...} // 错误信息 }二、协议消息全集(核心内容)
1. 初始化消息(初始化握手)
客户端 → 服务器:
{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": { "roots": { "listChanged": true }, "tools": {}, "resources": {} }, "clientInfo": { "name": "claude", "version": "1.0.0" } } }服务器响应:
{ "jsonrpc": "2.0", "id": 1, "result": { "protocolVersion": "2024-11-05", "capabilities": { "tools": {}, "resources": {} }, "serverInfo": { "name": "weather-server", "version": "1.0.0" } } }2. 工具相关消息
列出工具:
// 请求 { "jsonrpc": "2.0", "id": 2, "method": "tools/list" } // 响应 { "jsonrpc": "2.0", "id": 2, "result": { "tools": [ { "name": "get_weather", "description": "获取天气信息", "inputSchema": { "type": "object", "properties": { "city": {"type": "string"}, "unit": {"enum": ["celsius", "fahrenheit"]} }, "required": ["city"] } } ] } }调用工具:
// 请求 { "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "get_weather", "arguments": { "city": "北京", "unit": "celsius" } } } // 响应 { "jsonrpc": "2.0", "id": 3, "result": { "content": [ { "type": "text", "text": "北京天气:晴,25°C,湿度 60%" }, { "type": "image", "data": "base64...", "mimeType": "image/png" } ], "isError": false } }3. 资源相关消息
列出资源:
// 请求 { "jsonrpc": "2.0", "id": 4, "method": "resources/list" } // 响应 { "jsonrpc": "2.0", "id": 4, "result": { "resources": [ { "uri": "file:///reports/q4.md", "name": "Q4 报告", "description": "第四季度财务报告", "mimeType": "text/markdown" } ] } }读取资源:
// 请求 { "jsonrpc": "2.0", "id": 5, "method": "resources/read", "params": { "uri": "file:///reports/q4.md" } } // 响应 { "jsonrpc": "2.0", "id": 5, "result": { "contents": [ { "uri": "file:///reports/q4.md", "mimeType": "text/markdown", "text": "# Q4 财务报告\n\n收入:...\n利润:..." } ] } }4. 通知消息(服务器主动推送)
资源变更通知:
{ "jsonrpc": "2.0", "method": "notifications/resources/updated", "params": { "resources": [ { "uri": "file:///reports/q4.md", "changed": true } ] } }进度通知:
{ "jsonrpc": "2.0", "method": "notifications/progress", "params": { "progressToken": "abc123", "progress": 0.5, "total": 100 } }三、协议传输层
支持两种传输方式
1. 标准输入输出(STDIO)
客户端进程 │ ├─STDIN───┐ │ ▼ │ 服务器进程 │ ▲ └─STDOUT──┘通过管道通信
一行一个 JSON 消息
用换行符分隔
2. HTTP + Server-Sent Events(SSE)
客户端 ──HTTP POST──▶ 服务器 │ │ │◀──SSE 流───────────│ │ │ └──HTTP POST───▶ │ (调用工具) │STDIO 通信示例
# 服务器读取消息 import sys import json def read_message(): line = sys.stdin.readline() if not line: return None return json.loads(line) def send_message(msg): json.dump(msg, sys.stdout) sys.stdout.write('\n') sys.stdout.flush() # 客户端发送 echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}}' | python server.py四、协议中的核心概念
1. 工具(Tools)规范
{ "name": "tool_name", // 工具标识,全局唯一 "description": "...", // 给 LLM 看的描述 "inputSchema": { // JSON Schema "type": "object", "properties": { "param1": {"type": "string"} }, "required": ["param1"] } }2. 资源(Resources)规范
{ "uri": "scheme://path", // 统一资源标识符 "name": "显示名称", "description": "...", // 资源描述 "mimeType": "text/plain" // 内容类型 }3. 内容(Content)类型
{ "content": [ { "type": "text", // 文本内容 "text": "Hello World" }, { "type": "image", // 图片 "data": "base64...", "mimeType": "image/png" }, { "type": "resource", // 引用其他资源 "resource": { "uri": "file:///doc.md", "mimeType": "text/markdown" } } ] }五、完整通信流程示例
完整会话示例
// 1. 初始化 客户端 → {"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}} 服务器 ← {"jsonrpc":"2.0","id":1,"result":{...}} // 2. 列出工具 客户端 → {"jsonrpc":"2.0","id":2,"method":"tools/list"} 服务器 ← {"jsonrpc":"2.0","id":2,"result":{...}} // 3. 调用工具 客户端 → {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{...}} 服务器 ← {"jsonrpc":"2.0","id":3,"result":{...}} // 4. 资源变更通知(服务器主动) 服务器 ← {"jsonrpc":"2.0","method":"notifications/resources/updated","params":{...}} // 5. 列出资源 客户端 → {"jsonrpc":"2.0","id":4,"method":"resources/list"} 服务器 ← {"jsonrpc":"2.0","id":4,"result":{...}}六、协议的错误处理
错误响应格式
{ "jsonrpc": "2.0", "id": 123, "error": { "code": -32601, // JSON-RPC 标准错误码 "message": "Method not found", "data": { // MCP 扩展信息 "type": "INVALID_TOOL", "details": "Tool 'xyz' not found" } } }常见错误码
错误码 | 含义 | 场景 |
|---|---|---|
-32600 | 无效请求 | JSON 格式错误 |
-32601 | 方法不存在 | 调用未定义的方法 |
-32602 | 无效参数 | 参数不符合 schema |
-32700 | 解析错误 | JSON 解析失败 |
-32000 | 服务器错误 | 工具执行异常 |
七、协议扩展性
扩展字段
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {...}, "annotations": { // 扩展字段 "auth": {"token": "..."}, "trace": {"id": "abc123"} } }能力协商
{ "capabilities": { "tools": { "listChanged": true, // 支持工具变更通知 "callParallel": true // 支持并行调用 }, "resources": { "subscribe": true, // 支持资源订阅 "listChanged": true }, "prompts": {} // 提示词能力 } }八、实际实现示例
Python 实现片段
import json import sys import asyncio from typing import Dict, Any class MCPServer: def __init__(self, name: str): self.name = name self.tools = {} self.resources = {} async def handle_message(self, msg: Dict[str, Any]) -> Dict[str, Any]: method = msg.get("method") if method == "initialize": return { "jsonrpc": "2.0", "id": msg["id"], "result": { "protocolVersion": "2024-11-05", "serverInfo": {"name": self.name} } } elif method == "tools/list": return { "jsonrpc": "2.0", "id": msg["id"], "result": { "tools": [ { "name": "echo", "description": "Echo input", "inputSchema": { "type": "object", "properties": { "text": {"type": "string"} } } } ] } } elif method == "tools/call": tool_name = msg["params"]["name"] arguments = msg["params"]["arguments"] if tool_name == "echo": return { "jsonrpc": "2.0", "id": msg["id"], "result": { "content": [{ "type": "text", "text": arguments.get("text", "") }] } }完整通信追踪
# 启动服务器 $ python simple_server.py # 通信过程(STDIO) 发送: {"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}} 接收: {"jsonrpc":"2.0","id":1,"result":{...}} 发送: {"jsonrpc":"2.0","id":2,"method":"tools/list"} 接收: {"jsonrpc":"2.0","id":2,"result":{"tools":[...]}} 发送: {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{...}} 接收: {"jsonrpc":"2.0","id":3,"result":{"content":[...]}}九、协议设计哲学
为什么这样设计?
基于 JSON-RPC 2.0:
成熟标准,广泛支持
请求-响应模型简单
良好的错误处理
STDIO 传输:
语言无关性
简单可靠
无需网络配置
声明式工具定义:
LLM 可理解工具用途
运行时发现能力
类型安全输入
资源概念:
统一数据访问
变更通知机制
内容协商能力
与其他协议对比
协议 | 特点 | 与 MCP 的区别 |
|---|---|---|
OpenAI Function Calling | 函数调用,供应商绑定 | MCP 是开放协议 |
gRPC | 高性能 RPC,复杂 | MCP 更简单,JSON 友好 |
REST API | HTTP 资源操作 | MCP 是 LLM 专用协议 |
LSP | 编辑器语言服务 | 类似理念,不同领域 |
十、总结:MCP 协议是什么
MCP 协议是:
一套规范:定义了 LLM 如何与外部工具通信
基于 JSON-RPC 2.0:使用成熟的 RPC 标准
传输无关:支持 STDIO 和 HTTP/SSE
声明式:工具和资源有明确的 schema
双向通信:客户端调用工具,服务器主动通知
扩展性强:支持多种内容类型和扩展字段
简单说:
MCP 协议 = JSON 消息格式 + 通信约定 + 工具定义规范核心价值:
标准化 LLM 工具调用
实现工具的动态发现
提供安全的执行环境
支持丰富的返回类型
这就是为什么说 MCP Server 是"遵循 MCP 协议的进程"——它必须按照这个规范接收和发送 JSON 消息,才能与 Claude 等 LLM 应用正常通信。