OAuth scope selection falls back to the authorization server's scopes_supported, which the spec does not allow
維護者通常 1 天內回覆
還沒有人認領這個 Issue。
評估
- 難度
- 2/5
- 預估耗時
- 1-3 小時
- 新手友好度
- 79/100
- Issue 類型
- 缺陷
- 描述清晰度
- 描述清楚
- 活躍度
- 活躍
- 技術堆疊
- python
研究方向
從 src/mcp/client/auth/utils.py 的 get_client_metadata_scopes 開始,沿著 scope 選擇分支追蹤,並對照 issue 中引用的規範行為。檢查或新增針對缺少 challenge scope 和 PRM scopes_supported 的測試;完成條件是這些情況在 PRM scopes 存在時選取它們,否則省略 scope,且不使用 authorization server scopes。
由索引模型根據 Issue 內容生成。
描述
Initial Checks
- I confirm that I'm using the latest version of MCP Python SDK
- I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this issue
Description
When the 401 carries no scope and the Protected Resource Metadata (PRM) has no scopes_supported, get_client_metadata_scopes (src/mcp/client/auth/utils.py) requests every scope the authorization server lists:
# MCP spec scope selection priority:
# 1. WWW-Authenticate header scope
# 2. PRM scopes_supported
# 3. AS scopes_supported (SDK fallback)
# 4. Omit scope parameter
...
elif authorization_server_metadata is not None and authorization_server_metadata.scopes_supported is not None:
selected_scope = " ".join(authorization_server_metadata.scopes_supported)
The spec has two steps, and the second one ends in omitting scope (2026-07-28, Authorization → Scope Selection Strategy):
- Use
scopeparameter from the initialWWW-Authenticateheader in the 401 response, if provided- If
scopeis not available, use all scopes defined inscopes_supportedfrom the Protected Resource Metadata document, omitting thescopeparameter ifscopes_supportedis undefined.
The same section says clients SHOULD request "only the scopes necessary for their intended operations."
An authorization server's scopes_supported describes the whole authorization server, not this resource. Often that's a shared IdP serving many APIs (openid, profile, email, org-admin and write scopes for unrelated services). Tier 3 therefore turns "the resource didn't say" into "ask for everything the IdP has". The results:
- an over-privileged token for an MCP server that needed none of it;
- a broad consent screen for the user;
- a login failure when the authorization server refuses to issue some of the listed scopes to a public or dynamically registered client (
invalid_scope), where omittingscopewould have succeeded with the authorization server's default.
Example Code
The selection function on its own (works on 1.26.0, 1.30.0 and 2.3.0):
from mcp.client.auth.utils import get_client_metadata_scopes
from mcp.shared.auth import OAuthMetadata, ProtectedResourceMetadata
prm = ProtectedResourceMetadata(
resource="https://mcp.example.com/mcp",
authorization_servers=["https://auth.example.com"],
) # no scopes_supported
asm = OAuthMetadata(
issuer="https://auth.example.com",
authorization_endpoint="https://auth.example.com/authorize",
token_endpoint="https://auth.example.com/token",
scopes_supported=["openid", "profile", "email", "admin:org", "repo:write"],
)
print(get_client_metadata_scopes(None, prm, asm))
# 'openid profile email admin:org repo:write' — expected: None (omit scope)
In the real flow, OAuthClientProvider.async_auth_flow assigns this result to client_metadata.scope on every 401. So a client can't avoid it by configuring a narrower scope: that is #2317, which has several production reports.
Expected behaviour
Follow the spec: (1) the challenge scope, (2) PRM scopes_supported, otherwise omit scope. If a fallback beyond the spec is wanted, make it something a client turns on, not the default.
Relation to existing issues
- #2317: a configured
client_metadata.scopeis overwritten. This issue is separate: even with no configured scope, the SDK should omitscoperather than take the authorization server's list. Fixing #2317 alone would leave clients that don't configure a scope on tier 3. - #3172 (closed): put the configured scope after tier 3. That doesn't help here, because the AS-wide list still wins whenever the authorization server advertises any scopes.
Python & MCP Python SDK
- MCP Python SDK: reproduced on 1.26.0, 1.30.0, 2.3.0. The same code is on
mainatd7845c0. - Python 3.12
- 主要語言
- Python
- 星號
- 24.7k
- 分支
- 4.1k
- 平均合併
- 18 小時 27 分鐘
- 30 天內合併 PR
- 15
環境準備
- 沒有 Dockerfile 或 Docker Compose 檔案
- 有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
modelcontextprotocol/python-sdk 的其他 Issue
-
bug v2
難度 2/5 1-3 小時 新手友好度 76/100
modelcontextprotocol/python-sdk#3811 ·
維護者通常 1 天內回覆
-
bug v2
難度 2/5 1-3 小時 新手友好度 79/100
modelcontextprotocol/python-sdk#3810 ·
維護者通常 1 天內回覆
-
[Bug]: Inconsistent structured output wrapping and opt-out for typing.Dict and typing sequence generics in func_metadata可能重新可做 關聯的 PR 已關閉且未合併。 未關閉bug v1 v2
難度 2/5 1-3 小時 新手友好度 82/100
modelcontextprotocol/python-sdk#3771 · 3 則留言 ·
維護者通常 1 天內回覆
-
bug v2
難度 2/5 1-3 小時 新手友好度 68/100
modelcontextprotocol/python-sdk#3769 · 2 則留言 ·
維護者通常 1 天內回覆
-
2026 Streamable HTTP rejects whitespace-padded Mcp-Name values可能重新可做 關聯的 PR 已關閉且未合併。 未關閉bug spec-2026-07-28 v2
難度 2/5 1-3 小時 新手友好度 68/100
modelcontextprotocol/python-sdk#3763 · 4 則留言 ·
維護者通常 1 天內回覆
查看 modelcontextprotocol/python-sdk 的全部 Issue
相似的 Issue
-
bug ready-for-dev
難度 1/5 1-3 小時 新手友好度 92/100
OpenHands/extensions#897 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 72/100
tensorflow/datasets#11253 ·
維護者通常 1 天內回覆
-
fix(core): a config section with all keys commented out crashes startup可能已有人在做 @Aryanbhargava18 今天認領。 未關閉
難度 2/5 1-3 小時 新手友好度 75/100
kubeflow/mcp-server#512 ·
維護者通常 1 天內回覆
-
Stop trusting the compromised eMudhra CA certificates可能已有人在做 @anth-volk 今天認領。 未關閉
難度 2/5 1-3 小時 新手友好度 82/100
PolicyEngine/uk-triple-lock#54 ·
維護者通常 1 天內回覆
-
DBFS append mode silently overwrites existing files可能已有人在做 @IlyaKhalafi 今天認領。 未關閉
難度 2/5 1-3 小時 新手友好度 77/100
fsspec/filesystem_spec#2429 ·
維護者通常 1 天內回覆