当前位置: 首页 > news >正文

[mcp: JSON-RPC 2.0 规范]

1. 概述

JSON-RPC 是一种无状态、轻量级的远程过程调用(RPC)协议。本规范主要定义了几种数据结构以及它们的处理规则。它与传输协议无关,能够在同一进程内、通过套接字、HTTP 或多种消息传递环境中使用。它使用 JSON(RFC 4627)作为数据格式。

设计上,它的目标是简洁明了。

2. 术语

文中使用的关键词如 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY” 和 “OPTIONAL” 的解释遵循 RFC 2119。

JSON-RPC 使用 JSON 作为数据格式,JSON 的类型系统包括四种原始类型(字符串、数字、布尔值和 null)以及两种结构化类型(对象和数组)。此文中提到的 JSON 类型首字母总是大写。

所有 Client 和 Server 之间交换的成员名称,特别是涉及匹配的,应该区分大小写。方法(method)和函数(function)、过程(procedure)可以视为同义词。

  • Client:请求对象的发起者和响应对象的处理者。
  • Server:响应对象的发起者和请求对象的处理者。

一个实现可以同时担任这两个角色,分别处理不同客户端或同一客户端的请求。

3. 兼容性

JSON-RPC 2.0 的请求对象和响应对象与现有的 JSON-RPC 1.0 客户端或服务器不兼容。2.0 版本始终包含名为 “jsonrpc” 的字段,值为 “2.0”;而 1.0 版本没有这个字段。大多数 2.0 实现应该尝试处理 1.0 对象,尽管不支持点对点或类提示的特性。

4. 请求对象

RPC 调用通过发送一个请求对象给服务器表示。请求对象包含以下成员:

  • jsonrpc:指定 JSON-RPC 协议的版本。值必须为 “2.0”。
  • method:包含要调用的方法名称。方法名称以 “rpc” 开头的为系统保留,不能使用。
  • params:一个结构化的值,包含在方法调用时使用的参数。该字段可以省略。
  • id:由客户端指定的标识符,必须是字符串、数字或 null。如果省略该字段,则默认为通知类型。若包含,服务器返回的响应对象也必须包含该值,以便关联上下文。

4.1 通知

通知是没有 “id” 字段的请求对象。通知意味着客户端不关心响应,因此服务器不需要返回响应。通知不能确认,因此客户端无法得知是否发生错误。

4.2 参数结构

参数可以通过位置或名称传递:

  • 按位置传递:参数必须是一个数组,按照服务器预期的顺序传递。
  • 按名称传递:参数必须是一个对象,其中成员名称应与服务器预期的参数名称完全匹配。

5. 响应对象

服务器在处理请求时会返回一个响应对象,除非是通知类型。响应对象包含以下成员:

  • jsonrpc:指定 JSON-RPC 协议的版本。值必须为 “2.0”。
  • result:在成功时返回,表示方法的返回值。出错时,该字段不能存在。
  • error:在错误时返回,表示方法执行中的错误。没有错误时,该字段不能存在。包含错误详情的对象。
  • id:与请求对象中的 id 值相同。如果请求对象的 id 无法识别,返回 null。

5.1 错误对象

当 RPC 调用遇到错误时,响应对象中的 error 字段会包含以下信息:

  • code:一个整数,表示错误类型。
  • message:简短的错误描述。
  • data:一个可选的字段,包含错误的详细信息,值由服务器定义。

保留错误代码范围为 -32768 到 -32000,具体的错误代码定义如下:

错误代码错误信息含义
-32700解析错误无效的 JSON 格式。服务器解析 JSON 时出错。
-32600无效的请求发送的 JSON 不是有效的请求对象。
-32601方法未找到方法不存在或不可用。
-32602参数无效方法参数无效。
-32603内部错误服务器内部错误。
-32000 到 -32099服务器错误预留的服务器实现错误。

6. 批量请求

客户端可以同时发送多个请求对象,服务器将处理并返回相应的响应对象。批量请求的响应是一个数组,包含每个请求的响应对象。

  • 响应中的每个对象对应一个请求对象,通知类型的请求不会返回响应对象。
  • 批量请求可以并行处理,服务器处理顺序和并行度可以自由选择。
  • 如果批量请求本身无效,服务器返回一个单一的响应对象,而不是空数组。

