@@ -363,6 +363,46 @@ pub fn read_codex_api_key_from_env() -> Option<String> {
363363 . filter ( |value| !value. is_empty ( ) )
364364}
365365
366+ pub const ANTHROPIC_API_KEY_ENV_VAR : & str = "ANTHROPIC_API_KEY" ;
367+
368+ /// Read the Anthropic API key from the environment variable `ANTHROPIC_API_KEY`.
369+ pub fn read_anthropic_api_key_from_env ( ) -> Option < String > {
370+ env:: var ( ANTHROPIC_API_KEY_ENV_VAR )
371+ . ok ( )
372+ . map ( |value| value. trim ( ) . to_string ( ) )
373+ . filter ( |value| !value. is_empty ( ) )
374+ }
375+
376+ /// Read the Claude Code OAuth access token from `~/.claude/.credentials.json`.
377+ ///
378+ /// Claude Code stores OAuth credentials (from `claude.ai` login) in this file.
379+ /// The access token can be used as an `ANTHROPIC_API_KEY` bearer token for
380+ /// Anthropic API calls when a proper Anthropic provider is configured.
381+ pub fn read_claude_code_credentials ( ) -> Option < String > {
382+ let home = env:: var ( "HOME" ) . ok ( ) . map ( PathBuf :: from) ?;
383+ let creds_path = home. join ( ".claude" ) . join ( ".credentials.json" ) ;
384+ let content = std:: fs:: read_to_string ( creds_path) . ok ( ) ?;
385+ let json: serde_json:: Value = serde_json:: from_str ( & content) . ok ( ) ?;
386+ json[ "claudeAiOauth" ] [ "accessToken" ]
387+ . as_str ( )
388+ . map ( String :: from)
389+ . filter ( |s| !s. is_empty ( ) )
390+ }
391+
392+ /// If `ANTHROPIC_API_KEY` is not set in the environment, attempt to load the
393+ /// Claude Code OAuth token from `~/.claude/.credentials.json` and set it.
394+ ///
395+ /// Call this early in the process lifecycle so downstream provider lookups see it.
396+ pub fn bootstrap_anthropic_api_key_from_claude_credentials ( ) {
397+ if read_anthropic_api_key_from_env ( ) . is_some ( ) {
398+ return ;
399+ }
400+ if let Some ( token) = read_claude_code_credentials ( ) {
401+ // SAFETY: single-threaded startup context.
402+ unsafe { env:: set_var ( ANTHROPIC_API_KEY_ENV_VAR , token) } ;
403+ }
404+ }
405+
366406/// Delete the auth.json file inside `codex_home` if it exists. Returns `Ok(true)`
367407/// if a file was removed, `Ok(false)` if no auth file was present.
368408pub fn logout (
0 commit comments