claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[BUG] OAuth Authentication Succeeds but MCP Reconnection Fails - Requires Restart

Open jhinrichsen opened this issue 2 months ago • 6 comments

Bug Report: OAuth Authentication Succeeds but MCP Reconnection Fails - Requires Claude Code Restart

Summary

After successful OAuth authentication with an MCP server using streamable-http transport, Claude Code displays "Authentication successful, but server reconnection failed. You may need to manually restart Claude Code for the changes to take effect." The OAuth tokens are correctly stored, but MCP tools remain unavailable until Claude Code is restarted.

Environment

  • Claude Code Version: 2.0.26
  • OS: Linux (Fedora 42, kernel 6.16.12)
  • MCP Server: Custom Quarkus-based MCP server
  • Transport: streamable-http
  • Auth Method: OAuth 2.0 with Dynamic Client Registration (RFC 7591)
  • OAuth Provider: Keycloak 24.0.3

Steps to Reproduce

  1. Configure an MCP server with OAuth using streamable-http transport:

    claude mcp add --transport http myserver http://localhost:8080/mcp
    
  2. Start MCP server with OAuth/OIDC enabled:

    • Server implements Dynamic Client Registration (DCR)
    • Server provides protected resource metadata at /.well-known/oauth-protected-resource
    • Token lifetime: 24 hours
    • Redirect URIs: localhost only (as per MCP spec)
  3. Run /mcp command in Claude Code

  4. Complete OAuth flow in browser (login with test user)

  5. Observe authentication completion in browser

Expected Behavior

Based on Claude Code MCP documentation:

"Authentication tokens are stored securely and refreshed automatically."

Expected: After OAuth completes, Claude Code should:

  1. Store the OAuth tokens ✅ (works)
  2. Automatically reconnect to the MCP server using stored tokens ❌ (fails)
  3. Load authenticated MCP tools immediately ❌ (fails)
  4. No restart required ❌ (restart IS required)

Actual Behavior

  1. OAuth authentication completes successfully in browser
  2. Tokens are correctly stored in ~/.claude/.credentials.json:
    {
      "mcpOAuth": {
        "myserver|<hash>": {
          "serverName": "myserver",
          "serverUrl": "http://localhost:8080/mcp",
          "clientId": "<dynamically-registered-client-id>",
          "accessToken": "[valid 24h JWT token]",
          "expiresAt": 1761406726618,
          "refreshToken": "[valid refresh token]",
          "scope": "email profile"
        }
      }
    }
    
  3. Claude Code displays error: "Authentication successful, but server reconnection failed. You may need to manually restart Claude Code for the changes to take effect."
  4. MCP tools are NOT available in the current session
  5. Running claude mcp list shows: ✗ Failed to connect
  6. After restarting Claude Code:
    • Connection succeeds automatically using stored tokens
    • All authenticated MCP tools are available
    • No re-authentication needed

Technical Details

Token Validity

The stored access token is valid and working:

  • Decoded JWT shows: exp: 1761406726 (24 hours from issuance)
  • Token contains correct user identity
  • Token includes proper scopes (email profile)
  • Token can successfully call authenticated API endpoints when tested directly with curl

Server Configuration

  • MCP server is running (verified with curl http://localhost:8080/mcp → HTTP 405 as expected)
  • Server properly implements:
    • Dynamic Client Registration endpoint
    • OAuth 2.0 protected resource metadata (RFC 9728)
    • PKCE flow support
    • Token validation

Transport Details

  • NOT using deprecated SSE (this is different from issue #9127)
  • Using modern streamable-http transport
  • Server is properly configured for streamable-http

Workaround

Restart Claude Code after OAuth authentication completes. The stored tokens are preserved and work correctly after restart.

Impact

  • Poor user experience: requires manual restart after every OAuth authentication
  • Contradicts documentation which states tokens work automatically
  • Makes iterative development/testing of OAuth-enabled MCP servers cumbersome
  • First-time users may think authentication failed when it actually succeeded

Related Issues

  • #9127 - Different issue (SSE-specific servers like Jira)
  • #956 - Auto-refresh OAuth (marked as fixed May 2025)
  • #1845 - Auth lost on config update
  • #7290 - HTTP/SSE transport ignores auth headers

This issue is distinct from #9127 as it affects streamable-http (modern protocol), not deprecated SSE.

Additional Notes

  • The OAuth flow itself works perfectly (DCR succeeds, tokens are valid)
  • The token storage works correctly
  • The issue is specifically in the reconnection logic after initial authentication
  • Subsequent Claude Code sessions work fine (tokens persist across restarts)
  • The problem only occurs during the initial authentication session

Proposed Fix

After successful OAuth token storage, Claude Code should:

  1. Use the newly stored tokens to establish an MCP connection
  2. Load the MCP tools into the current session
  3. Avoid requiring a restart for a session state that should be hot-reloadable

Questions for Maintainers

  1. Is the "reconnection failed" + restart requirement intentional behavior?
  2. If so, why does the documentation not mention this?
  3. Is there a technical limitation preventing hot-reconnection after OAuth completes?
  4. Should the error message be clearer about whether restart is always required vs. optional?

Would you like me to test any additional scenarios or provide more debug information?

jhinrichsen avatar Oct 24 '25 15:10 jhinrichsen