7 示例

  1. 带位置参数的 RPC 调用

    --> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
    <-- {"jsonrpc": "2.0", "result": 19, "id": 1}--> {"jsonrpc": "2.0", "method": "subtract", "params": [23, 42], "id": 2}
    <-- {"jsonrpc": "2.0", "result": -19, "id": 2}
    
  2. 带命名参数的 RPC 调用

    --> {"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}
    <-- {"jsonrpc": "2.0", "result": 19, "id": 3}--> {"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 4}
    <-- {"jsonrpc": "2.0", "result": 19, "id": 4}
    
  3. 通知

    --> {"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]}
    --> {"jsonrpc": "2.0", "method": "foobar"}
    
  4. 调用不存在的方法

    --> {"jsonrpc": "2.0", "method": "foobar", "id": "1"}
    <-- {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "1"}
    
  5. 无效的 JSON 调用

    --> {"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz]
    <-- {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}
    
  6. 无效请求对象的调用

    --> {"jsonrpc": "2.0", "method": 1, "params": "bar"}
    <-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}
    
  7. 批量请求,含无效的 JSON

    --> [{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},{"jsonrpc": "2.0", "method": "foobar"}
    ]
    <-- {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}
    
  8. 带空数组的请求

    --> []
    <-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}
    
  9. 带无效元素的批量请求

    --> [1]
    <-- [{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}
    ]
    
  10. 无效的批量请求

    --> [1,2,3]
    <-- [{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null},{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null},{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}
    ]
    
  11. 批量请求

    --> [{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},{"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},{"foo": "boo"},{"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},{"jsonrpc": "2.0", "method": "get_data", "id": "9"}
    ]
    <-- [{"jsonrpc": "2.0", "result": 7, "id": "1"},{"jsonrpc": "2.0", "result": 19, "id": "2"},{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null},{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "5"},{"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"}
    ]
    
  12. 批量请求(全是通知)

    --> [{"jsonrpc": "2.0", "method": "notify_sum", "params": [1,2,4]},{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]}
    ]
    <-- // 所有通知批量没有返回内容
    

8 扩展

以 rpc. 开头的方法名称是为系统扩展保留的,必须避免用于其他目的。每个系统扩展在相关规范中定义。所有系统扩展都是可选的。

http://www.dtcms.com/a/305442.html

相关文章:

  • sqLite 数据库 (2):如何复制一张表,事务,聚合函数,分组加过滤,列约束,多表查询,视图,触发器与日志管理,创建索引
  • Python的魔术方法
  • 在 Cloudflare 平台上完整部署 GitHub 项目 MoonTV 实现免费追剧流程
  • 计算机网络基础(一) --- (网络通信三要素)
  • Deep Learning_ Foundations and Concepts-Springer (2024)【拜读】20章3节
  • Linux C:构造数据类型
  • python基础:request请求Cookie保持登录状态
  • Python高效历史记录管理:保存最后N个元素的完整指南
  • 机械学习--线性回归
  • 项目如何进行阶段性评估?核心要点
  • Java07--面向对象
  • 【收银系统开发】收银系统之数字键盘,人机交互中重复判断——仙盟创梦IDE
  • thingsboard 自定义动作JS编程
  • 1768. 交替合并字符串
  • 2025年06月 C/C++(四级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • 【C#学习Day13笔记】静态成员、接口、运算符重载和索引器
  • Redis 键值对操作详解:Python 实现指南
  • 【Dify】-进阶14- 用 Dify 搭建法律文档解析助手
  • 工作中使用git可能遇到的场景
  • docker docker、swarm 全流程执行
  • 抵御酒店管理系统收银终端篡改攻击 API 加密的好处及实现——仙盟创梦IDE
  • LLM中BLEU 指标、ROUGE 指标、PPL指标
  • MySQL图解索引篇
  • 7.29 Java SE(Java高级 P191-P199)
  • Linux 线程概念与控制
  • 继续打卡day6
  • SpringJDBC源码初探-DataSource类
  • 理解“无界队列”与“有界队列”及其适用场景
  • BigemapPro吸附功能 | 绘图共点共边,标绘从此无缝衔接!
  • 【Python】数据可视化之聚类图