引言
MCP协议基于 JSON-RPC 2.0 规范构建消息通信层。理解消息格式是掌握MCP协议的基础,也是开发MCP Server和Client的第一步。
本文将详细解析:
- JSON-RPC 2.0核心规范
- MCP请求/响应的消息结构
- 错误编码与处理约定
- 数据类型定义与序列化
- 消息校验与版本兼容
JSON-RPC 2.0 基础
什么是JSON-RPC?
JSON-RPC是一种轻量级的远程过程调用(RPC)协议。它使用JSON作为数据格式,支持请求-响应和通知两种通信模式。
┌─────────────────────────────────────────────────────────────┐
│ JSON-RPC 2.0 通信模型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Client Server │
│ │ │ │
│ │──── 请求 (Request) ────► │ │
│ │ │ │
│ │◄─── 响应 (Response) ──── │ │
│ │ │ │
│ │──── 通知 (Notification) ►│ (无响应) │
│ │ │ │
└─────────────────────────────────────────────────────────────┘
核心规范
| 特性 | 说明 |
|---|---|
| 传输 | 与传输层无关(stdio、SSE、WebSocket均可) |
| 格式 | 始终为JSON对象,非数组 |
| 版本 | 必须包含 jsonrpc: "2.0" 字段 |
| ID | 请求必须包含唯一ID,响应必须匹配对应ID |
| 通知 | 不包含ID的请求,Server无需响应 |
MCP消息结构
请求消息
MCP请求遵循JSON-RPC 2.0规范,增加MCP特定的方法命名空间:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_docs",
"arguments": {
"query": "MCP协议"
}
}
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
jsonrpc | string | 是 | 固定为 "2.0" |
id | number/string | 是 | 请求唯一标识,响应通过此ID匹配 |
method | string | 是 | MCP方法名,格式为 namespace/action |
params | object | 否 | 方法参数,可为null |
响应消息
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "搜索结果..."
}
],
"isError": false
}
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
jsonrpc | string | 是 | 固定为 "2.0" |
id | number/string | 是 | 与请求ID一致 |
result | object | 与error二选一 | 成功响应数据 |
error | object | 与result二选一 | 错误信息 |
错误响应
当请求处理失败时,Server返回错误响应:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32603,
"message": "Internal error",
"data": {
"details": "数据库连接超时",
"retryAfter": 5
}
}
}
MCP方法命名空间
MCP的方法按功能域组织,使用 域/操作 格式:
| 命名空间 | 方法 | 用途 |
|---|---|---|
| initialize | initialize | 连接初始化与能力协商 |
| ping | ping | 心跳检测 |
| notifications | notifications/initialized | 初始化完成通知 |
| resources | resources/list | 列出可用资源 |
| resources | resources/read | 读取资源内容 |
| resources | resources/subscribe | 订阅资源变更 |
| tools | tools/list | 列出可用工具 |
| tools | tools/call | 调用工具 |
| prompts | prompts/list | 列出可用提示模板 |
| prompts | prompts/get | 获取提示模板内容 |
| logging | logging/setLevel | 设置日志级别 |
方法分类
| 分类 | 方法 | 用途 |
|---|---|---|
| 生命周期 | initialize, notifications/initialized, ping | 连接建立与保活 |
| 工具管理 | tools/list, tools/call | 工具的发现与调用 |
| 资源管理 | resources/list, resources/read, resources/subscribe | 资源访问与订阅 |
| 提示管理 | prompts/list, prompts/get | 提示模板的管理 |
| 日志管理 | logging/setLevel | 运行时日志控制 |
错误编码规范
标准JSON-RPC错误码
| 错误码 | 名称 | 描述 |
|---|---|---|
-32700 | Parse Error | JSON解析失败 |
-32600 | Invalid Request | 无效的JSON-RPC请求 |
-32601 | Method Not Found | 请求的方法不存在 |
-32602 | Invalid Params | 参数验证失败 |
-32603 | Internal Error | 服务器内部错误 |
-32000 ~ -32099 | Server Error | 服务器自定义错误 |
MCP扩展错误码
MCP在标准错误码基础上增加协议级错误:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32002,
"message": "Tool execution failed",
"data": {
"toolName": "search_docs",
"errorType": "timeout",
"duration": 30000
}
}
}
| MCP错误码 | 含义 | 典型场景 |
|---|---|---|
-32000 | 工具未找到 | 请求的工具不存在 |
-32001 | 资源未找到 | 请求的资源URI无效 |
-32002 | 执行超时 | 工具执行超过时限 |
-32003 | 权限不足 | 无权访问指定资源 |
-32004 | 限流触发 | 请求频率过高 |
数据类型定义
基础类型
MCP使用JSON原生类型,并定义了内容类型:
// TypeScript类型定义
type RequestId = string | number;
interface TextContent {
type: "text";
text: string;
}
interface ImageContent {
type: "image";
data: string;
mimeType: string;
}
interface AudioContent {
type: "audio";
data: string;
mimeType: string;
}
type Content = TextContent | ImageContent | AudioContent;
工具参数Schema
工具参数使用JSON Schema定义输入验证规则:
{
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索关键词"
},
"limit": {
"type": "integer",
"description": "返回数量上限",
"minimum": 1,
"maximum": 100,
"default": 10
}
},
"required": ["query"]
}
}
消息校验
TypeScript实现
function validateMessage(raw: string): JSONRPCMessage {
let parsed: any;
try {
parsed = JSON.parse(raw);
} catch {
throw new Error("Parse Error: 无效的JSON格式");
}
if (parsed.jsonrpc !== "2.0") {
throw new Error("Invalid Request: JSON-RPC版本必须为2.0");
}
if (!parsed.method && !parsed.result && !parsed.error) {
throw new Error("Invalid Request: 必须包含method、result或error之一");
}
return parsed as JSONRPCMessage;
}
Python实现
import json
from typing import Any, Dict
def validate_mcp_message(raw: str) -> Dict[str, Any]:
"""验证并解析MCP消息"""
try:
data = json.loads(raw.strip())
except json.JSONDecodeError as e:
raise ValueError(f"Parse Error: {e}")
if data.get("jsonrpc") != "2.0":
raise ValueError("Invalid Request: jsonrpc版本不匹配")
has_method = "method" in data
has_result = "result" in data
has_error = "error" in data
if not (has_method or has_result or has_error):
raise ValueError("Invalid Request: 缺少method/result/error字段")
return data
调试与工具
# 使用MCP Inspector验证消息
npx @modelcontextprotocol/inspector
# 快速验证JSON-RPC格式
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
python3 -c "import json,sys; obj=json.load(sys.stdin); assert obj['jsonrpc']=='2.0'; print('Valid')"
总结
MCP的消息格式基于JSON-RPC 2.0提供了以下核心能力:
| 特性 | 优势 |
|---|---|
| 标准化 | 成熟稳定的RPC协议基础 |
| 可扩展 | 自描述的方法命名空间机制 |
| 类型安全 | 完整的JSON Schema验证支持 |
| 版本兼容 | 协商机制确保平滑演进 |
下一步学习建议:
本文最后更新于 2024-06-30。