MCP 入门 —— (JSON-RPC 2.0 协议)
简介
JSON-RPC是一个无状态且轻量级的远程过程调用(RPC)协议**
在AI技术飞速演进的今天,底层通信协议的选择对系统效率和互操作性至关重要。新兴的AI协议如模型上下文协议(MCP)[1]和 Agent2Agent(A2A)[2]协议,都使用了 JSON-RPC 2.0 协议
协议
1. JSON-RPC 2.0:起源与核心规范
JSON-RPC协议的诞生,源于对早期RPC协议(如XML-RPC[4]、SOAP[5])复杂性的反思,旨在提供一种更轻量、更简洁的远程过程调用机制。其2.0版本规范(基于2009年草案,正式发布于2010年左右)更是将这一理念发扬光大。其核心设计哲学正如规范开篇所言:“It is designed to be simple!”
核心原则
我们先来看一下JSON-RPC协议设计的几个核心原则。
- Stateless (无状态): 每次请求都是独立的,服务器不保存客户端状态。
- Light-weight (轻量级): 协议开销小,消息体紧凑。
- JSON Data Format (JSON数据格式): 使用广泛流行、易于解析和人类可读的JSON(RFC 4627[6]) 作为数据交换格式。
- Transport Agnostic (传输无关): 协议本身不限定网络传输方式,可在HTTP、WebSocket[7]、TCP、甚至进程内等多种环境使用。
请求对象
一个 JSON-RPC 2.0 请求数据是一个单一的 JSON 对象,可以包含以下成员:
jsonrpc:字符串,指定 JSON-RPC 的版本号,对于 2.0 规范来说,这个值必须是 2.0。
method:字符串,指定要调用的远程方法的名称。
params:结构化值,可以是数组或者对象,传递给远程方法的参数。如果方法不需要参数可以省略。
id:唯一标识符,可以是字符串或数字,用于关联请求和响应,服务端必须返回相同的值。如果请求是一个通知类型,则此参数可以被省略
一个标准的 JSON-RPC 2.0 请求示例如下:
|
|
响应对象
一个 JSON-RPC 2.0 响应数据也是一个单一的 JSON 对象,可以包含以下成员:
- jsonrpc:字符串,指定 JSON-RPC 的版本号,对于 2.0 规范来说,这个值必须是2.0。
- result:当请求成功时,包含由远程方法返回的结果。如果请求失败,则不包含此成员。
- error:当请求失败时,包含一个错误对象。如果请求成功,则不包含此成员。
- id:与请求中的 id 相同,用于识别哪个请求对应的响应。
错误对象包括以下成员:
- code:整数,用于说明错误类型。JSON-RPC 2.0 定义了一组标准的错误码。
- message:字符串,提供关于错误的简短描述。
- data:可选,可以包含额外的错误信息,比如堆栈信息等。
一个成功的响应示例如下:
|
|
而一个异常响应示例如下:
|
|
通知
通知是一种特殊类型的请求,没有 id 成员,因此不会得到响应。这样客户端可以向服务器发送事件或命令而无需等待回复。一个通知示例如下:
|
|
批量请求
JSON-RPC 2.0 支持批量请求,即可以在单个请求中发送多个 JSON-RPC 调用。每个调用都是独立的 JSON-RPC 请求对象,被放在一个数组中。服务器处理这些请求后返回一个数组,其中每个元素对应于一个调用。需要注意的是,如果其中一个调用是通知,则不会有对应的响应项。
|
|
错误码
JSON-RPC 2.0 规范中定义了标准的错误码,但开发者也可以根据自己的业务逻辑添加自定义的错误码。这些自定义错误代码应该在-32000到-32099之间,以避免与标准错误码冲突。通过使用自定义错误码,可以为客户端提供更加具体的错误信息。
假如这样一个场景,应用程序需要处理用户认证失败的情况,可以定义一个特定的错误码,比如 -32001,并为这个错误码配一个说明,如 Authentication failed。示例如下:
|
|
此外,还可以在 error 的 data 参数中包含更多的错误细节,比如错误发生的具体位置或建议的解决方法。
JSON-RPC 2.0 定义的标准错误码如下(自定义错误吗不要使用如下几个):
32700: 解析错误,服务器收到无效的 JSON。
32600: 无效请求,发送的 JSON 不是有效的请求对象。
32601: 方法未找到,方法不存在或无效。
32602: 无效参数,提供的参数无效。
32603: 内部错误,JSON-RPC 内部错误。
2.GO实现案例——基于 http
client 端
|
|
server 端
|
|
|
|
3.使用场景
JSON-RPC 2.0 的使用场景包括但不限于如下几个:
- Web 应用程序,客户端与服务器之间的异步通信,例如浏览器与后端服务交互。
- 微服务之间的通信,通过 JSON-RPC 调用其他微服务的接口。
- 物联网设备,设备与服务器之间的通信,由于 JSON-RPC 的轻量级特性,非常适合资源受限的设备。
- 移动应用,移动客户端与服务器之间的交互,减少数据传输量,提高响应速度。
- 区块链和加密货币,节点之间的通信或客户端与节点的交互,许多区块链系统(如以太坊)使用 JSON-RPC 进行接口调用。
- 远程过程调用(RPC)服务,替代传统的 SOAP 或 XML-RPC,提供简单的接口调用机制。
文档和版本控制
良好的文档对于任何 API 都至关重要,尤其是像 JSON-RPC 2.0 这样依赖于明确的请求和响应格式的协议。
- 编写清晰的 API 文档:详细描述每个方法的用途、参数、返回值和可能的错误情况。可以使用工具如 Swagger 或 Postman 来生成交互式的 API 文档。
- 保持文档更新:随着 API 的发展,确保文档始终保持最新状态,反映最新的变更和改进。
- 版本控制:为 API 引入版本控制,以便在不影响现有用户的情况下进行更新。可以在 URL 中或通过请求头指定 API 版本。
社区和支持
JSON-RPC 2.0 是一个开放的标准,拥有活跃的社区和丰富的资源。参与社区讨论、阅读官方文档和技术博客、关注相关论坛和社交媒体,都可以帮助更快地解决问题,并获取最新的最佳实践。
此外,很多流行的编程语言和框架都有现成的 JSON-RPC 库,可以大大简化开发过程。选择一个成熟且维护良好的库,不仅可以节省时间,还能减少出错的可能性。
4.小结
JSON-RPC 2.0作为一种轻量级的 RPC 协议,提供了如标准化的错误处理、批量请求支持和通知机制等功能,具有简单、易用、跨语言等优点,适用于多种分布式系统场景。