MCP Auth
- Entity ID:
ent-20260410-bb75b9bc6190 - Type:
service - Scope:
shared - Status:
active - Aliases: MCP authentication, MCP OAuth, ClaudeAuthProvider
Description
The MCP auth module (src/services/mcp/auth.ts, 88KB) handles OAuth 2.0 authentication for MCP server connections. It supports two flows: standard OAuth authorization code with PKCE, and XAA (Cross-App Access) for enterprise SSO. Tokens are stored in the platform keychain, and the system handles refresh, revocation, step-up auth, and vendor-specific error normalization.
How it works
Standard OAuth flow
performMCPOAuthFlow() orchestrates the browser-based PKCE flow:
- Discover auth server metadata via RFC 9728 + RFC 8414 fallback chain (
fetchAuthServerMetadata()) - Start a local HTTP server on
127.0.0.1for the callback - Open the user's browser to the authorization endpoint
- Wait for callback (5-minute timeout)
- Exchange authorization code for tokens
- Store tokens in platform keychain
Claude Code registers as a public client (token_endpoint_auth_method: 'none'). It supports CIMD (URL-based client_id) via a clientMetadataUrl getter pointing to MCP_CLIENT_METADATA_URL.
For remote/browser-based environments where localhost is unreachable, users can paste the callback URL manually.
XAA (Cross-App Access) flow
performMCPXaaAuth() enables enterprise SSO — one IdP login is reused across all XAA-configured MCP servers:
- Acquire
id_tokenfrom IdP (cached in keychain by issuer; if missing, runs OIDC authorization_code+PKCE) - RFC 8693 token exchange + RFC 7523 jwt-bearer grant (no browser needed)
- Store tokens in the same keychain slot as normal OAuth
ClaudeAuthProvider
ClaudeAuthProvider (line 1376) implements OAuthClientProvider from @modelcontextprotocol/sdk. It manages:
- Token storage and retrieval from secure keychain
- Proactive token refresh (5 minutes before expiry)
- Server key generation: {serverName}|{sha256(configJson).slice(0,16)}
Step-up authentication
wrapFetchWithStepUpDetection() handles 403 insufficient_scope responses. When detected, it marks step-up pending and forces PKCE re-authorization instead of useless token refresh (RFC 6749 section 6 forbids scope elevation via refresh).
Vendor normalization
normalizeOAuthErrorBody() fixes non-standard error codes from specific vendors. For example, Slack returns invalid_refresh_token, expired_refresh_token, and token_expired — all normalized to the standard invalid_grant.
Token revocation
revokeServerTokens() implements RFC 7009 — revokes refresh token first, then access token.
Constants
| Constant | Value | Purpose |
|---|---|---|
AUTH_REQUEST_TIMEOUT_MS |
30,000 (30s) | Per-request timeout |
MAX_LOCK_RETRIES |
5 | Concurrent auth lock attempts |
| OAuth callback timeout | 5 minutes | Browser auth flow timeout |
| Proactive refresh | 5 min before expiry | Token refresh trigger |
MCP_AUTH_CACHE_TTL_MS |
15 min | Skip re-probing servers that recently returned 401 |
Trade-offs
- Public client — no client secret, simpler setup, but relies entirely on PKCE for security. Standard for CLI tools but less secure than confidential clients.
- Platform keychain storage — secure but platform-specific. Requires different implementations per OS.
- Vendor normalization — fixes real interop issues but creates ongoing maintenance as new vendors ship non-standard responses.
- Step-up auth — correct per RFC but adds complexity. Without it, expired scope tokens would loop endlessly on refresh.
- XAA SSO — single login for all enterprise MCP servers, but adds an entire second auth flow to maintain.
Depends on
@modelcontextprotocol/sdk— OAuth client provider interface- Platform secure storage (keychain/credential manager)
- mcp-subsystem — parent system, provides server config
Key claims
- Supports two auth flows: standard OAuth PKCE and XAA enterprise SSO
- Tokens stored in platform keychain, not in config files
- Auth probe results cached for 15 minutes to avoid repeated 401 failures
- Normalizes vendor-specific OAuth errors to standard codes
Relations
part_ofmcp-subsystemused_bymcp-clientrelated_tooauth-service
Sources
src-20260409-a5fc157bc756, source code analysis of src/services/mcp/auth.ts