快速结论:该报错发生在 MCP Python SDK(1.x 版本)中,当客户端发送 notifications/cancelled 取消一个正在处理的请求(如 tools/call)时,服务端的 RequestResponder.cancel 会额外向对方发送一条 Request cancelled 错误响应,违反 MCP 取消规范( SHOULD NOT send a response for the cancelled request)。优先排查 SDK 版本是否为 1.x,并考虑升级到 2.x 或应用 monkey-patch 临时修复。
适用环境:mcp 1.27.0、Python 3.11、stdio transport。
最快修复方案:将 MCP Python SDK 升级到 v2.0.0 或更高版本(该版本已通过 #3188 修复,取消的请求不再返回任何响应)。如果无法升级,可在下游服务端 monkey-patch RequestResponder.cancel 屏蔽 _send_response 调用。
注意事项:1.x 分支目前仅接收关键修复,官方建议在 1.x 场景下使用 Issue 正文提供的 monkey-patch 作为临时方案;2.x 已修复该问题,但需验证你的项目与 2.x 的兼容性。
问题场景
用户通过 stdio transport 运行 MCP Python SDK 服务端,当客户端发起一个长时间运行的 tools/call(例如 await asyncio.sleep、自定义轮询工具、长数据库查询),随后发送 notifications/cancelled 取消该请求时,服务端会在取消后主动向客户端发送一条带有 Request cancelled 的 JSON-RPC 错误响应。严格的客户端(如 Claude Code)会将此响应识别为未知消息 ID,关闭传输并重新连接。
报错原文
{"jsonrpc": "2.0", "id": 99, "error": {"code": 0, "message": "Request cancelled"}}
Received a response for an unknown message ID
原因分析
RequestResponder.cancel 方法(mcp/shared/session.py 中的 cancel)在收到 notifications/cancelled 后,除取消 _cancel_scope 和设置 _completed = True 外,还会调用 _session._send_response 向请求方发送一条 ErrorData(code=0, message="Request cancelled") 响应。这违反了 MCP 规范中“接收方不应为已取消的请求发送响应”的明确要求(详见 cancellation.mdx 规范第 33-36 行)。
环境排查
- 确认 MCP Python SDK 版本:在
1.x分支(如 1.27.0)存在该行为;2.0.0 及更高版本已修复。 - 确认 Python 版本(Issue 中验证为 3.11,其他版本可能同样受影响)。
- 确认传输方式为 stdio transport(其他传输方式可能也会触发,但 Issue 未验证)。
- 确认客户端是否为严格实现(如 Claude Code),会因未知消息 ID 断开传输。
解决步骤
- 首选方案:将 MCP Python SDK 升级到 v2.0.0 或更高版本——官方确认 #3188 已修复该问题,取消的请求不会再收到合成响应。
- 临时方案(1.x 环境):在下游服务端入口处应用 monkey-patch,覆盖
RequestResponder.cancel,移除_send_response调用:
from mcp.shared.session import RequestResponder
async def _cancel_without_response(self) -> None:
if not self._entered:
raise RuntimeError("RequestResponder must be used as a context manager")
if not self._cancel_scope:
raise RuntimeError("No active cancel scope")
self._cancel_scope.cancel()
self._completed = True
RequestResponder.cancel = _cancel_without_response
- 升级后仍需验证:确保发送
notifications/cancelled后,服务端不再输出Request cancelled响应。
验证方法
在 stdio 传输下,按 Issue 复现步骤操作:发送 initialize + notifications/initialized,再发送一个等待中的 tools/call,然后发送 notifications/cancelled 并根据请求 ID 观察服务端 stdout——不再出现 {"jsonrpc": "2.0", "id": 99, "error": {"code": 0, "message": "Request cancelled"}} 即表示修复生效。若使用 Claude Code 作为客户端,应不再出现 Received a response for an unknown message ID 且不会触发传输重连。
参考来源
modelcontextprotocol/python-sdk #2480
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug]: Failed to add the siliconflow model in version 0.22.1](https://www.chat-gpts.plus/wp-content/uploads/2026/08/11515-8122380b-768x403.jpg)
![[Question]: Ragflow frontend build failed](https://www.chat-gpts.plus/wp-content/uploads/2026/08/11566-887690ef-768x403.jpg)
![[Question]: After creating an agent in version 0.21.1, the screen goes blank and nothing is displayed.](https://www.chat-gpts.plus/wp-content/uploads/2026/08/11734-d8142ce2-768x403.jpg)