Skip to content

Claude.ai connector MCP #1674

Description

@itspers

Claude.ai MCP Connection Issue

Describe the bug
Claude.ai fails to establish MCP connection after successful OAuth flow, while other MCP clients (Cursor, mcp-inspector, direct API calls) work perfectly with the same OAuth server. The issue appears to be that Claude.ai rejects the authentication after token exchange and doesn't send the access token in subsequent MCP requests.

Maybe somebody knows what the trick with claude.ai auth logic? Maybe it need special tokens.. i dont know was sitting whole day, tried all LLMs on this - no luck. Oauth just works and give tokens, but it just reject to use them.

To Reproduce
Steps to reproduce the behavior:

  1. Set up an MCP server with OAuth 2.0 Authorization Code Flow with PKCE
  2. Configure Claude.ai to connect to the MCP server
  3. Click "Connect" in Claude.ai - OAuth flow initiates correctly
  4. Complete authorization on consent page - redirects back to Claude.ai
  5. Claude.ai shows "Authentication was not successful" error
  6. Subsequent MCP requests from Claude.ai are sent without Authorization header

Expected behavior
After successful OAuth token exchange, Claude.ai should:

  1. Accept the authentication and show successful connection
  2. Send access token in Authorization header for MCP requests
  3. Successfully communicate with the MCP server

Logs
Complete flow showing the issue:

1. Initial MCP request (no token):

LOG [McpAuthGuard] MCP request: HEAD /api/mcp - no token - UA: python-httpx/0.27.2
WARN [McpAuthGuard] MCP missing token: HEAD /api/mcp

2. Discovery phase (Claude.ai fetches OAuth metadata):

DEBUG [OAuthMetadataController] Discovery alias hit: oauth-protected-resource/api/mcp - GET /api/.well-known/oauth-protected-resource/api/mcp
DEBUG [OAuthMetadataController] Discovery: oauth-protected-resource - GET /api/.well-known/oauth-protected-resource/api/mcp - python-httpx/0.27.2
DEBUG [OAuthMetadataController] Discovery alias hit: oauth-authorization-server/api - GET /api/.well-known/oauth-authorization-server/api
DEBUG [OAuthMetadataController] Discovery: oauth-authorization-server - GET /api/.well-known/oauth-authorization-server/api - python-httpx/0.27.2

3. OAuth client registration:

LOG [OAuthController] OAuth client registration request: Claude, grant_types=authorization_code,refresh_token, redirect_uris=1
LOG [OAuthService] Dynamic client registration: name=Claude, auth_method=client_secret_post
LOG [OAuthController] Client registration successful: dcr_71a87533-607e-42f6-b538-5b09cc894026, name=Claude, redirect_uris=1

4. OAuth authorization flow:

LOG [OAuthController] OAuth authorize: dcr_71a87533-607e-42f6-b538-5b09cc894026 -> https://claude.ai/api/mcp/auth_callback
LOG [OAuthController] OAuth authorize request: client_id=dcr_71a87533-607e-42f6-b538-5b09cc894026, response_type=code, redirect_uri=https://claude.ai/api/mcp/auth_callback, resource=https://unfortunately-shield-exactly-pounds.trycloudflare.com/api/mcp
LOG [OAuthController] Redirecting to consent page: dcr_71a87533-607e-42f6-b538-5b09cc894026, scopes=api:read,api:write, state=hH2gUyXBMpYjBXSc5V0YiQ7uj730vdZsVw-aU6buFlg, pkce=yes

5. User consent and authorization code generation:

LOG [OAuthController] OAuth consent: dcr_71a87533-607e-42f6-b538-5b09cc894026 -> approved
LOG [OAuthService] Authorization code generated and stored: dcr_71a87533-607e-42f6-b538-5b09cc894026, user=b0b2cbf2-bd97-48f5-843e-11d9bab33e3e, workspace=UI4KZE, codeLength=43
LOG [OAuthController] Success redirect URL: https://claude.ai/api/mcp/auth_callback?code=Lw9a8_wBdf7r6YzvZ4vwhsccHBhFwkDFATlf-NwD5Wo&state=hH2gUyXBMpYjBXSc5V0YiQ7uj730vdZsVw-aU6buFlg

6. Token exchange (SUCCESSFUL):

LOG [OAuthController] OAuth token: authorization_code from dcr_71a87533-607e-42f6-b538-5b09cc894026
DEBUG [OAuthService] Token exchange completed successfully: dcr_71a87533-607e-42f6-b538-5b09cc894026, user=b0b2cbf2-bd97-48f5-843e-11d9bab33e3e, workspace=UI4KZE, accessToken=689chars, refreshToken=43chars, scopes=api:read,api:write, jti=5695a26c-8725-49d5-b18a-8cce2de96458
DEBUG [OAuthController] Token exchange successful: dcr_71a87533-607e-42f6-b538-5b09cc894026, accessToken=689chars, refreshToken=43chars, expires=7200s, scope=api:read api:write

7. Final MCP requests (FAILED - no token sent):

LOG [McpAuthGuard] MCP request: POST /api/mcp - no token - UA: Claude-User
WARN [McpAuthGuard] MCP missing token: POST /api/mcp
LOG [McpAuthGuard] MCP request: GET /api/mcp - no token - UA: Claude-User
WARN [McpAuthGuard] MCP missing token: GET /api/mcp

Additional context

  • OAuth Server Implementation: Full OAuth 2.0 Authorization Code Flow with PKCE
  • Dynamic Client Registration: Supported and working
  • Token Format: JWT access tokens with standard claims (iss, aud, azp, scope, exp, iat, jti)
  • Discovery Endpoints: .well-known/oauth-authorization-server and .well-known/oauth-protected-resource
  • Other Clients: Cursor, mcp-inspector, and direct API calls work perfectly
  • Claude.ai Compatibility: Follows 3/26 and 6/18 auth specs as documented
  • Callback URL: https://claude.ai/api/mcp/auth_callback
  • Token Endpoint Auth: Supports client_secret_post as requested by Claude.ai

Working Comparison
When testing with mcp-inspector, the same OAuth server works perfectly:

  • OAuth flow completes successfully
  • Access token is sent in Authorization header
  • MCP communication works as expected

Browser Network Logs
Claude.ai shows step=end_error after OAuth callback, indicating post-callback validation failure on Claude's side.

Hypothesis
Claude.ai appears to perform additional token validation after the OAuth callback that our server passes, but Claude's validation fails, causing it to reject the authentication and not send the token in MCP requests.

Environment

  • OAuth Server: NestJS with JWT tokens
  • MCP Server: Standard MCP protocol implementation
  • Deployment: Cloudflare tunnel (also fails on live environment)
  • OAuth Spec: RFC 6749 + PKCE (RFC 7636)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingexternalNot directly related to the MCP protocol.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions