Session ID not present in memory store should return 404, not 400

在运行基于 MCP Python SDK 构建的 Streamable HTTP 服务器时,客户端连接时若提供的 Mcp-Session-Id 在服务器内存存储中不存在(例如服务器重启导致 session 丢失),本应返回 404 让客户端重新初始化,但服务器返回了 400。这会阻止客户端正确恢复连

快速结论:该报错发生在使用 MCP Python SDK 的 Streamable HTTP 传输时,当客户端提供的 Session ID 在内存中不存在(例如服务器重启后),服务器错误地返回 HTTP 400 而非 404。优先检查你的 MCP Python SDK 版本是否已合并修复 PR #1945。

问题场景

在运行基于 MCP Python SDK 构建的 Streamable HTTP 服务器时,客户端连接时若提供的 Mcp-Session-Id 在服务器内存存储中不存在(例如服务器重启导致 session 丢失),本应返回 404 让客户端重新初始化,但服务器返回了 400。这会阻止客户端正确恢复连接。

报错原文

# 问题代码位置: src/mcp/server/streamable_http_manager.py 第250-256行
# 服务器在 session 不存在时返回 HTTP 400,而不是预期的 404
HTTP 400 Bad Request: Session ID not present in memory store

原因分析

这是 MCP Python SDK 的一个已知行为缺陷。如 Issue #880 所述,session 不会在服务器重启间持久化。当客户端使用一个未持久化的 session ID 连接时,服务器将其视为“错误请求”(400),但实际上该请求本身并无错误,只是 session 因服务器重启而丢失。正确的语义是返回 404 Not Found,这样客户端可以据此发起新的初始化流程获取新 session ID。该问题在 src/mcp/server/streamable_http.py 第371行已有类似 404 处理逻辑,但在 streamable_http_manager.py 中未被覆盖。

环境排查

  • 确认 MCP Python SDK 版本(Issue 报告环境:Python 3.10.12 + MCP SDK 2.3.4)
  • 检查是否使用了 StreamableHTTPSessionManager 作为 session 管理
  • 确认服务器已重启且 session 未被持久化(如不使用外部 session 存储)

解决步骤

  1. 更新 SDK 到修复版本:升级 MCP Python SDK 到包含 PR #1945 的版本。该 PR 在 v1.x 分支和 main 分支均已合入,StreamableHTTPSessionManager 现在会对未知/过期 session ID 返回 HTTP 404。
  2. 验证修复来源:确认你的版本包含 commit 引用自 PR #1945(等同于之前修复 #1727 的变更)。
  3. 检查客户端重试逻辑:确保客户端(例如基于 mcp-go 的实现)在收到 404 后能正确发起重新初始化并获取新 session ID(参考 mark3labs/mcp-go 客户端的 streamable_http.go:257 处理)。
  4. 替代方案(如无法升级):手动修改 streamable_http_manager.py 中返回 400 的逻辑,改为返回 404。但注意此修改需自行维护,官方已修复。

验证方法

在服务器重启后,使用原有(已失效)的 Mcp-Session-Id 发送请求,确认服务器返回 HTTP 404 而非 400。然后检查客户端是否能据此发起新的初始化请求并获得新的有效 session ID,后续正常通信。

参考来源

modelcontextprotocol/python-sdk #1004

PR #1945: 修复返回 404

Issue #1727(重复问题)

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 18313

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注