取消
社区译文;来源: MCP 80041ab0
模型上下文协议(MCP)支持通过通知消息选择性地取消正在处理的请求。客户端SHOULD发送取消通知,表明应终止此前由其发出的请求。
当服务器关闭某个订阅流时,服务器MUST发送引用该 subscriptions/listen 请求 ID 的 notifications/cancelled(参见订阅
)。服务器MUST NOT将 notifications/cancelled 用于任何其他目的。
取消流程
客户端要取消正在处理的请求时,会发送一条 notifications/cancelled 通知,其中包含:
- 要取消的请求 ID
- 可选的原因字符串,可用于日志记录或显示
{
"jsonrpc": "2.0",
"method": "notifications/cancelled",
"params": {
"requestId": "123",
"reason": "User requested cancellation"
}
}特定于传输的取消方式
客户端如何发出取消信号取决于传输:
- 可流式 HTTP(Streamable HTTP):关闭 SSE 响应流即为取消信号。服务器MUST将客户端断开连接视为取消该请求。不需要也不应期待
notifications/cancelled消息。 - stdio:没有可供关闭的逐请求流。客户端MUST发送引用请求 ID 的
notifications/cancelled通知。
超时
实现SHOULD为所有已发送请求设置超时,以防止连接挂起和资源耗尽。如果请求在超时时间内未收到成功或错误响应,发送方SHOULD取消请求并停止等待响应。根据特定于传输的取消方式 ,这意味着:
- 可流式 HTTP(Streamable HTTP):关闭该请求的响应流,即构成取消。
- stdio:发送引用该请求 ID 的
notifications/cancelled通知。
SDK 和其他中间件SHOULD允许按请求配置这些超时。
实现MAY在收到与该请求对应的进度通知 时重置超时计时,因为这表明工作确实正在进行。但是,无论是否收到进度通知,实现都SHOULD始终强制执行最大超时,以限制行为不当的客户端或服务器造成的影响。
行为要求
- 取消通知MUST只能引用符合以下条件的请求:
- 此前由客户端发出
- 被认为仍在处理中
- 服务器发送的取消通知MUST引用
subscriptions/listen请求,以终止该订阅流 - 收到取消通知的服务器SHOULD:
- 停止处理已取消的请求
- 释放关联资源
- 不再为已取消的请求发送响应
- 在以下情况下,服务器MAY忽略取消通知:
- 引用的请求未知
- 处理已经完成
- 请求无法取消
- 客户端SHOULD忽略之后到达的、针对已取消请求的任何响应
时序注意事项
由于网络延迟,取消通知可能在请求处理完成后到达,甚至可能在响应已经发出后才到达。
双方都MUST妥善处理这些竞态条件:
sequenceDiagram
participant Client
participant Server
Client->>Server: 请求(ID: 123)
Note over Server: 开始处理
Client--)Server: notifications/cancelled(ID: 123)
alt
Note over Server: 取消到达前<br/>处理可能已经完成
else 尚未完成
Note over Server: 停止处理
end
实现说明
- 双方都SHOULD记录取消原因,以便调试
- 应用 UI SHOULD在请求取消时给出提示
错误处理
无效的取消通知SHOULD被忽略:
- 未知的请求 ID
- 已完成的请求
- 格式错误的通知
这样既能保持通知“发送后不等待响应”的性质,也能容纳异步通信中的竞态条件。