1. MCP 与 JSON‑RPC:需要理解一次的“无聊”基础
在上一讲里我们讨论了为什么需要 MCP,以及它如何融入 Apps SDK 栈。这一讲我们把焦点缩小到最“无聊”的一层——MCP 消息格式,这样你就能自信地阅读原始 JSON 日志,明白 ChatGPT 到底发给你的服务器了什么、服务器又返回了什么。
MCP 使用 JSON‑RPC 2.0 作为数据传输:所有请求、响应和通知,都是具有可预期模式的普通 JSON 对象。
也就是说,不再是“每个服务自创一套格式”,而是有一个基础契约:
- 请求必须包含字段 jsonrpc(通常为 "2.0")、唯一的 id、字符串方法名 method,以及包含参数的 params 对象;
- 响应通过 id 与请求关联,并且只包含 result 或 error 二者之一;
- 通知(notifications)与请求类似,但没有 id,也不期望收到响应。
大致如下:
{
"jsonrpc": "2.0",
"id": 42,
"method": "tools/list",
"params": {
"cursor": null
}
}
这是一个 request。成功时的回复:
{
"jsonrpc": "2.0",
"id": 42,
"result": {
"tools": [],
"nextCursor": null
}
}
如果你想到“这不就是普通的 RPC 吗”,没错。MCP 只是进一步固定了有哪些具体方法(tools/list、tools/call、resources/list、prompts/list,…)以及它们使用什么格式来接收参数并返回数据。
要把握的一点是:JSON‑RPC 是“请求—响应—通知”的骨架;MCP 则规定了“具体有哪些请求以及它们的内容”。
2. Request:MCP 如何提出要执行的操作
从请求开始。请求总是朝“某人想做点什么”的方向。通常是客户端 → 服务器(ChatGPT → 你的 MCP 服务器),但 MCP 也允许反向请求,即服务器请求客户端做 sampling 或 elicitation。本讲我们主要关注经典情形:客户端请求服务器。
任何 MCP request 都有三个关键字段:
- jsonrpc —— JSON‑RPC 协议版本,通常 "2.0"。
- id —— 请求标识;可以是任意 JSON 类型,但实践中多为数字或字符串。关键是对活动请求来说 id 必须唯一。
- method —— 形如 "tools/list" 或 "tools/call" 的字符串。MCP 规定了一组允许的方法。
还有一个 params 对象,具体方法的参数都放在这里。
示例:请求工具列表
假设 ChatGPT 刚连接到你的 MCP 服务器,想知道它可以调用哪些 tools。它会发送大致如下的请求:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {
"cursor": null
}
}
字段 cursor 用于分页——如果工具很多,服务器可以分批返回。
对于我们的教学应用(挑选礼物)这里暂时会比较无聊:就一两个工具,但协议不变。先把它当作直观示例;更正式的结构我们会在 tools 章节再看。
示例:调用工具(tools/call)
现在稍微有意思一点。假设我们已有 MCP tool suggest_gifts,你会在讲 MCP 服务器时实现它。它期望的参数有:
- occasion —— 场合(Birthday、Wedding 等),
- budget —— 美元金额,
- recipient —— 字符串,描述收礼人。
当 ChatGPT 决定使用这个工具时,会构造如下 MCP 请求:
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "suggest_gifts",
"arguments": {
"occasion": "birthday",
"budget": 100,
"recipient": "friend who loves board games"
}
}
}
注意以下几点。
首先,工具名称来自你在服务器端的声明(server.registerTool("suggest_gifts", …))。其次,arguments 对象必须符合你在工具描述中提供的 JSON Schema。
如果 GPT 试图发送不符合模式的参数(例如,budget: "一百美元"),服务器可以根据实现选择在协议层或业务逻辑层返回错误。此时只需抓住这种请求的一般形态;在下文工具章节中我们会更系统地看这些消息。
资源与提示的 Requests
对资源与提示的请求也类似。MCP 规范定义了这些方法:
- resources/list —— 枚举可用资源;
- resources/read(或 resources/get)—— 通过 URI 读取具体资源;
- prompts/list —— 获取可用提示列表;
- prompts/get —— 获取某个提示的内容。
读取包含礼物目录的资源的请求示例:
{
"jsonrpc": "2.0",
"id": 15,
"method": "resources/read",
"params": {
"uri": "mcp://gift-server/resources/gift_catalog"
}
}
先记住两点。其一,每个原语都有 */list 与 */get/*/read 方法。其二,方法名总是在字符串字段 method 中,所有内容都在 params&nb
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/sinat_25548781/article/details/165630671




