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

[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.xdnf.cn/news/16521.html

相关文章:

  • 机器学习之线性回归——小白教学
  • LRU(Least Recently Used)原理及算法实现
  • 最新优茗导航系统源码/全开源版本/精美UI/带后台/附教程
  • BreachForums 黑客论坛强势回归
  • sqLite 数据库 (2):如何复制一张表,事务,聚合函数,分组加过滤,列约束,多表查询,视图,触发器与日志管理,创建索引
  • JAVA_TWENTY—ONE_单元测试+注解+反射
  • 学习Python中Selenium模块的基本用法(3:下载浏览器驱动续)
  • Seq2Seq学习笔记
  • 前端优化之虚拟列表实现指南:从库集成到手动开发
  • 嵌入式学习日志————TIM定时中断之定时器定时中断
  • Python算法实战:从排序到B+树全解析
  • 算法精讲:二分查找(一)—— 基础原理与实现
  • 自学嵌入式 day37 HTML
  • 信号上升沿时间与频谱分量的关系
  • FastAPI后台任务:异步魔法还是同步噩梦?
  • Simulink建模-Three-Phase V-I Measurement 模块详解
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现各种食物的类型检测识别(C#代码UI界面版)
  • react 的 useTransition 、useDeferredValue
  • GitHub下载项目完整配置SSH步骤详解
  • Python day28
  • Linux重定向的理解
  • Mysql缓冲池和LRU
  • 树形结构递归查询与嵌套结构转换:Flask + PostgreSQL 完整实现
  • Linux 启动流程、密码破解、引导修复完全手册
  • MoR vs MoE架构对比:更少参数、更快推理的大模型新选择
  • vue面试题
  • AI驱动的知识管理新时代:释放组织潜力的关键武器
  • Python Flask: Windows 2022 server SMB账户(共享盘账户)密码修改
  • Java注解全面解析与应用实战
  • 在Word和WPS文字中把全角数字全部改为半角