多轮往返请求(Multi Round-Trip Requests,MRTR)是在此版本的 MCP 规范中引入的。
它替代了以前发送服务器发起请求的做法。服务器 MUST 使用 MRTR 模式发送服务器到客户端请求
(例如
roots/list、sampling/createMessage 或 elicitation/create)。
以前的服务器发起请求模式不再受支持。这是一个破坏性变更。Multi Round-Trip Requests
Model Context Protocol (MCP) 定义了几种方式,使服务器可以在处理客户端请求期间向用户请求额外信息 (例如roots/list、sampling/createMessage 或 elicitation/create)。
多轮往返请求模式提供了一种标准化方式来处理这些服务器请求,而不需要跨服务器实例的共享存储层,
也不需要有状态负载均衡。
高层流程如下:
- 客户端向服务器发送初始请求,其中包含执行操作所需的参数。
- 服务器确定需要额外信息才能满足该请求,并以请求更多信息的响应回答。
- 客户端从用户或其他来源收集所请求的信息,然后带上额外请求的信息重试原始请求。
- 服务器确定已有足够信息完成操作,并以最终结果响应。
核心类型
此流程在 MCP 中使用以下类型实现。InputRequests
InputRequests 对象是服务器到客户端请求的映射。
键是服务器分配的字符串标识符;值是请求对象(例如 ElicitRequest、CreateMessageRequest 或 ListRootsRequest)。
InputResponses
InputResponses 对象是客户端对服务器请求的响应映射。
键对应于 InputRequests 映射中的键;值是客户端针对每个请求给出的结果(例如 ElicitResult、CreateMessageResult 或 ListRootsResult)。
InputRequiredResult
InputRequiredResult 是一种 Result,
表示在请求完成之前需要额外输入。
inputRequests(可选):客户端必须满足的服务器发起请求的InputRequests映射。requestState(可选):仅对服务器有意义的不透明字符串。客户端 MUST NOT 检查、解析、修改它,也不得对其内容作出任何假设。
Supported Requests
服务器 MAY 在以下客户端请求上发送InputRequiredResult 响应:
服务器 MUST NOT 在任何其他客户端请求上发送
InputRequiredResult 响应。
基本工作流
基本工作流描述服务器如何将向客户端请求额外输入作为客户端-服务器请求的一部分。 在此示例中,我们使用tools/call 作为客户端请求,但同一模式适用于上面列出的任何受支持请求。
值得注意的是,它允许服务器在不维护任何服务器端状态的情况下请求额外信息。
服务器会将任何所需上下文编码到 requestState 字段中,客户端在重试时将其原样回显。
请注意,每个步骤中的请求都是完全独立的:处理重试的服务器不需要除重试请求中直接存在的信息之外的任何信息。
Server Requirements (Basic Workflow)
-
服务器 MAY 使用
InputRequiredResult响应任何受支持的客户端请求。 -
InputRequiredResultMAY 包含inputRequests字段。inputRequests键是服务器分配的标识符,并且在请求作用域内 MUST 唯一。inputRequests值是请求对象,MUST 是ElicitRequest、CreateMessageRequest或ListRootsRequest之一
-
InputRequiredResultMAY 包含requestState字段。如果指定,该字段是仅对服务器有意义的不透明字符串。服务器可以自由使用任何格式编码状态(例如 base64 编码 JSON、加密 JWT、序列化二进制)。 -
如果客户端请求包含
requestState字段,服务器 MUST 将requestState视为攻击者可控输入。如果requestState影响授权、资源访问或业务逻辑,服务器 MUST 保护其完整性(例如 HMAC 或 AEAD), 并且 MUST 拒绝未通过验证的状态。只有当篡改最多导致请求失败时,完整性保护才 MAY 省略。 -
为防止重放,服务器 SHOULD 在受完整性保护的
requestState载荷中包含以下内容,并在收到时逐一验证:- 已认证主体;拒绝由不同主体提供的状态。
- 较短过期时间(TTL);拒绝在过期后提供的状态;
- 发起请求的标识符,例如方法名及其关键参数摘要;拒绝在不匹配请求上提供的状态。
-
服务器 MUST 在每个
InputRequiredResult响应中至少包含inputRequests或requestState之一。 -
服务器 MUST NOT 发送客户端未在其能力中声明支持的
inputRequests。例如,如果客户端未声明支持elicitation,服务器 MUST NOT 在inputRequests字段中包含任何elicitation/create请求。 -
服务器 MUST NOT 假设客户端会满足
inputRequests或重试原始请求。如果服务器希望反复提示用户提供信息,直到获得完成请求所需的信息,它 MAY 在同一请求的多次尝试中返回InputRequiredResult。
Client Requirements (Basic Workflow)
- 如果客户端收到包含
inputRequests字段的InputRequiredResult,客户端 MUST 在重试原始请求之前构造所请求的输入。如果InputRequiredResult不 包含inputRequests字段,客户端 MAY 立即重试原始请求。 - 如果
InputRequiredResult包含requestState字段,客户端 MUST 在重试原始请求时回显该字段的精确值。 客户端 MUST NOT 检查、解析、修改requestState内容,或对其作出任何假设。如果InputRequiredResult不包含requestState字段,客户端 MUST NOT 在重试中包含该字段。 - 初始请求和重试之间的 JSON-RPC
idMUST 不同,因为它们是独立请求。 inputRequests和requestState字段只影响客户端对原始请求的重试。它们 MUST NOT 用于客户端可能并行发送的任何其他请求。
错误处理
服务器 SHOULD 校验客户端提供的数据是有效的InputResponses 对象,并且其中的信息可以被正确解析。
协议错误(格式错误的 JSON、无效 schema、服务器内部错误)SHOULD 返回带有适当错误码和消息的 JSON-RPC 错误响应。
如果 InputResponses 对象中提供了额外的非预期参数,服务器 SHOULD 忽略任何它不识别或不需要的信息。
如果客户端未能发送先前 InputRequests 中请求的全部信息,而缺失的信息是服务器处理请求所必需的,
服务器 SHOULD 用新的 InputRequiredResult 响应,再次请求缺失信息,而不是返回错误。
安全考量
由于requestState 会经过客户端,恶意或受攻陷的客户端可能会尝试修改它,以改变服务器行为、
绕过授权检查或破坏服务器逻辑。服务器 MUST 按上方服务器要求所述校验请求状态。