Skip to content

fix: route OAuth callback token exchange through proxy fetch#1342

Open
iherdt wants to merge 1 commit into
modelcontextprotocol:mainfrom
iherdt:fix/oauth-callback-uses-proxy-fetch
Open

fix: route OAuth callback token exchange through proxy fetch#1342
iherdt wants to merge 1 commit into
modelcontextprotocol:mainfrom
iherdt:fix/oauth-callback-uses-proxy-fetch

Conversation

@iherdt
Copy link
Copy Markdown

@iherdt iherdt commented May 22, 2026

Summary

The /oauth/callback handler calls auth() without passing a fetchFn, so the SDK falls back to global fetch for the metadata + token-endpoint requests. Auth servers that emit incomplete CORS headers on POST responses (e.g. /oauth2/token returning no Access-Control-Allow-Origin even though the preflight does) cause the token exchange to fail with TypeError: Failed to fetch — even when the initial registration phase succeeded via the existing proxy fetch path.

This matches the proxy-fetch pattern already used in useConnection.handleAuthError and AuthDebugger, so it's not a new mechanism — just an existing one applied to the callback that was missed.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)

Changes Made

  • client/src/components/OAuthCallback.tsx: accept config and connectionType props; build a createProxyFetch(config) when connectionType === "proxy"; pass that as fetchFn to auth().
  • client/src/App.tsx: thread config and connectionType through to the lazy-loaded OAuthCallback.

Net diff: +25 / -4.

Related Issues

None filed yet. The same root cause as the proxy-fetch work in useConnection (commit that added createProxyFetch), just for a different callsite.

Testing

  • Tested in UI mode
  • Tested with Streamable HTTP transport
  • Manual testing performed
  • Added/updated automated tests (no existing tests for OAuthCallback.tsx)

Reproducer

Real-world repro against WorkOS's demo MCP — its auth server signin.shop.workos.com returns no Access-Control-Allow-Origin on the /oauth2/token POST response (only on the preflight).

  1. Start inspector, transport = Streamable HTTP, URL = https://shop.workos.com/mcp, Connection Type = Via Proxy.
  2. Click Connect → 401 → OAuth flow kicks off.
  3. Without this fix: metadata discovery + registration succeed through /fetch, browser redirects to authorize, user signs in, lands at /oauth/callback?code=..., then TypeError: Failed to fetch toast appears and the token exchange dies. Browser console shows three CORS errors against signin.shop.workos.com .well-known/* and /oauth2/token endpoints.
  4. With this fix: the same three requests are made via localhost:6277/fetch instead, the token exchange completes, and the inspector connects to the MCP server.

Test Results

npm test -- --testPathPattern="OAuthCallback|App|proxyFetch" → 59/59 pass. Prettier check passes on changed files.

Checklist

  • Code follows the style guidelines (prettier --check passes)
  • Self-review completed
  • Code is commented where necessary

Breaking Changes

None. OAuthCallback gains two required props but it's only mounted from one place in App.tsx (line 1288), which is updated in this PR.

Additional Context

The original proxy-fetch work landed for the initial-connection OAuth flow but the callback was a separate code path. With both wired up, the inspector now works end-to-end against any auth server whose CORS is "good enough for browsers that don't preflight" but trips on POST responses — a class of misconfiguration we've seen in the wild beyond just WorkOS.

The /oauth/callback handler called `auth()` without a fetchFn, so the
SDK fell back to global fetch for the metadata + token-endpoint
requests. Auth servers that emit incomplete CORS headers (e.g.
`/oauth2/token` missing Access-Control-Allow-Origin on the response)
caused the token exchange to fail with `TypeError: Failed to fetch`,
even when initial registration succeeded via the proxy.

Wire config + connectionType into OAuthCallback and build a
createProxyFetch when connectionType === "proxy", matching the
existing pattern in useConnection and AuthDebugger.

Reproducible against the WorkOS shop MCP at https://shop.workos.com/mcp
(signin.shop.workos.com auth server). With this fix the full OAuth
dance — metadata discovery, registration, authorize redirect, callback,
token exchange — completes end to end.
@iherdt iherdt force-pushed the fix/oauth-callback-uses-proxy-fetch branch from 8e2e820 to 6957754 Compare May 22, 2026 23:30
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.

1 participant