- 数据层: 定义了基于 JSON-RPC 定义客户端-服务器通信协议,协议层包含生命周期管理和核心原语;同时支持对工具、资源和提示等对象的操作
- 传输层: 定义了客户端和服务器之间进行数据交换的通信机制和通道,包括特定于传输的连接建立、消息帧和授权
数据层的标准化
JSON-RPC协议
所有工具都必须用统一的格式描述——包括工具名、使用说明、参数结构、返回格式等
Agent 向 MCP Server 索取所有工具说明清单这一步在 MCP 中称为 "初始化", 对应一次 JSON-RPC 请求
MCP 中的每一次请求,本质上都是在交换 JSON-RPC 2.0 标准的数据包
是什么?
JSON-RPC 是两个服务之间通过发送 JSON 数据来进行沟通的一种“通用语言”
- RPC (Remote Procedure Call):就是指远程过程调用。在 A 服务上调用一个函数,但实际上这个函数是在 B 服务上运行的,B 把结果运行完再传回给 A
- JSON:所有的数据传输都使用最通用的 JSON 格式,无论Agent是用什么编程语言写的,大家都能看懂对方发来的信息
- 无状态 (Stateless):每一次请求都是独立的,就像寄信一样,寄出去一封,收回来一封,协议本身不记忆之前的状态
JSON-RPC格式
请求体:
{
"jsonrpc": "2.0", // 1. 版本号:必须是 "2.0"
"method": "tools/call", // 2. 方法名:需要执行的操作
"params": { // 3. 参数:执行操作需要的数据
"name": "get_weather", // 4. 调用的函数名
"arguments": {
"city": "Beijing" // 5. 函数入参
}
},
"id": 1 // 6. ID:请求的编号号,用于匹配回信
}
响应体:
{
"jsonrpc": "2.0",
"result": { // 1. 结果:成功时的返回数据
"content": [
{
"type": "text",
"text": "北京今天晴,气温 25 度"
}
]
},
"id": 1 // 2. ID:对应请求的 ID
}
错误结构:
{
"jsonrpc": "2.0",
"error": { // 错误对象
"code": -32601, // 标准错误码
"message": "Method not found" // 错误信息
},
"id": 1
}
MCP 如何利用 JSON-RPC 工作?
初始化阶段-建立连接与能力协商
- 能力协商: 客户端和服务端会确认协议版本、功能支持等信息。
- 就绪通知: 初始化完成后,客户端会发送 notifications/initialized 告知服务器已准备好。
意义: 保证双方在同一协议下通信,建立通信基础,为后续工具发现和调用做好准备。
示例
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"roots": {
"listChanged": true
},
"sampling": {},
"elicitation": {}
},
"clientInfo": {
"name": "ExampleClient",
"title": "Example Client Display Name",
"version": "1.0.0"
}
}
}
初始化成功后,客户端必须发送initialized通知,表明其已准备好开始正常运行
如果没有这步,服务端会认为客户端并未准备好,所以将禁止后续的其他操作。
{
"jsonrpc": "2.0",
"method": "notifications/initialized"
}
工具发现阶段-索取工具列表清单
- 标准化描述: 每隔工具都以Json描述名称、参数类型、返回值格式和使用说明
- 无需理解内部逻辑: agent不需要知道具体实现,只需要知道工具需要什么和能返回什么
- 动态发现: 工具可能随时变化,每次获取都是最新工具列表
对外提供的能力
- Resources(资源): 供外部直接读取的外部数据,如文件、API结果等
- Tools(工具): 供外部调用工具服务
- Prompts(提示): 预定义的提示词模板
示例
{
"jsonrpc": "2.0",
"method": "tools/list",
"params": {},
"id": 100
}
调用阶段
LLM 决策需要调用某个 MCP 服务时,Agent 会构建标准 JSON-RPC 请求发送给 MCP Server
示例
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {
"city": "Beijing"
}
},
"id": 101
}
MCP Server执行流程
- 解析工具名和参数,根据name找到对应工具执行
- 执行工具
- 返回结果,构造符合JSON-RPC格式的结果返回
工具变更阶段-处理工具列表更新
- 变更通知: 服务端通过
notifications/tools/list/changed通知客户端工具列表已更新 - 重新获取: 客户端收到通知后重新请求获取清单并更新内部工具注册表
- 保证一致性: Agent始终知道最新可用工具,实现动态适应和高可扩展性
示例
{
"jsonrpc": "2.0",
"method": "notifications/tools/list_changed",
"params": {}
}
传输层标准化
stido-标准输入输出
父子进程 Stdio 传输不涉及任何网络协议 (TCP/HTTP), 本质是进程间通信
SSE-Server-Sent Events
单向通讯只推不收, 因此需双端方案实现, 即接收通道和发送通道
痛点
- 状态维护,client必须维护一个长连接接收和一个短连接发送
- 重连机制,无法自动断点重连,需要双方定时心跳维护长连接
Streamable HTTP
解决 SSE 模式中读写分离带来的架构复杂度和传统 HTTP 的一次性交互无法满足 MCP 双向异步通知、以及无法断点重连 等问题。
原理
Streamable HTTP 把所有交互集中到一个 HTTP POST 请求中, 利用 HTTP 流式能力承载 JSON-RPC 协议
- 单一连接,只维护一个端点
- 请求发送,报文放在POST请求的body发送
- 流式响应,利用分块传输编码(Chunked Encoding),将结果分批次实时吸入响应body中
优势
- 简化架构,一个端点实现双向异步通讯并且不区分读写
- 灵活性高,可以根据场景选择是否使用流式响应
- 资源效率高,不用一直维持sse长连接
- 更可靠的恢复机制,支持断点重连,可通过Session ID + Last‑Event-ID恢复会话
- 基础设施更友好,标准的HTTP基础设施(API网关、负载均衡等)兼容性更好