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

[BUG] Claude Code MCP client ignores scopes_supported from OAuth protected resource metadata, preventing refresh token issuance

Open phernandez opened this issue 3 months ago • 5 comments

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Claude Code's MCP client fails to include OAuth scopes in authorization requests, even when the MCP server correctly provides scopes_supported in the OAuth protected resource metadata. This results in authorization requests without the offline_access scope, preventing refresh token issuance and causing authentication timeouts every 5 minutes.

What Should Happen?

Expected Behavior:

  1. Claude Code should read scopes_supported from the MCP server's /.well-known/oauth-protected-resource endpoint
  2. Include those scopes in OAuth authorization requests
  3. Receive refresh tokens when offline_access scope is supported
  4. Automatically refresh tokens to maintain persistent authentication

Error Messages/Logs

Debug Logs:
  [DEBUG] MCP server "basic-memory": Fetched OAuth metadata with scope: NONE
  [DEBUG] MCP server "basic-memory": Scopes in URL: NOT FOUND
  [DEBUG] MCP server "basic-memory": No scopes available from URL or metadata
  [DEBUG] MCP server "basic-memory": ERROR: No scopes stored to add to token request!
  [DEBUG] MCP server "basic-memory": Has refresh token: false
  [DEBUG] MCP server "basic-memory": Token expires in: 300

Steps to Reproduce

Actual Behavior:

  1. Claude Code fetches OAuth metadata but logs "Fetched OAuth metadata with scope: NONE"
  2. Authorization URLs are generated without any scope parameter
  3. OAuth authorization requests exclude the offline_access scope
  4. No refresh tokens are issued, causing re-authentication every 5 minutes

Reproduction Steps:

  1. Set up an MCP server with OAuth using WorkOS AuthKit (or similar provider)
  2. Configure the server to return scopes_supported: ["openid", "profile", "email", "offline_access"] in /.well-known/oauth-protected-resource
  3. Connect to the MCP server via Claude Code with debug logging enabled
  4. Observe the authorization URL in debug logs - it will be missing the scope parameter

Correct OAuth Protected Resource Metadata: { "resource": "https://mcp.basicmemory.com/mcp", "authorization_servers": ["https://eloquent-lotus-05.authkit.app/"], "scopes_supported": ["openid", "profile", "email", "offline_access"], "bearer_methods_supported": ["header"] }

Environment:

  • Claude Code version: 1.0.117
  • Platform: macOS (also affects other platforms)
  • MCP server: WorkOS AuthKit with Dynamic Client Registration

Impact:

  • High: Prevents extended MCP usage sessions
  • Users must manually re-authenticate every 5 minutes
  • Makes MCP servers with OAuth authentication practically unusable for development work

Comparison with Other Claude Clients:

  • Claude Desktop, Web, and Mobile handle OAuth refresh tokens correctly with the same MCP server
  • Only Claude Code exhibits this issue, suggesting a client-specific OAuth implementation problem

Technical Details: The issue appears to be in Claude Code's MCP OAuth client implementation where it's not properly parsing or using the scopes_supported field from the OAuth protected resource metadata when constructing authorization requests.

Workaround: None available. Users must manually re-authenticate every 5 minutes.

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

No response

Claude Code Version

Claude Code v1.0.117

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

PyCharm terminal

Additional Information

No response

phernandez avatar Sep 17 '25 04:09 phernandez