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:
- Rewrite
redirect_uri to its own callback at /authorize time, stashing Claude's original redirect URI in the state parameter
- On receiving the callback from Azure AD, forward the code onwards to Claude at
https://claude.ai/api/mcp/auth_callback?code=...&state=...
- 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"
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
/authorizerequest correctly, but the/oauth/callbackhandler 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_callbackas its redirect URI via dynamic client registration. The proxy should:redirect_urito its own callback at/authorizetime, stashing Claude's original redirect URI in thestateparameterhttps://claude.ai/api/mcp/auth_callback?code=...&state=.../tokenrequest, rewritingredirect_uriback to the proxy's callbackInstead, 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_callbackwith:{"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/callbackentry: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"