MCP 的 JSON-RPC 消息详解
JSON-RPC 的极简结构让智能体协议既易于扩展,又能保证实现一致性。理解 MCP 消息模型,是打造高质量 AI 系统的关键一步。
在 AI 协议体系中,消息格式既是通信的桥梁,也是生态兼容的关键。深入掌握模型上下文协议(MCP)的 JSON-RPC 消息结构,是构建稳健智能系统的第一步。
消息模型概览
MCP 采用 JSON-RPC 2.0(Remote Procedure Call, 远程过程调用)作为基础通信协议,定义三种核心消息类型。下表总结了各类型的用途与响应要求:
| 消息类型 | 是否需要响应 | 用途 |
|---|---|---|
| Request | 是 | 发起调用,期望获得响应 |
| Response | 否(仅作为回复) | 返回请求执行结果 |
| Notification | 否 | 单向事件通知,不需应答 |
下面分别给出三种消息类型的典型 JSON 示例:
// Request 示例
{ "jsonrpc": "2.0", "id": "123", "method": "tools/list", "params": {} }
// Response 示例
{ "jsonrpc": "2.0", "id": "123", "result": { "tools": [] } }
// Notification 示例
{ "jsonrpc": "2.0", "method": "progress", "params": { "progress": 50 } }
为了更直观地理解消息交互流程,下面用时序图展示 Request/Response 与 Notification 的典型过程:
能力协商机制(Capabilities)
在 MCP 会话初始化阶段,双方通过 initialize 请求进行能力交换。客户端声明自身支持的特性,服务端返回其可提供的能力,交集即为实际可用范围。
下表列举了能力协商相关字段及示例:
| 字段 | 说明 | 示例 |
|---|---|---|
protocolVersion | 协议版本号 | "2024-11-05" |
capabilities | 声明可用功能 | {"sampling": {}, "roots": {"listChanged": true}} |
clientInfo | 客户端信息 | {"name": "my-client", "version": "1.0.0"} |
resources.subscribe)前,需确认服务端 capabilities 中声明支持。常见消息类型与示例
本节介绍 MCP 协议中最常用的消息类型及其典型用法。
生命周期消息(Lifecycle)
生命周期相关消息用于初始化会话、能力协商及健康检查。下表总结了主要方法及其作用:
| 方法 | 类型 | 作用 |
|---|---|---|
initialize | 请求 | 初始化会话并协商能力 |
initialized | 通知 | 客户端通知初始化完成 |
ping | 请求/响应 | 健康检查 |
以下为典型生命周期消息的 JSON 示例:
// initialize
{ "jsonrpc": "2.0", "id": 1, "method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {"sampling": {}, "roots": {"listChanged": true}},
"clientInfo": {"name": "my-client", "version": "1.0.0"}
}
}
// ping
{ "jsonrpc": "2.0", "id": 2, "method": "ping", "params": {} }
{ "jsonrpc": "2.0", "id": 2, "result": {"status": "ok"} }
工具调用消息(Tools)
工具相关消息用于查询和执行可用工具。下表说明了常用方法:
| 方法 | 类型 | 说明 |
|---|---|---|
tools/list | 请求 | 获取工具列表及输入 schema |
tools/call | 请求 | 调用指定工具执行任务 |
下面是工具调用消息的典型 JSON 示例:
// tools/list
{ "jsonrpc": "2.0", "id": 3, "method": "tools/list" }
// 响应
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"tools": [{ "name": "calculate", "inputSchema": {} }]
}
}
资源消息(Resources)
资源相关消息支持对外部资源的订阅、变更监听与读取。下表列举了常用方法:
| 方法 | 类型 | 功能 |
|---|---|---|
resources/subscribe | 请求 | 订阅资源更新 |
resources/updated | 通知 | 资源更新通知 |
以下为资源消息的典型 JSON 示例:
// 订阅日志文件
{ "jsonrpc": "2.0", "id": 7, "method": "resources/subscribe",
"params": { "uri": "file:///logs/app.log" } }
{ "jsonrpc": "2.0", "method": "resources/updated",
"params": { "uri": "file:///logs/app.log" } }
提示模板消息(Prompts)
提示模板相关消息用于列出或获取可用的 Prompt 模板。响应中通常含 messages 字段,供采样或生成使用。
采样消息(Sampling)
采样消息用于服务端向客户端请求大语言模型(LLM, Large Language Model)生成文本。以下为典型 JSON 示例:
{ "jsonrpc": "2.0", "id": 11, "method": "sampling/createMessage",
"params": {
"messages": [
{ "role": "user", "content": {"type": "text", "text": "What is the capital of France?"} }
],
"maxTokens": 100
}
}
{ "jsonrpc": "2.0", "id": 11,
"result": {
"role": "assistant",
"content": {"type": "text", "text": "The capital of France is Paris."}
}
}
日志消息(Logging)
日志相关消息用于设置日志级别和输出日志内容。下表说明了主要方法:
| 方法 | 类型 | 功能 |
|---|---|---|
logging/setLevel | 请求 | 设置日志级别 |
logging/message | 通知 | 输出日志内容 |
错误与异常机制
MCP 的错误处理遵循 JSON-RPC 规范。下方 JSON 示例展示了标准错误响应结构:
{
"jsonrpc": "2.0",
"id": 13,
"error": {
"code": -32601,
"message": "Method not found",
"data": {"method": "unknown/method"}
}
}
常见错误码及含义如下表所示:
| 错误码 | 含义 |
|---|---|
| -32700 | Parse error |
| -32600 | Invalid request |
| -32601 | Method not found |
| -32602 | Invalid params |
| -32603 | Internal error |
| -32000 ~ -32099 | MCP 特定错误(Server error) |
- 响应必须带原始请求的
id; - 通知不可带
id; - 不支持的能力不应调用。
进度与取消机制
对于长任务,MCP 支持通过 progress 通知回报进度,取消则由 cancelled 通知触发。下方为典型 JSON 示例:
{ "jsonrpc": "2.0", "method": "progress",
"params": { "progressToken": "task-1", "progress": 40, "total": 100, "message": "Running" } }
{ "jsonrpc": "2.0", "method": "cancelled",
"params": { "requestId": 7, "reason": "user interrupt" } }
调试建议与实现要点
开发 MCP 协议时,需关注以下实现细节。下表总结了常见建议:
| 关注点 | 建议 |
|---|---|
| 能力声明 | 使用对象结构声明,避免布尔值错误 |
| ID 保持一致 | 响应与请求必须 ID 对齐 |
| 批量请求 | 支持数组形式一次提交多请求 |
| 初始化 | protocolVersion 为必填字段 |
| 命名空间 | 方法名应为如 tools/list、resources/subscribe 形式 |
TypeScript 实现示例(伪代码)
下面代码展示了 MCP 消息处理的典型 TypeScript 伪实现。该函数根据消息类型分别处理请求与通知,并严格遵循 JSON-RPC 错误返回规范。
async function handleMessage(message) {
if (message.id !== undefined) {
try {
const result = await processRequest(message);
return { jsonrpc: "2.0", id: message.id, result };
} catch (error) {
return {
jsonrpc: "2.0",
id: message.id,
error: { code: -32603, message: error.message },
};
}
}
await processNotification(message);
}
总结
MCP 基于 JSON-RPC 的统一消息模型,通过严格的结构约定和能力协商机制,使得客户端与服务端之间的通信具备 可预测性、可扩展性与一致性。开发者应在实现时保持协议约束、能力声明与错误处理的严格对齐,从而让智能体生态在不同实现间实现真正的互操作。