快速结论:该报错发生在 Python 3.10 环境下,当 MCP 工具的返回值注解为包含 NotRequired 键的 TypedDict 时,工具注册阶段会触发 PydanticForbiddenQualifier 异常。优先排查是否使用了 typing.get_type_hints 而非 typing_extensions.get_type_hints 来解析注解。
适用环境:MCP Python SDK 2.x(main 分支)、Python 3.10(3.11 及以上不受影响)、依赖 pydantic 与 typing_extensions。
最快修复方案:暂无确认的一步修复方案(补丁已提交但尚未合并)。若需自行修复,可尝试将 src/mcp/server/mcpserver/utilities/func_metadata.py 中的 get_type_hints 导入来源从 typing 改为 typing_extensions。
注意事项:此修复方案来自 Issue 评论中的补丁确认,但尚未合并到主分支,使用时需自行评估风险并验证兼容性。
问题场景
在 Python 3.10 环境下使用 MCP Python SDK 注册工具,工具返回值注解为包含 NotRequired 键的 TypedDict 时触发。报错发生在 @mcp.tool() 装饰器执行阶段,导致工具在 import 时即注册失败,工具永远不会被创建。
报错原文
pydantic.errors.PydanticForbiddenQualifier: The annotation 'NotRequired[int]' contains the 'typing.NotRequired' type qualifier, which is invalid in the context it is defined.
原因分析
根因位于 src/mcp/server/mcpserver/utilities/func_metadata.py 的 _create_model_from_typeddict 函数。该函数使用 typing.get_type_hints 解析 TypedDict 注解,并将结果直接传给 create_model。但 typing.get_type_hints 仅在 Python 3.11 及以上版本会剥离 Required/NotRequired 限定符;在 Python 3.10 上,field_type 仍是 NotRequired[int],pydantic 会拒绝 TypedDict 上下文之外的裸限定符。
观察到的差异:
python 3.10.19 typing.get_type_hints(Person) -> {'name': str, 'age': typing_extensions.NotRequired[int]}
python 3.13.12 typing.get_type_hints(Person) -> {'name': str, 'age': int}
typing_extensions.get_type_hints 在两个版本上都会返回剥离后的形式。
环境排查
- 确认 Python 版本是否为 3.10(3.11 及以上不受影响)
- 确认 MCP Python SDK 版本为 2.x(main 分支)
- 确认 typing_extensions 已安装且版本支持
NotRequired - 检查返回值注解是否包含
NotRequired键(而非total=False的 TypedDict)
解决步骤
- 定位文件
src/mcp/server/mcpserver/utilities/func_metadata.py,找到_create_model_from_typeddict函数。 - 将导入语句中的
get_type_hints从typing改为typing_extensions(该库已用于导入is_typeddict)。 - (可选)在
tests/server/mcpserver/test_func_metadata.py中添加包含NotRequired字段的测试用例,验证修复效果。 - 在 Python 3.10 环境中运行复现脚本,确认工具能够正常注册。
验证方法
在 Python 3.10 环境下运行 Issue 中的复现脚本,确认不再抛出 PydanticForbiddenQualifier 异常,且 get_person 工具能够成功注册。同时可在 Python 3.13 上运行同一脚本,确保行为一致。
参考来源
modelcontextprotocol/python-sdk #3227
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[BUG]: Backend helper process crashes during agent sessions; ~830 MB leaked per agent exchange](https://www.chat-gpts.plus/wp-content/uploads/2026/08/6145-883c9b4e-768x403.jpg)
![[Question]: Rewrite component in agent](https://www.chat-gpts.plus/wp-content/uploads/2026/08/9143-c33f455d-768x403.jpg)
![[Question]: Is there a way to configure how particular extension should be parsed?](https://www.chat-gpts.plus/wp-content/uploads/2026/08/7984-5b787e60-768x403.jpg)