fix: route proxy OAuth flow through proxy fetch to bypass CORS#1638
Open
c-bik wants to merge 1 commit into
Open
fix: route proxy OAuth flow through proxy fetch to bypass CORS#1638c-bik wants to merge 1 commit into
c-bik wants to merge 1 commit into
Conversation
When using Via Proxy connection mode, the browser-side token exchange POST to the OAuth token endpoint is CORS-blocked by corporate MCP gateways. Fix by: 1. OAuthCallback: pass createProxyFetch(config) as fetchFn to auth() when connectionType is "proxy", so the token exchange goes through the Node.js proxy instead of the browser. 2. useConnection: accept optional serverUrlOverride in connect() and use it for InspectorOAuthClientProvider, avoiding a React state timing race where sseUrl hasn't updated yet when connectMcpServer() is called from onOAuthConnect. 3. useConnection: remove authProvider from proxy transport options for SSE and Streamable HTTP. The token is injected manually via headers; having authProvider on a proxy-URL transport causes the SDK to do OAuth discovery against localhost:6277 on 401, triggering a bogus redirect to /authorize on the proxy. 4. App.tsx: pass connectionType and config to OAuthCallback, and forward serverUrl to connectMcpServer after OAuth callback.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When using Via Proxy connection mode, the browser-side token exchange POST to the OAuth token endpoint is CORS-blocked by corporate MCP gateways (and any auth server that doesn't return
Access-Control-Allow-Originon POST responses). This causesTypeError: Failed to fetchafter the OAuth redirect completes, leaving the inspector unable to connect.This PR fixes three related failure modes in the proxy OAuth flow. It is related to #1342 (which fixes the same
OAuthCallbackCORS issue) but additionally addresses two further bugs that appear after the token exchange succeeds.Type of Change
Changes Made
OAuthCallback.tsx: acceptconfigandconnectionTypeprops; passcreateProxyFetch(config)asfetchFntoauth()whenconnectionType === "proxy", routing the token exchange through the Node.js proxy instead of the browser. This is the same pattern already used inuseConnection.handleAuthErrorandAuthDebugger.useConnection.ts- React state race fix:onOAuthConnectinApp.tsxcallssetSseUrl(serverUrl)immediately followed byconnectMcpServer(). BecausesetSseUrlis async,connectMcpServerstill sees the stalesseUrland looks up the OAuth token under the wrong sessionStorage key, finding nothing. Fixed by adding an optionalserverUrlOverrideparameter toconnect()and passing the URL directly fromonOAuthConnect.useConnection.ts- spurious redirect fix: In proxy mode,authProvider: serverAuthProviderwas passed toStreamableHTTPClientTransportandSSEClientTransport. When the transport receives a 401, the SDK callsauth()withserverUrlset to the proxy URL (localhost:6277/mcp), not the real MCP server. This causes OAuth discovery against the proxy, which returns 404, and the SDK then redirects the browser tolocalhost:6277/authorize. RemovedauthProviderfrom proxy transport options -- the Bearer token is already injected manually into headers before the connection is made.App.tsx: threadconnectionTypeandconfigdown toOAuthCallback; passserverUrlexplicitly toconnectMcpServerafter the OAuth callback.Related Issues
OAuthCallbackCORS fix; this PR adds fixes for two additional failure modes)Testing
Test Results and/or Instructions
Validated end-to-end against a real corporate MCP gateway backed by Azure AD, which enforces strict CORS on the token endpoint.
Without this fix:
/oauth/callbackTypeError: Failed to fetch(CORS-blocked)connectMcpServerreads the wrong sessionStorage keylocalhost:6277/authorizeWith this fix:
npm test-> 535/535 passnpm run test:e2e-> 24/24 passnpm run prettier-check-> passes on all changed filesChecklist
npm run prettier-fix)Breaking Changes
None.
OAuthCallbackgains two optional props; the single call site inApp.tsxis updated. Theconnect()signature change is additive (optional third parameter).Additional Context
The three bugs form a cascade: fix (1) alone and you hit (2); fix (1) and (2) and you hit (3). All three need to be addressed together for the proxy OAuth flow to work reliably against real-world auth servers with strict CORS policies.