Skip to content

OAuth callback flow broken for Claude.ai — proxy does not forward auth code to client redirect_uri #365

Description

@michaelalinks

Problem

When deploying AKS MCP with OAuth behind a TLS-terminating ingress (Envoy Gateway) and connecting via Claude.ai, the OAuth flow fails after the user successfully authenticates with Azure AD.

Root cause: The AKS MCP OAuth proxy intercepts the /authorize request correctly, but the /oauth/callback handler attempts to complete the token exchange itself rather than forwarding the auth code back to the client's (Claude's) registered redirect URI.

Claude registers https://claude.ai/api/mcp/auth_callback as its redirect URI via dynamic client registration. The proxy should:

  1. Rewrite redirect_uri to its own callback at /authorize time, stashing Claude's original redirect URI in the state parameter
  2. On receiving the callback from Azure AD, forward the code onwards to Claude at https://claude.ai/api/mcp/auth_callback?code=...&state=...
  3. Proxy the /token request, rewriting redirect_uri back to the proxy's callback

Instead, the server attempts to complete the exchange itself, which means Claude never receives the auth code and fails with code: Field required.

Reference

This proxy pattern is documented and working here:
https://dhanushgcse.github.io/MCPAuthViaMicrosoftEntra/

Related PR: #364

Evidence

After completing Microsoft login, the browser lands at claude.ai/api/mcp/auth_callback with:

{"type":"error","error":{"type":"invalid_request_error","message":"code: Field required"}}

Pod logs show the flow stops after redirecting to Azure AD with no subsequent /oauth/callback entry:

time="14:50:03" level=debug msg="Registering config prompts (query_aks_cluster_metadata_from_kubeconfig)" time="14:50:03" level=debug msg="Registering health prompts (check_cluster_health)" time="14:50:03" level=info msg="AKS MCP service initialization completed successfully" time="14:50:03" level=info msg="AKS MCP version: " time="14:50:03" level=info msg="Registering OAuth endpoints..." time="14:50:03" level=info msg="Streamable HTTP server listening on 0.0.0.0:8000" time="14:50:03" level=info msg="MCP endpoint available at: http://0.0.0.0:8000/mcp" time="14:50:03" level=info msg="Send POST requests to /mcp to initialize session and obtain Mcp-Session-Id" time="14:50:03" level=info msg="OAuth authentication enabled - Bearer token required for MCP endpoint" time="14:50:03" level=info msg="OAuth metadata available at: http://0.0.0.0:8000/.well-known/oauth-protected-resource" time="14:52:18" level=debug msg="OAuth DEBUG - Missing authorization header for POST /mcp" time="14:52:18" level=error msg="Authentication FAILED - handling error" time="14:52:18" level=error msg="MIDDLEWARE ERROR: Error response sent" time="14:52:30" level=debug msg="OAuth DEBUG: Received request for protected resource metadata: GET /.well-known/oauth-protected-resource" time="14:52:30" level=debug msg="OAuth DEBUG: Building protected resource metadata for URL: https://aks-mcp.<redacted>/mcp (transport: streamable-http)" time="14:52:30" level=debug msg="OAuth DEBUG: Successfully generated protected resource metadata with 1 authorization servers" time="14:52:30" level=debug msg="OAuth DEBUG: Received request for authorization server metadata: GET /.well-known/oauth-authorization-server" time="14:52:30" level=debug msg="OAuth DEBUG: Fetching Azure AD metadata from: https://login.microsoftonline.com/<redacted>/v2.0/.well-known/openid-configuration" time="14:52:30" level=debug msg="OAuth DEBUG: Successfully parsed Azure AD metadata, original grant_types_supported: []" time="14:52:30" level=debug msg="OAuth DEBUG: Setting default grant_types_supported (was empty/nil)" time="14:52:30" level=debug msg="OAuth DEBUG: Enforcing S256 code challenge method support (MCP requirement)" time="14:52:30" level=debug msg="OAuth DEBUG: Final metadata prepared - grant_types_supported: [authorization_code refresh_token], response_types_supported: [code id_token code id_token id_token token], code_challenge_methods_supported: [S256]" time="14:52:30" level=debug msg="OAuth DEBUG: Received client registration request: POST /oauth/register" time="14:52:30" level=debug msg="OAuth DEBUG: Client registration request parsed - client_name: Claude, redirect_uris: [https://claude.ai/api/mcp/auth_callback]" time="14:52:31" level=debug msg="OAuth DEBUG: Received authorization proxy request: GET /oauth2/v2.0/authorize" time="14:52:31" level=debug msg="OAuth DEBUG: Removing resource parameter for Azure AD compatibility: https://aks-mcp.<redacted>/mcp" time="14:52:31" level=debug msg="OAuth DEBUG: Setting final scope for Azure AD: api://<redacted>/.default" time="14:52:31" level=debug msg="OAuth DEBUG: Redirecting to Azure AD authorization endpoint: https://login.microsoftonline.com/<redacted>/oauth2/v2.0/authorize"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions