Skip to main content
模型上下文协议(MCP)支持通过通知消息对正在进行中的请求进行可选取消。客户端应该发送取消通知,以表明它先前发出的某个请求应被终止。 当服务器拆除某个 subscriptions/listen 请求 ID 对应的订阅流时,必须发送引用该请求 ID 的 notifications/cancelled(请参见 订阅)。服务器不得出于任何其他目的发送 notifications/cancelled

取消流程

当客户端想要取消正在进行中的请求时,它会发送一个 notifications/cancelled 通知,其中包含:
  • 要取消的请求 ID
  • 一个可选的原因字符串,可用于记录或显示
{
  "jsonrpc": "2.0",
  "method": "notifications/cancelled",
  "params": {
    "requestId": "123",
    "reason": "用户请求取消"
  }
}

特定于传输的取消

客户端如何发出取消信号取决于传输方式:
  • Streamable HTTP:关闭 SSE 响应流即表示取消信号。
    服务器必须将客户端断开连接视为该请求的取消。不需要也不应期望 notifications/cancelled 消息。
  • stdio:没有可关闭的按请求流。客户端必须发送一个引用该请求 ID 的 notifications/cancelled 通知。

超时

实现应该为所有已发送的请求设置超时,以防止连接挂起和资源耗尽。当请求在超时时间内未收到成功或错误响应时,发送方应该取消该请求并停止等待响应。如特定于传输的取消所述,这意味着:
  • Streamable HTTP:关闭该请求的响应流,这就构成了取消。
  • stdio:发送一个引用该请求 ID 的 notifications/cancelled 通知。
SDK 和其他中间件应该允许按请求粒度配置这些超时。 实现可以在收到与该请求对应的进度通知时重置超时计时,因为这意味着工作确实正在进行中。不过,无论是否收到进度通知,实现应该始终强制执行一个最大超时,以限制有异常行为的客户端或服务器所造成的影响。

行为要求

  1. 取消通知必须仅引用以下请求:
    • 之前由客户端发出的请求
    • 被认为仍在进行中的请求
  2. 服务器发送的取消通知必须引用一个 subscriptions/listen 请求,以终止该订阅流
  3. 接收到取消通知的服务器应该
    • 停止处理已取消的请求
    • 释放相关资源
    • 不要为已取消的请求发送响应
  4. 服务器可以忽略取消通知,如果:
    • 所引用的请求未知
    • 处理已经完成
    • 该请求无法取消
  5. 客户端应该忽略之后到达的任何针对已取消请求的响应

时序考虑

由于网络延迟,取消通知可能在请求处理完成后到达,甚至可能在响应已经发送之后到达。 双方必须妥善处理这些竞态条件:

实现说明

  • 双方应该记录取消原因以便调试
  • 应用程序 UI 应该在请求取消时予以指示

错误处理

无效的取消通知应该被忽略:
  • 未知的请求 ID
  • 已完成的请求
  • 格式错误的通知
这保留了通知“发出即忘记”的特性,同时允许异步通信中的竞态条件。