
目标读者:第一次接触 MCP、对 JSON-RPC 不熟、习惯 REST 思维的同学。
一、先用一句话理解 MCP
MCP(Model Context Protocol)是一个让 AI 客户端与外部工具/数据源统一通信的协议标准。
它不是某个具体 API,而是一套"如何发现工具、如何调用工具、如何回传结果"的通用规则。
你可以把它类比成:
- REST:面向资源(URL + HTTP 方法)
- MCP:面向模型工具协作(JSON-RPC + 会话 + 能力协商)
二、JSON-RPC 是什么?(MCP 的消息语言)
MCP 常用 JSON-RPC 2.0 编码消息。核心字段只有几个:
jsonrpc:协议版本(固定"2.0")id:请求编号(用于请求-响应关联)method:调用的方法名(例如tools/list、tools/call)params:方法参数
一个最小请求示例:
json
{
"jsonrpc": "2.0",
"id": 101,
"method": "tools/call",
"params": {
"name": "list_releases",
"arguments": {
"owner": "wisdomfriend",
"repo": "github_watch_dual"
}
}
}
对应响应示例:
json
{
"jsonrpc": "2.0",
"id": 101,
"result": {
"content": [
{
"type": "text",
"text": "..."
}
]
}
}
三、为什么 MCP 不是"两个 REST 接口就够了"?
很多同学会问:
"做两个 REST 不就行了吗?比如 GET /tools + POST /call。"
在单项目里可以这么做,但会遇到两个关键问题:
- 并发调用时,请求-响应关联要自己维护
- 流式返回、通知机制要自己再造一遍
这两个问题,我们在项目里都做了可运行演示。
四、项目实战演示 1:并发请求为什么必须靠 id
1)演示入口
启动项目:
bash
cd github_watch_dual
uvicorn src.api:app --reload --port 8090
请求并发演示接口:
bash
curl http://127.0.0.1:8090/demo/jsonrpc/concurrent
2)你会看到什么
接口会返回三组关键数据:
requests_sent:发出的请求(带id)responses_in_arrival_order:按到达顺序的响应(可能乱序)responses_mapped_by_id:按id重新关联后的映射
3)这说明了什么
并发场景下,响应不保证按请求顺序返回。
如果不用 id 做关联,客户端就可能"对错号"。
这就是为什么 MCP/JSON-RPC 把 id 设计为核心字段,而不是可选装饰。
五、项目实战演示 2:流式通知为什么不是普通 REST 一次响应
1)演示入口
访问流式接口:
bash
curl -N http://127.0.0.1:8090/demo/jsonrpc/stream
2)你会看到什么
服务端会持续推送 text/event-stream:
- 先发多条
notifications/progress - 最后发一条带
id的最终result
这就是"通知"和"最终结果"并存的通信模式。
3)这说明了什么
如果只用最朴素 REST 一问一答:
- 你很难优雅地表达中间进度通知
- 或者需要额外造轮子(轮询、WebSocket、SSE 规范、自定义事件格式)
MCP 把这类模式标准化了,客户端和服务端都按同一协议处理。
六、结合真实 MCP 客户端代码理解四层职责
项目里真实调用代码(src/tool_backends.py)是:
streamablehttp_client(...):建立传输通道(transport)ClientSession(read, write):协议会话封装(session)session.initialize():握手/能力协商(初始化阶段)session.call_tool(...):真正工具调用(业务阶段)
它看起来比 REST 多几步,但本质是在做协议分层,减少跨系统集成时的长期复杂度。
七、session.initialize() 到底在做什么?
初始化阶段常见职责:
- 客户端与服务端确认协议版本
- 交换能力声明(支持哪些功能)
- 建立会话上下文(某些服务端会分配 Session ID)
如果跳过这步,常见后果是:
- 客户端按 A 能力调用,服务端按 B 能力处理
- 版本不匹配导致奇怪错误
- 会话状态不完整导致后续调用失败
八、新手常见误区
-
误区 1:MCP 就是"另一个 REST API"
- 纠正:MCP 是协议标准,HTTP 只是其中一种传输层。
-
误区 2:
id可有可无- 纠正:并发时
id是请求-响应关联的关键。
- 纠正:并发时
-
误区 3:一次响应就够,通知不重要
- 纠正:工具调用常需要进度、事件、最终结果分阶段输出。
九、什么时候该用 MCP,什么时候不用?
建议用 MCP:
- 你要把工具能力开放给多个 AI 客户端(IDE、Agent、服务)
- 你希望复用一套标准调用协议,减少重复集成
- 你需要并发、通知、流式等高级交互能力
不一定要用 MCP:
- 单次脚本、一次性实验
- 单客户端单后端、生命周期很短的小项目
十、结语
MCP 看起来"比 REST 麻烦",本质是把复杂度从"每个项目重复造轮子"变成"一次标准化"。
对新手来说,先记住这句话就够:
REST 适合快速做资源接口,MCP 适合做可复用的模型工具协议。
参考资料
- MCP Transports(官方):https://modelcontextprotocol.io/docs/concepts/transports
- MCP 最新规范(Transports):https://modelcontextprotocol.io/specification/latest/basic/transports
- MCP SDK 总览:https://modelcontextprotocol.io/docs/sdk
- Python SDK:https://github.com/modelcontextprotocol/python-sdk
- Anthropic MCP 介绍:https://www.anthropic.com/research/model-context-protocol