快速结论:这个报错通常出现在 Windows 普通(非管理员、未开启开发者模式)用户首次运行 MCP Python SDK 测试套件时,具体失败于 test_safe_join_rejects_symlink_escape。它并不是你的代码或安全实现有问题,而是测试本身无条件创建符号链接,而 Windows 默认不允许普通用户创建符号链接,所以应优先排查测试环境权限,而非修改 src/mcp/shared/path_security.py。
适用环境:已在 Windows 11(10.0.26200)上复现;Python 3.14.7 与 Python 3.12.10 均有相关记录;mcp 2.0.1.dev23+56af447、mcp-types 2.0.1.dev23+56af447;pytest 8.4.2;使用 uv sync 与 uv run pytest。Issue 未确认 CUDA、显卡或 PyTorch 相关环境,不涉及这些项目。
最快修复方案:暂无确认的一步修复方案。Issue 中给出的处理方向是修改测试文件,让符号链接创建失败时跳过测试而非直接失败:将 tests/shared/test_path_security.py:145 的 symlink_to() 包进 try/except OSError,捕获后调用 pytest.skip()。该方案作者已在本地验证,套件从 5791 passed / 1 failed 变为 5790 passed / 0 failed,但截至 Issue 关闭尚无合并的 PR 证据。
注意事项:跳过该测试会让该机器上失去符号链接逃逸覆盖;Issue 评论建议另外增加一个无需提权的 Windows 目录 junction(mklink /J)测试来补足这一点,但该补充测试同样属于建议,并非已验证合并的方案。不要为了跑通测试而盲目以管理员身份运行全套件,也不要把这个失败误判为 safe_join 运行时实现存在缺陷。
问题场景
在 Windows 上以普通非提权用户身份克隆 modelcontextprotocol/python-sdk 并运行测试套件时触发。典型操作为:git clone 仓库、uv sync 安装依赖,然后执行 uv run pytest tests/shared/test_path_security.py,或运行完整套件。失败只出现在本地普通 Windows 机器,项目 CI 的 Windows 任务反而是绿的,因此该测试呈现“CI 永远通过、本地永远报错”的状态。Issue 报告者统计:其余 5791 个测试通过,仅此 1 个失败,16 个跳过。
报错原文
tests\shared\test_path_security.py:145: in test_safe_join_rejects_symlink_escape
(sandbox / "escape").symlink_to(outside)
E OSError: [WinError 1314] A required privilege is not held by the client
原因分析
最可能的原因是测试在 tests/shared/test_path_security.py:145 无条件创建符号链接,而 Windows 只允许提权进程,或开启了 Developer Mode 的普通用户创建符号链接,这两者都不是 Windows 机器的默认状态。异常在测试 setup 阶段、进入 safe_join() 之前就已抛出,因此失败点并非被测试的安全逻辑,而是测试的前置环境假设。
CI 之所以没有暴露该问题,是因为 .github/workflows/shared.yml 中的 Windows runner 明显具备创建符号链接的权限,所以该测试在 CI 上总能通过。Issue 评论进一步指出:WinError 1314 在 Python 中映射为普通 OSError,并不属于 FileExistsError、PermissionError 那类子类,因此按 .winerror 做窄类型捕获既不可移植也很脆弱。另一条评论补充了一个覆盖盲点:Windows 上还有无需提权的目录 junction(mklink /J),而 Path.is_symlink() 看不到它,所以若只是跳过符号链接测试,在这些机器上会完全没有逃逸覆盖;不过 safe_join 经由 Path.resolve() 已能正确处理 junction,这属于覆盖缺口而非运行时缺陷。
环境排查
- 确认操作系统是否为 Windows,以及当前进程是否提权、系统是否开启 Developer Mode。
- 确认是否使用
uv sync与uv run pytest运行测试。 - 确认触发文件是否为
tests/shared/test_path_security.py,失败行是否为第 145 行附近的symlink_to()调用。 - 确认 mcp 与 mcp-types 版本(Issue 中为 2.0.1.dev23+56af447,属 2.x 线)。
- 确认 pytest 版本(Issue 中为 8.4.2)。
- 确认 Python 版本(Issue 中出现 3.14.7 与 3.12.10)。
- Issue 未涉及 CUDA、PyTorch、显卡或额外自定义节点,无需排查这些项。
解决步骤
- 先单独运行触发文件,确认失败是权限导致的符号链接创建失败:
uv run pytest tests/shared/test_path_security.py,查看报错是否包含[WinError 1314]。 - 若确认是符号链接权限问题,可优先尝试的修复是修改测试文件本身:将
tests/shared/test_path_security.py中第 145 行的(sandbox / "escape").symlink_to(outside)用try/except OSError包裹,在except分支调用pytest.skip(f"symlink creation is not permitted here: {exc}")。 - 保留原有的
PathEscapeError断言,仅包裹symlink_to(),使符号链接可用的环境(包括现有 CI)仍完整执行逃逸断言。 - 按 Issue 评论意见,捕获范围应使用宽泛的
OSError,不要仅捕获特定权限错误,因为 WinError 1314 没有对应的窄类型。 - (可选,覆盖增强建议)可额外增加一个在 Windows 上使用
cmd /c mklink /J创建目录 junction 的兄弟测试,并用@pytest.mark.skipif(sys.platform != "win32", ...)限定平台;若mklink返回非零码则跳过。该方案在 Issue 中属于建议,未经合并验证。 - 无需修改
src/mcp/shared/path_security.py;Issue 双方均确认运行时实现不需要改动。
验证方法
在 Windows 普通非提权机器上重新运行 uv run pytest tests/shared/test_path_security.py:修复后 test_safe_join_rejects_symlink_escape 应显示为 skipped,且跳过原因是符号链接创建不被允许,而不是通过 pytest.mark.skip 之类方式被无条件屏蔽。运行完整套件时应看到 Issue 作者验证的结果(5790 passed / 0 failed),而不是原来的 5791 passed / 1 failed。若增加了 junction 补充测试,应确认该测试在 Windows 上实际执行并断言 safe_join 抛出 PathEscapeError,而非被错误跳过。
参考来源
modelcontextprotocol/python-sdk #3408
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[v2] Expose the SSE max_event_size setting in Streamable HTTP clients](https://www.chat-gpts.plus/wp-content/uploads/2026/10/3332-0ba364ef-768x403.jpg)

![[BUG] o1, o1-pro, and o3 reasoning models fallback to 8k default context window](https://www.chat-gpts.plus/wp-content/uploads/2026/10/7303-58ff742f-768x403.jpg)