Fix case-insensitive handling of text MIME types for FileResource

当 MCP Python SDK 的 FileResource 收到混合大小写或全大写的 text 媒体类型(如 Text/Markdown 、 TEXT/plain )时,会被误判为二进制资源,导致文本内容以 bytes 返回。优先排查 MIME 类型比较是否做了大小写归一化。

快速结论:当 MCP Python SDK 的 FileResource 收到混合大小写或全大写的 text 媒体类型(如 Text/Markdown、TEXT/plain)时,会被误判为二进制资源,导致文本内容以 bytes 返回。优先排查 MIME 类型比较是否做了大小写归一化。

适用环境:Issue 已确认环境为 Python 3.12.13、MCP Python SDK 1.28.1(测试于 v2 main 分支 commit 3a6f299),修复在 v2.0.0 发布。操作系统与显卡等未在 Issue 中说明。

最快修复方案:升级到包含 #3171 修复的 v2.0.0 或更高版本;该版本将 FileResource 的 is_binary 替换为 encoding 字段,并在 text/* 判断前将媒体类型转为小写。

注意事项:该修复只覆盖 FileResource 资源侧。streamable HTTP server 中 Content-Type 请求头的比较(src/mcp/server/streamable_http.py)属于另一处代码,仍未标准化大小写,需等待 #2918 处理。若在 2.x 上仍遇到混合大小写 text/* 被当作 blob 返回,可在原 Issue 下重新开启反馈。

问题场景

使用 MCP Python SDK 创建 FileResource 时,如果传入的 mime_type 不是全小写形式,例如 Text/Markdown 或 TEXT/plain,调用方期望该资源按文本读取,但 SDK 却将其归类为二进制。这会影响后续依赖文本内容的下游消费者,使其拿到 bytes 而不是文本。

报错原文

Fix case-insensitive handling of text MIME types for FileResource

assert resource.is_binary is False
# mixed-case text/* MIME type is classified as binary

"application/json" -> True
"Application/JSON" -> True
"application/json; charset=utf-8" -> True
"APPLICATION/JSON; CHARSET=UTF-8" -> True
"text/plain" -> False

原因分析

最可能的原因是 FileResource 判断文本类型时,直接用区分大小写的方式检查 MIME 类型是否以 text/ 开头,没有先把值归一化为小写。按照 RFC 9110 §8.3.1,媒体类型本身大小写不敏感,application/json、Application/JSON 与 APPLICATION/JSON 等价,text/* 也同样如此。因此 Text/Markdown 不匹配小写的 text/ 前缀,被错误归为二进制。

此外,Issue 评论指出 streamable HTTP server 中对 Content-Type 请求头的比较也没有标准化 .lower(),这是与资源侧不同的另一处问题,由 #2918 跟进。

环境排查

  • 确认 MCP Python SDK 版本:Issue 报告使用 1.28.1,修复进入 v2.0.0。
  • 确认 Python 版本:Issue 报告为 Python 3.12.13。
  • 确认触发点:是 FileResource 的 mime_type 判断,还是 streamable HTTP server 的 Content-Type 头比较。
  • 确认传入的 MIME 类型大小写形式,例如是否使用了 Text/Markdown、TEXT/plain 等非全小写值。

解决步骤

  1. 先确认当前 SDK 版本是否低于 v2.0.0,因为 #3171 的修复在 v2.0.0 中发布。
  2. 升级到 v2.0.0 或更高版本,获取 FileResource 资源侧的大小写不敏感修复。
  3. 升级后检查 FileResource 的文本类型判断:修复版本使用 encoding 字段替代 is_binary,并在判断 text/* 前将媒体类型转为小写。
  4. 如果仍看到混合大小写 text/* 被当作 blob 返回,且问题出现在 streamable HTTP server 的 Content-Type 比较上,则跟踪 #2918 的修复进展;该处尚未包含在此次 FileResource 修复中。
  5. 如果确认在 2.x 上资源侧仍有问题,按 Issue 维护者说明,可在原 Issue 下重新开启并附上复现信息。

验证方法

使用修复后的版本,构造 mime_type 为 Text/Markdown 的 FileResource,确认其被识别为文本资源而非二进制;同时测试 TEXT/plain 等全大写形式。若涉及 HTTP 侧,还需单独验证 streamable HTTP server 对 Content-Type 的解析是否已做大小写归一化,未修复前不要将资源侧结果等同于 HTTP 侧结果。

参考来源

modelcontextprotocol/python-sdk #3131

modelcontextprotocol/python-sdk #2918

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 26616

发表回复

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