Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
9.0 kB · 234 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235import { isEnvTruthy } from 'src/utils/envUtils.js'
// Default to prod config, override with test/staging if enabledtype OauthConfigType = 'prod' | 'staging' | 'local'
function getOauthConfigType(): OauthConfigType { if (process.env.USER_TYPE === 'ant') { if (isEnvTruthy(process.env.USE_LOCAL_OAUTH)) { return 'local' } if (isEnvTruthy(process.env.USE_STAGING_OAUTH)) { return 'staging' } } return 'prod'}
export function fileSuffixForOauthConfig(): string { if (process.env.CLAUDE_CODE_CUSTOM_OAUTH_URL) { return '-custom-oauth' } switch (getOauthConfigType()) { case 'local': return '-local-oauth' case 'staging': return '-staging-oauth' case 'prod': // No suffix for production config return '' }}
export const CLAUDE_AI_INFERENCE_SCOPE = 'user:inference' as constexport const CLAUDE_AI_PROFILE_SCOPE = 'user:profile' as constconst CONSOLE_SCOPE = 'org:create_api_key' as constexport const OAUTH_BETA_HEADER = 'oauth-2025-04-20' as const
// Console OAuth scopes - for API key creation via Consoleexport const CONSOLE_OAUTH_SCOPES = [ CONSOLE_SCOPE, CLAUDE_AI_PROFILE_SCOPE,] as const
// Claude.ai OAuth scopes - for Claude.ai subscribers (Pro/Max/Team/Enterprise)export const CLAUDE_AI_OAUTH_SCOPES = [ CLAUDE_AI_PROFILE_SCOPE, CLAUDE_AI_INFERENCE_SCOPE, 'user:sessions:claude_code', 'user:mcp_servers', 'user:file_upload',] as const
// All OAuth scopes - union of all scopes used in Claude CLI// When logging in, request all scopes in order to handle both Console -> Claude.ai redirect// Ensure that `OAuthConsentPage` in apps repo is kept in sync with this list.export const ALL_OAUTH_SCOPES = Array.from( new Set([...CONSOLE_OAUTH_SCOPES, ...CLAUDE_AI_OAUTH_SCOPES]),)
type OauthConfig = { BASE_API_URL: string CONSOLE_AUTHORIZE_URL: string CLAUDE_AI_AUTHORIZE_URL: string /** * The claude.ai web origin. Separate from CLAUDE_AI_AUTHORIZE_URL because * that now routes through claude.com/cai/* for attribution — deriving * .origin from it would give claude.com, breaking links to /code, * /settings/connectors, and other claude.ai web pages. */ CLAUDE_AI_ORIGIN: string TOKEN_URL: string API_KEY_URL: string ROLES_URL: string CONSOLE_SUCCESS_URL: string CLAUDEAI_SUCCESS_URL: string MANUAL_REDIRECT_URL: string CLIENT_ID: string OAUTH_FILE_SUFFIX: string MCP_PROXY_URL: string MCP_PROXY_PATH: string}
// Production OAuth configuration - Used in normal operationconst PROD_OAUTH_CONFIG = { BASE_API_URL: 'https://api.anthropic.com', CONSOLE_AUTHORIZE_URL: 'https://platform.claude.com/oauth/authorize', // Bounces through claude.com/cai/* so CLI sign-ins connect to claude.com // visits for attribution. 307s to claude.ai/oauth/authorize in two hops. CLAUDE_AI_AUTHORIZE_URL: 'https://claude.com/cai/oauth/authorize', CLAUDE_AI_ORIGIN: 'https://claude.ai', TOKEN_URL: 'https://platform.claude.com/v1/oauth/token', API_KEY_URL: 'https://api.anthropic.com/api/oauth/claude_cli/create_api_key', ROLES_URL: 'https://api.anthropic.com/api/oauth/claude_cli/roles', CONSOLE_SUCCESS_URL: 'https://platform.claude.com/buy_credits?returnUrl=/oauth/code/success%3Fapp%3Dclaude-code', CLAUDEAI_SUCCESS_URL: 'https://platform.claude.com/oauth/code/success?app=claude-code', MANUAL_REDIRECT_URL: 'https://platform.claude.com/oauth/code/callback', CLIENT_ID: '9d1c250a-e61b-44d9-88ed-5944d1962f5e', // No suffix for production config OAUTH_FILE_SUFFIX: '', MCP_PROXY_URL: 'https://mcp-proxy.anthropic.com', MCP_PROXY_PATH: '/v1/mcp/{server_id}',} as const
/** * Client ID Metadata Document URL for MCP OAuth (CIMD / SEP-991). * When an MCP auth server advertises client_id_metadata_document_supported: true, * Claude Code uses this URL as its client_id instead of Dynamic Client Registration. * The URL must point to a JSON document hosted by Anthropic. * See: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-00 */export const MCP_CLIENT_METADATA_URL = 'https://claude.ai/oauth/claude-code-client-metadata'
// Staging OAuth configuration - only included in ant builds with staging flag// Uses literal check for dead code eliminationconst STAGING_OAUTH_CONFIG = process.env.USER_TYPE === 'ant' ? ({ BASE_API_URL: 'https://api-staging.anthropic.com', CONSOLE_AUTHORIZE_URL: 'https://platform.staging.ant.dev/oauth/authorize', CLAUDE_AI_AUTHORIZE_URL: 'https://claude-ai.staging.ant.dev/oauth/authorize', CLAUDE_AI_ORIGIN: 'https://claude-ai.staging.ant.dev', TOKEN_URL: 'https://platform.staging.ant.dev/v1/oauth/token', API_KEY_URL: 'https://api-staging.anthropic.com/api/oauth/claude_cli/create_api_key', ROLES_URL: 'https://api-staging.anthropic.com/api/oauth/claude_cli/roles', CONSOLE_SUCCESS_URL: 'https://platform.staging.ant.dev/buy_credits?returnUrl=/oauth/code/success%3Fapp%3Dclaude-code', CLAUDEAI_SUCCESS_URL: 'https://platform.staging.ant.dev/oauth/code/success?app=claude-code', MANUAL_REDIRECT_URL: 'https://platform.staging.ant.dev/oauth/code/callback', CLIENT_ID: '22422756-60c9-4084-8eb7-27705fd5cf9a', OAUTH_FILE_SUFFIX: '-staging-oauth', MCP_PROXY_URL: 'https://mcp-proxy-staging.anthropic.com', MCP_PROXY_PATH: '/v1/mcp/{server_id}', } as const) : undefined
// Three local dev servers: :8000 api-proxy (`api dev start -g ccr`),// :4000 claude-ai frontend, :3000 Console frontend. Env vars let// scripts/claude-localhost override if your layout differs.function getLocalOauthConfig(): OauthConfig { const api = process.env.CLAUDE_LOCAL_OAUTH_API_BASE?.replace(/\/$/, '') ?? 'http://localhost:8000' const apps = process.env.CLAUDE_LOCAL_OAUTH_APPS_BASE?.replace(/\/$/, '') ?? 'http://localhost:4000' const consoleBase = process.env.CLAUDE_LOCAL_OAUTH_CONSOLE_BASE?.replace(/\/$/, '') ?? 'http://localhost:3000' return { BASE_API_URL: api, CONSOLE_AUTHORIZE_URL: `${consoleBase}/oauth/authorize`, CLAUDE_AI_AUTHORIZE_URL: `${apps}/oauth/authorize`, CLAUDE_AI_ORIGIN: apps, TOKEN_URL: `${api}/v1/oauth/token`, API_KEY_URL: `${api}/api/oauth/claude_cli/create_api_key`, ROLES_URL: `${api}/api/oauth/claude_cli/roles`, CONSOLE_SUCCESS_URL: `${consoleBase}/buy_credits?returnUrl=/oauth/code/success%3Fapp%3Dclaude-code`, CLAUDEAI_SUCCESS_URL: `${consoleBase}/oauth/code/success?app=claude-code`, MANUAL_REDIRECT_URL: `${consoleBase}/oauth/code/callback`, CLIENT_ID: '22422756-60c9-4084-8eb7-27705fd5cf9a', OAUTH_FILE_SUFFIX: '-local-oauth', MCP_PROXY_URL: 'http://localhost:8205', MCP_PROXY_PATH: '/v1/toolbox/shttp/mcp/{server_id}', }}
// Allowed base URLs for CLAUDE_CODE_CUSTOM_OAUTH_URL override.// Only FedStart/PubSec deployments are permitted to prevent OAuth tokens// from being sent to arbitrary endpoints.const ALLOWED_OAUTH_BASE_URLS = [ 'https://beacon.claude-ai.staging.ant.dev', 'https://claude.fedstart.com', 'https://claude-staging.fedstart.com',]
// Default to prod config, override with test/staging if enabledexport function getOauthConfig(): OauthConfig { let config: OauthConfig = (() => { switch (getOauthConfigType()) { case 'local': return getLocalOauthConfig() case 'staging': return STAGING_OAUTH_CONFIG ?? PROD_OAUTH_CONFIG case 'prod': return PROD_OAUTH_CONFIG } })()
// Allow overriding all OAuth URLs to point to an approved FedStart deployment. // Only allowlisted base URLs are accepted to prevent credential leakage. const oauthBaseUrl = process.env.CLAUDE_CODE_CUSTOM_OAUTH_URL if (oauthBaseUrl) { const base = oauthBaseUrl.replace(/\/$/, '') if (!ALLOWED_OAUTH_BASE_URLS.includes(base)) { throw new Error( 'CLAUDE_CODE_CUSTOM_OAUTH_URL is not an approved endpoint.', ) } config = { ...config, BASE_API_URL: base, CONSOLE_AUTHORIZE_URL: `${base}/oauth/authorize`, CLAUDE_AI_AUTHORIZE_URL: `${base}/oauth/authorize`, CLAUDE_AI_ORIGIN: base, TOKEN_URL: `${base}/v1/oauth/token`, API_KEY_URL: `${base}/api/oauth/claude_cli/create_api_key`, ROLES_URL: `${base}/api/oauth/claude_cli/roles`, CONSOLE_SUCCESS_URL: `${base}/oauth/code/success?app=claude-code`, CLAUDEAI_SUCCESS_URL: `${base}/oauth/code/success?app=claude-code`, MANUAL_REDIRECT_URL: `${base}/oauth/code/callback`, OAUTH_FILE_SUFFIX: '-custom-oauth', } }
// Allow CLIENT_ID override via environment variable (e.g., for Xcode integration) const clientIdOverride = process.env.CLAUDE_CODE_OAUTH_CLIENT_ID if (clientIdOverride) { config = { ...config, CLIENT_ID: clientIdOverride, } }
return config}