Repository navigation
Description
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:
- Set up an MCP server with OAuth 2.0 Authorization Code Flow with PKCE
- Configure Claude.ai to connect to the MCP server
- Click "Connect" in Claude.ai - OAuth flow initiates correctly
- Complete authorization on consent page - redirects back to Claude.ai
- Claude.ai shows "Authentication was not successful" error
- Subsequent MCP requests from Claude.ai are sent without Authorization header
Expected behavior
After successful OAuth token exchange, Claude.ai should:
- Accept the authentication and show successful connection
- Send access token in Authorization header for MCP requests
- 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-serverand.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_postas 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)
Activity
jhrozek commentedon Oct 28, 2025
This report sounds like something that should be reported to Anthropic, not to this repo
domdomegg commentedon Nov 26, 2025
Thanks for the report, this is out of scope for this repo - contact Anthropic support for issues with Claude.ai.
saki82 commentedon Feb 14, 2026
Stumbled over this post while researching the same problem. i have the solution:
Cloudflares built-in security rule "Cloudflare Bot Management rules for all plans" is blocking the request.
How to verify:
Go to Cloudflare Dashboard → Security → Analytics → Events and look for Block actions from "Managed rules" → "Cloudflare Bot Management rules for all plans" → "Manage AI bots" on requests to your n8n domain.
The fix:
Create a WAF Custom Rule to skip bot detection for Claude MCP traffic:
BeOnTech01 commentedon Mar 17, 2026
Realmente resolveu o meu problema
Muito bom, resolveu o meu problema