MCP OAuth completes but token is not honored — server stays in 'Needs authentication'
Summary
Adding a remote HTTP MCP server that uses OAuth 2.1 (authorization_code + PKCE, pre-registered client_id/client_secret) completes the browser OAuth dance successfully, but the resulting token is not used or persisted — /mcp continues to show the server as "Needs authentication" indefinitely. Tools never become available.
Affects multiple OAuth-protected MCP servers hosted by one corporate vendor (three distinct environments — dev, staging, prod-region). Does not affect other OAuth-protected MCP servers (Figma, Atlassian, Google Drive) on the same install, suggesting the issue is specific to some combination of that provider's OAuth metadata, scope handling, or callback timing.
Reproduction
claude mcp add --transport http --client-id <id> --client-secret --callback-port 8080 corp-mcp https://<corporate-mcp-host>/mcp(paste secret at prompt)/mcp→ click Authenticate, or invoke the auto-generatedmcp__corp-mcp__authenticatetool- Browser opens to authorization_endpoint, sign-in succeeds, browser redirects to
http://localhost:8080/callback?code=...&state=... - Claude Code reports "authentication successful"
/mcpandclaude mcp liststill show server as "! Needs authentication"- Re-attempting OAuth produces the same outcome on loop
Evidence the server side is healthy
The auth and MCP pipeline both work when bypassing Claude Code:
- Token exchange via curl with the same client_id/secret/PKCE verifier returns a valid Bearer token (HTTP 200,
expires_in: 14400, correct audience/permission claims). - That token authenticates a manual
POST /mcp—initializereturns proper server capabilities;tools/listreturns the full tool inventory with schemas. - So the OAuth provider and the MCP server are both functioning correctly in isolation; only Claude Code's bridging between them is failing.
Pattern
In the same Claude Code session, claude mcp list shows:
- ✓ Connected: Figma (mcp.figma.com), Atlassian (mcp.atlassian.com), Google Drive (drivemcp.googleapis.com)
- ! Needs authentication (stuck): three corporate MCP servers from the same vendor, across three environments
OAuth providers that work and the ones that don't both implement OAuth 2.1 with authorization_code + PKCE. The differentiator may be the OAuth discovery metadata shape, scope handling, or callback timing.
Environment
- Claude Code version: 2.1.143
- OS: macOS 26.4.1
- Transport: HTTP (streamable)
- Grant: authorization_code + PKCE (S256), pre-registered client
Workaround
None known via Claude Code's UI. The token can be obtained manually via curl and used directly against the MCP server, but Claude Code does not expose any documented way to inject a pre-obtained Bearer token for a configured MCP server.
Possibly related
A prior Claude Code OAuth callback listener (process named 2.1.143, same as the running CLI version) was found holding port 8080 even though no OAuth flow was active. Killing that stale process was required before a new flow could bind. This may be why "auth successful" + repeated retries keep producing the same "Needs authentication" state — each new attempt may be racing against or talking to a stale prior listener.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