fix: detect 401 errors from StreamableHTTP transport for OAuth flow #966
+24
−5
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
Fix for Streamable HTTP WWW-Authenticate challenge not triggering OAuth flow in version 0.17.5.
When an OAuth-protected MCP server returns a 401
WWW-Authenticatechallenge via Streamable HTTP transport, the proxy was returning 500 instead of 401 to the client. This prevented the client-side OAuth discovery and redirect flow from triggering.Type of Change
Changes Made
The server-side error handling only checked for
SseErrorinstances when detecting 401 responses from MCP servers. However,StreamableHTTPClientTransportthrows a different error type (genericErrorwith "HTTP 401" in the message) when there's noauthProviderconfigured on the server-side transport.Changes:
StreamableHTTPErrorfrom the SDKis401Error()helper function that detects 401 errors from:SseErrorwith code 401 (existing behavior)StreamableHTTPErrorwith code 401 (new)Errorwith "HTTP 401" or "(401)" in message (fallback)/mcp,/stdio, and/sseroutes to use the new helperRelated Issues
Fixes #960
Testing
Test Results and/or Instructions
How to test this fix:
WWW-Authenticateheader on 401Note: The server package currently lacks test infrastructure. The
is401Error()helper is a simple pure function. Automated tests could be added when server-side test infrastructure is established.Checklist
npm run prettier-fix)Breaking Changes
None
Additional Context
Root Cause Analysis:
The SDK's
StreamableHTTPClientTransport.send()method handles 401 responses differently depending on whether anauthProvideris configured:authProvider: Attempts OAuth flow internallyauthProvider: ThrowsError('Error POSTing to endpoint (HTTP 401): ...')The Inspector's proxy server creates transports without an
authProvider(the OAuth flow is handled client-side), so it receives the generic Error. The existing error handler only checked forSseError, causing the 401 to be returned as a 500.🤖 Generated with Claude Code