modelcontextprotocol / modelcontextprotocol/python-sdk

OAuth token refresh hits the wrong endpoint when the auth server lives under a path

未關閉
#3,240 2 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

P1 v1 v2
主要語言
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_endpoint under 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)

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

首先追蹤 async_auth_flow 及其到 _refresh_token 的 eager refresh 路徑,然後比較 _get_token_endpoint、_perform_authorization_code_grant 和 DCR 中的 fallback 行為。針對中繼資料端點包含路徑的 authorization server,重現快取中已過期 token 的情境。完成條件是 refresh 使用已探索到的 token endpoint,且不會清除有效 token 或回退到互動式驗證。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
api, authentication
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
冷清
描述清晰度
描述清楚
新手友好度
48/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。