
The resource URL path is ignored when building the protected resource metadata URL
快速结论:该报错发生在使用 MCP Python SDK 构建 OAuth 受保护资源元数据 URL 时,SDK 默认只使用固定根路径 /.well-known/oauth-protected-resource,忽略了资源 URL 中的路径部分。优先排查你的 resource_server_url 配置是否正确,并确保 SDK 版本 ≥ v1.17.0(服务端)或 ≥ v1.21.0(客户端)。
问题场景
用户在使用 MCP Python SDK(Model Context Protocol Python SDK)搭建或连接 OAuth 保护的 MCP 服务器时,发现服务器端构建的受保护资源元数据 URL 没有包含资源路径。例如,如果实际资源 URL 是 https://resource.example.com/resource1,服务器本应返回 https://resource.example.com/.well-known/oauth-protected-resource/resource1,但当前实现只返回 https://resource.example.com/.well-known/oauth-protected-resource。
报错原文
The resource URL path is ignored when building the protected resource metadata URL
Current behavior:
If the resource URL is `https://resource.example.com/resource1`, the protected resource metadata URL to be `https://resource.example.com/.well-known/oauth-protected-resource`
Expected behavior (per RFC 9728 §3.1):
If the resource URL is `https://resource.example.com/resource1`, the protected resource metadata URL to be `https://resource.example.com/.well-known/oauth-protected-resource/resource1`
原因分析
这是 MCP Python SDK 在 OAuth 元数据构建上的设计缺陷,未遵循 RFC 9728 Section 3.1 规范。具体来说:
- 服务器端硬编码了固定路由
/.well-known/oauth-protected-resource,没有将资源 URL 的路径部分(如/resource1)插入到 well-known URI 之后。 - RFC 9728 要求元数据 URL 应通过将 well-known 字符串插入资源标识符的路径组件之间构建。例如
https://resource.example.com/resource1应变为/.well-known/oauth-protected-resource/resource1。 - 这种硬编码方式在多租户场景下会导致多个资源共用一个元数据端点,无法区分。
- 此外,服务器也没有正确利用
WWW-Authenticate头中的resource_metadata字段来提供准确的元数据 URL。
可能原因还包括:resource_server_url 配置未正确设置,或 SDK 版本过旧没有包含修复。
环境排查
- MCP Python SDK 版本:确认是否为最新版本(Issue 关闭时最新 v1.27.2)。修复此问题的版本为 v1.17.0(服务端)和 v1.21.0(客户端)。
- Python 版本:无特殊要求,但建议 ≥ 3.9。
- OAuth 配置:检查
settings.auth.resource_server_url是否正确设置了资源服务器的基础 URL(包含完整路径)。 - RFC 9728 合规性:确认客户端是否支持路径发现流程(旧版客户端只尝试根 URL)。
解决步骤
- 升级 SDK(服务端)到 v1.17.0 或更高版本:该版本增加了
build_resource_metadata_url()函数,它会按照 RFC 9728 §3.1 在主机和资源路径之间插入/.well-known/oauth-protected-resource。元数据路由现在注册在这个基于路径的 URL 上,WWW-Authenticate头中的resource_metadata也会使用该 URL。 - 配置正确的
resource_server_url:在服务器端设置settings.auth.resource_server_url = "https://resource.example.com/resource1"。该 URL 会按原样用于构建元数据端点,SDK 不再猜测资源标识符。 - 升级 SDK(客户端)到 v1.21.0 或更高版本:客户端发现流程现在会优先尝试从
WWW-Authenticate头中的resource_metadata字段获取元数据 URL,然后尝试基于路径的 well-known URI,最后回退到根路径。 - 可选但推荐:升级到 v1.27.2(当前最新):包含所有前述修复,并且与 v2 (main) 的代码对齐。
- 如果仍遇到问题:检查 Issue #1264 中跟踪的边界情况——当
resource_server_url省略了传输路径时,可能导致元数据中的resource字段与严格客户端解析的结果不匹配。
验证方法
使用调试工具或自定义客户端确认元数据 URL 是否包含正确的路径。具体地:
- 启动配置了
resource_server_url=https://resource.example.com/resource1的 MCP 服务器。 - 对服务器发起 HTTP 请求(如 GET 元数据端点)。
- 检查返回的
WWW-AuthenticateHeader 中的resource_metadata字段,应包含https://resource.example.com/.well-known/oauth-protected-resource/resource1。 - 直接访问该元数据 URL,应能获取有效的 JSON 元数据响应。
- 如果使用客户端连接,确认客户端能够发现并成功完成 OAuth 流程。
参考来源
modelcontextprotocol/python-sdk #1052
RFC 9728 Section 3.1 – Well-Known URI for Protected Resource Metadata



