modelcontextprotocol / modelcontextprotocol/python-sdk
OAuth token refresh hits the wrong endpoint when the auth server lives under a path
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 24.3k
- 派生
- 4k
- 平均合并
- 1 天 1 小时
- 30 天内合并 PR
- 31
描述
Ran into this with a hosted MCP server whose authorization server isn't at the origin root — token endpoint is https://host/oauth2/api/v1/token, not https://host/token.
If a client starts up with a cached-but-expired access token (+ refresh token) and hasn't done discovery yet, async_auth_flow refreshes at the very top — before any 401/metadata discovery. So oauth_metadata is None and _refresh_token uses the fallback urljoin(get_authorization_base_url(server_url), "/token"), i.e. just {scheme}://{netloc}/token. That 404s, _handle_refresh_response clears the tokens, and the flow drops to full interactive auth — which a headless/gateway client can't do. So the server silently disconnects every time the access token expires (mine are 5 min, so… constantly).
Same path-stripping fallback is in _get_token_endpoint, _perform_authorization_code_grant (/authorize) and DCR (/register) — refresh is just the one that bites silently.
Repro (roughly):
- MCP server whose AS metadata puts
token_endpointunder a path, not{origin}/token - log in normally so tokens get cached
- let the access token expire (or clear the expiry), reconnect with a fresh provider
- watch the refresh POST go to
https://host/token→ 404 → "Token refresh failed" → tokens cleared → it tries to open a browser
Fix looks like: discover metadata before the eager refresh (or stop dropping the issuer path in the fallback). Happy to PR — have a branch that pulls the PRM/ASM discovery out of the 401 branch and runs it before the refresh.
(used some AI help digging into this)
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
首先跟踪 async_auth_flow 及其到 _refresh_token 的 eager refresh 路径,然后比较 _get_token_endpoint、_perform_authorization_code_grant 和 DCR 中的回退行为。针对元数据端点包含路径的 authorization server,重现缓存的过期 token 场景。完成标准是 refresh 使用发现的 token endpoint,并且不会清除有效 token 或回退到交互式身份验证。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- api, authentication
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 冷清
- 描述清晰度
- 描述清楚
- 新手友好度
- 48/100