Skip to content

Day 8 — MCP 设计文档

设计目标:实现 MCP(Model Context Protocol)的客户端和服务端,让 Agent 能调用外部工具服务(作为客户端),也能把自己的工具暴露给外部使用(作为服务端),通过标准化的 JSON-RPC 2.0 协议通信。


一、核心接口设计

1.1 MCPMessage(基于 JSON-RPC 2.0)

字段类型说明
jsonrpcstr固定值 "2.0"
idOptional[int]请求/响应 ID(通知没有)
methodOptional[str]请求的方法名
paramsOptional[dict]请求参数
resultOptional[Any]成功响应结果
errorOptional[MCPError]错误响应

MCPMethod 枚举

方法说明
INITIALIZE"initialize"握手初始化
TOOLS_LIST"tools/list"列出可用工具
TOOLS_CALL"tools/call"调用工具
NOTIFICATION"notifications/message"通知消息

MCPError

字段说明
code标准错误码(-32700 解析错误、-32600 无效请求、-32601 方法不存在、-32603 内部错误)
message错误描述

1.2 MCPClient

方法签名说明
connectasync connect(command, args)启动子进程并连接
initializeasync initialize() -> dict握手
discover_toolsasync discover_tools() -> List[RemoteTool]发现远程工具
call_toolasync call_tool(name, args) -> Any调用远程工具
closeasync close()关闭连接

1.3 MCPServer

方法签名说明
startasync start()启动服务(监听 stdin)
handle_requestasync handle_request(msg) -> MCPMessage处理请求并返回响应

1.4 RemoteTool

继承 Tool 接口,作为远程工具的本地代理:

属性/方法说明
name来自远程工具定义
description来自远程工具定义
parameters来自远程工具定义
execute内部调用 client.call_tool()

二、关键流程图

MCPClient 连接与发现流程

MCPServer 请求处理流程

端到端调用流程


三、设计决策与权衡

决策 1:基于 JSON-RPC 2.0

方案优点缺点
JSON-RPC 2.0(选择)标准化、简单、与官方 MCP 规范一致文本协议,性能不如二进制
gRPC / Protobuf高性能、强类型复杂,学习成本高
自定义 JSON 格式完全自由不标准,互操作性差

选择理由:MCP 协议规范本身就基于 JSON-RPC 2.0,保持一致性。且 JSON 可读性好,适合教学和调试。

决策 2:Stdio 传输层

方案优点缺点
Stdio(选择)零配置、安全(无网络暴露)仅限本机
HTTP/SSE支持远程调用需要端口配置、网络安全
WebSocket全双工同上

选择理由:教学阶段用 Stdio 最简单——MCPClient 直接用 subprocess 启动 MCPServer,通过 stdin/stdout 通信。理解了协议后,换 HTTP 传输层只需替换 IO 读写部分。

决策 3:RemoteTool 透明代理

RemoteTool 实现了和本地 Tool 完全一样的接口,Agent 无需区分工具是本地还是远程的:

方案优点缺点
透明代理(选择)Agent 代码零修改,本地远程一视同仁远程调用延迟不可见
显式区分可以针对远程做超时/重试Agent 代码需要感知工具来源

选择理由:"代理模式"是经典设计模式——消费者不关心实现细节。这也是 MCP 协议的核心价值:标准化让集成变得透明

决策 4:请求 ID 管理

MCPClient 用递增整数作为请求 ID,维护一个 pending_requests: Dict[int, Future] 映射:

python
self._next_id += 1
future = asyncio.get_event_loop().create_future()
self._pending[request_id] = future
# 发送请求...
# 收到响应时根据 id 找到 future 并设置结果

这样可以在同一个连接上并发多个请求,通过 ID 匹配响应。


四、与前序章节的集成点

  • 依赖 Day 5:MCPServer 暴露的是 ToolRegistry 中的工具;RemoteTool 继承 Tool 接口
  • 被 Day 4 依赖:MCPClient 发现的远程工具注册到 ToolRegistry,供 AgentRuntime 使用

五、与真实生产系统的对比

维度miniOpenClaw生产级实现
传输层Stdio(本机)HTTP + SSE / WebSocket(跨网络)
认证API Key / OAuth2 / mTLS
工具发现一次性 list动态发现 + 缓存 + 版本检查
错误处理基础错误码完整 JSON-RPC 错误码 + 重试
资源管理未实现MCP Resources(文件、数据库等)
采样未实现MCP Sampling(服务端请求客户端 LLM 能力)
连接池单连接连接池 + 健康检查 + 负载均衡