Skip to content

fix: skip eager token refresh when OAuth metadata is unavailable (#3240) - #3246

Open
zsxh1990 wants to merge 2 commits into
modelcontextprotocol:mainfrom
zsxh1990:fix/oauth-refresh-metadata-discovery
Open

fix: skip eager token refresh when OAuth metadata is unavailable (#3240)#3246
zsxh1990 wants to merge 2 commits into
modelcontextprotocol:mainfrom
zsxh1990:fix/oauth-refresh-metadata-discovery

Conversation

@zsxh1990

@zsxh1990 zsxh1990 commented Aug 4, 2026

Copy link
Copy Markdown

Problem

When the authorization server lives under a non-root path (e.g. https://host/oauth2/api/v1/token), the eager token refresh at the top of async_auth_flow hits the wrong endpoint.

Root cause: _refresh_token falls back to urljoin(get_authorization_base_url(server_url), "/token") when oauth_metadata is None. get_authorization_base_url strips the path, so a server at /oauth2/api/v1/token gets https://host/token instead.

This happens because the eager refresh runs before any PRM/ASM metadata discovery — so oauth_metadata is always None on a restart with cached-but-expired tokens.

Fix

Add and self.context.oauth_metadata is not None to the eager refresh guard. When metadata is missing:

  1. Skip the eager refresh (we don't know the real token endpoint)
  2. Let the request proceed with the stale token
  3. Receive 401 → run full PRM/ASM discovery → learn the correct token_endpoint
  4. Refresh or re-authorize with the right endpoint

This is correct because:

  • With metadata: eager refresh works as before (we know the endpoint)
  • Without metadata + token valid: no refresh needed, request succeeds
  • Without metadata + token expired: skip → 401 → discovery → correct endpoint

Fixes #3240

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Re-trigger cubic

When the auth server lives under a non-root path (e.g. /oauth2/api/v1/token),
the eager refresh at the top of async_auth_flow used the fallback
urljoin(get_authorization_base_url(server_url), '/token') which strips the
path, hitting the wrong endpoint.

Fix: only attempt the eager refresh when oauth_metadata is already populated
(i.e. we know the real token_endpoint). Without metadata, let the request
proceed with the stale token, receive a 401, and run full PRM/ASM discovery
before retrying — which resolves the correct token endpoint.

Includes regression test: test_auth_flow_skips_eager_refresh_when_metadata_missing

Fixes modelcontextprotocol#3240
@zsxh1990
zsxh1990 force-pushed the fix/oauth-refresh-metadata-discovery branch from c80b05e to a9d322e Compare August 4, 2026 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

1 participant