> ## Documentation Index
> Fetch the complete documentation index at: https://docs.open4rena.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment variables

> Environment variables that change how o4 behaves.

o4 reads the environment variables below. Most settings belong in the [configuration files](/configuration/overview); environment variables are useful for API keys, one-off runs, and scripts.

## General

<ParamField path="O4_TRUST_WORKSPACE" type="string">
  Set to `1` to treat the current workspace as [trusted](/safety/workspace-trust) for this process, without recording it. Project config, hooks, MCP servers, plugins and skills then load as if you had run `o4 trust`. Any other value is ignored. Meant for automation that has already vetted the repository.
</ParamField>

<ParamField path="O4_SUBAGENT_MODEL" type="string">
  A model reference, such as `anthropic:claude-opus-5`, that every [sub-agent](/guides/subagents) uses. It takes priority over the model the `agent` tool call or the sub-agent definition asks for. `inherit` uses the parent session's model, and so does a reference o4 can't resolve. When unset, a sub-agent uses the model the tool call asks for, then the one its definition names, then the parent's model.
</ParamField>

<ParamField path="O4_ACCESSIBILITY" type="string">
  Has no effect in o4 0.2.74. o4 reads it, and `ACCESSIBILITY_ENABLED`, but the saved **Screen reader** setting replaces the result when the interface starts. To turn on screen reader output, use the `--accessibility` flag or the **Screen reader** setting in `/config appearance`. See [Themes and display](/configuration/appearance).
</ParamField>

<ParamField path="O4_TUI_MODE" type="string">
  Set to `alternate` to run the TUI in the terminal's alternate screen, the way full-screen programs do. By default, o4 draws below your shell prompt and leaves the conversation in your terminal's scrollback.
</ParamField>

<ParamField path="O4_CLIPBOARD_OSC52" type="string">
  When o4 can't copy with a system clipboard command, it falls back to sending the text to your terminal with an OSC 52 escape sequence. Set this to `0`, `false`, `no` or `off` to turn that fallback off. On by default.
</ParamField>

<ParamField path="EDITOR" type="string">
  The editor o4 opens when you edit your prompt in an external editor (`Ctrl+G`), create or edit an agent definition, or edit an MCP config file. If it's unset, o4 uses `VISUAL`, then `vi`. o4 runs the value as a single program name or path, without a shell, so it can't include arguments: with `EDITOR="code --wait"`, `Ctrl+G` fails with "Failed to launch editor". Point it at a wrapper script if your editor needs flags.
</ParamField>

<ParamField path="VISUAL" type="string">
  Used as the editor when `EDITOR` isn't set.
</ParamField>

<ParamField path="COLORFGBG" type="string">
  Set by some terminals to their text and background color numbers, such as `15;0`. With the `auto` theme, when the terminal doesn't report its colors, o4 reads the background number: 8 or more means a light background. See [Themes and display](/configuration/appearance).
</ParamField>

<ParamField path="VSCODE_THEME" type="string">
  In the VS Code terminal, with the `auto` theme, a value that contains `light` makes o4 use light colors when the terminal doesn't report its own. See [Themes and display](/configuration/appearance).
</ParamField>

<ParamField path="TERM_IMAGE_PREVIEW" type="string">
  Has no effect in o4 0.2.74. o4 reads it to decide whether your terminal can show inline image previews, but it doesn't draw previews in any terminal yet. An image you paste or attach shows as a label above the prompt either way.
</ParamField>

## Model providers and API keys

o4 checks these variables for a provider's credentials when no key for that provider is stored in `~/.o4/settings.json`. A key you enter in `/config` or the setup wizard takes priority over the environment. See [Providers and API keys](/models/providers).

| Variable | Provider |
| - | - |
| `ANTHROPIC_API_KEY` | `anthropic` |
| `CLAUDE_CODE_OAUTH_TOKEN` | `claude-code` (a Claude subscription; see [Claude and ChatGPT subscriptions](/models/subscriptions)) |
| `OPENAI_API_KEY` | `openai` |
| `OPENAI_CODEX_ACCESS_TOKEN` | `openai-codex` (a ChatGPT subscription). When unset, o4 reads the login the `codex` CLI saved in `~/.codex/auth.json`. |
| `GOOGLE_API_KEY`, then `GEMINI_API_KEY` | `google` |
| `XAI_API_KEY` | `xai` |
| `DEEPSEEK_API_KEY` | `deepseek` |
| `KIMI_API_KEY` | `kimi-coding` |
| `META_API_KEY`, then `MODEL_API_KEY` | `meta` |
| `ZAI_API_KEY` | `zai` |
| `ZAI_CODING_API_KEY` | `zai-coding-plan` |
| `OLLAMA_API_KEY` | `ollama` (needed for Ollama Cloud, not for a local server) |

For "`A`, then `B`", o4 uses the first one that is set and not empty.

### Amazon Bedrock

The `amazon-bedrock` provider looks for credentials in this order:

1. A Bedrock API key in `AWS_BEARER_TOKEN_BEDROCK`, or `BEDROCK_API_KEY`.
2. `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`, plus `AWS_SESSION_TOKEN` for temporary credentials.
3. The profile named in `AWS_PROFILE` (or `default`) in `~/.aws/credentials`.

The region comes from `AWS_REGION`, then `AWS_DEFAULT_REGION`, then the region of the `AWS_PROFILE` profile (or `default`) in `~/.aws/config`, and finally `us-east-1`. The `bedrock_region` key in `settings.json` has no effect in 0.2.74.

`BEDROCK_ENDPOINT_OVERRIDE` replaces the Bedrock Runtime endpoint URL. o4 accepts only HTTPS Bedrock Runtime endpoints on AWS hosts and ignores anything else, with a warning in the log.

### Subscription logins from other tools

<ParamField path="CODEX_HOME" type="path">
  Where the `codex` CLI keeps its files. Default `~/.codex`. o4 reads `$CODEX_HOME/auth.json` only for your ChatGPT account ID and the usage limits `/status` shows. The access token for `openai-codex` requests, and `/auth import codex`, always use `~/.codex/auth.json`, so if you move `CODEX_HOME`, set `OPENAI_CODEX_ACCESS_TOKEN` too.
</ParamField>

<ParamField path="CLAUDE_CONFIG_DIR" type="path">
  Where Claude Code keeps its files. When o4 can't run the `claude` command, `/auth import claude` reads `.credentials.json` from this folder first, then from `~/.claude`.
</ParamField>

### Web search

The `web_search` tool uses Brave Search or Tavily when it has a key, and DuckDuckGo otherwise.

<ParamField path="BRAVE_API_KEY" type="string">
  A Brave Search API key. Used when no `brave` key is stored in `settings.json`. If both a Brave and a Tavily key are available, Brave is used.
</ParamField>

<ParamField path="TAVILY_API_KEY" type="string">
  A Tavily API key. Used when no `tavily` key is stored in `settings.json` and no Brave key is available.
</ParamField>

<Note>
  Commands run by the `bash`, `repl` and `test_run` tools, `!` commands, `o4 watch` checks, and the language servers and formatters o4 starts don't see your provider keys. o4 removes these from their environment: the variables in the provider table above, `AWS_BEARER_TOKEN_BEDROCK`, `BEDROCK_API_KEY`, the `api_key_env` variable of each [custom provider](/models/openai-compatible), and the key variables of a few providers o4 doesn't offer. This way the model can't read your keys through a shell command. Other `AWS_*` variables, `GH_TOKEN`, `GITHUB_TOKEN` and `GOOGLE_APPLICATION_CREDENTIALS` stay, so tools like `aws`, `gh` and `gcloud` keep working. `BRAVE_API_KEY` and `TAVILY_API_KEY` also stay. Hooks, MCP servers, the `grep` tool and plugin tools get only a short list of basic variables (`PATH`, `HOME`, `USER`, `LOGNAME`, `SHELL`, `TERM`, `TMPDIR`, `TZ`, `LANG`, `PWD` and `LC_*`), plus the ones you set for hooks and MCP servers in their config, including an MCP server's [`pass_env`](/extend/mcp). Plugin tools also get a fixed `PATH` of `/usr/bin:/bin:/usr/sbin:/sbin`.
</Note>

## Daemon

<ParamField path="O4_AGENT_RUNTIME_DATA_DIR" type="path">
  The data folder `o4 daemon` commands use for the [daemon](/extend/daemon)'s socket, lock, record and log. Default `~/.o4`. Each data folder has its own daemon, so set the same value for `o4 daemon start`, `status` and `stop`. The `[daemon]` settings are still read from `~/.o4/config.toml`.
</ParamField>

## Telemetry

o4 sends a small anonymous usage ping at most once a day. See [Telemetry and privacy](/help/telemetry-and-privacy) for what it contains. These variables can only turn telemetry off; they can't turn it on if you disabled it with `telemetry_enabled` in `settings.json`.

<ParamField path="O4_TELEMETRY" type="string">
  Set to `0`, `false`, `off`, `no` or `disabled` to turn telemetry off for this process.
</ParamField>

<ParamField path="O4_TELEMETRY_DISABLED" type="string">
  Set to `1`, `true`, `on`, `yes` or `enabled` to turn telemetry off for this process.
</ParamField>

<ParamField path="O4_PING_ENDPOINT" type="string">
  The URL the daily ping is sent to, for example an internal mirror. Default `https://t.open4rena.ai/p`.
</ParamField>

<ParamField path="O4_TELEMETRY_ENDPOINT" type="string">
  A URL to upload the local telemetry event log (`~/.o4/telemetry/events.jsonl`) to. When set, o4 posts the logged events there every 5 minutes and when the session ends. Unset by default, so the event log stays on your machine.
</ParamField>

## Debugging

<ParamField path="RUST_LOG" type="string">
  Sets what o4 writes to its log file, `~/.o4/o4.log`. It takes the usual `tracing` filter syntax, such as `debug` or `o4_coding_agent=debug,warn`. Default `warn`. The TUI keeps log output off the screen, so read the file instead.
</ParamField>

<ParamField path="O4_ALLOW_LOCALHOST" type="string">
  A test switch. Set to `1` to let [MCP servers](/extend/mcp) with a remote transport and `http` [hooks](/extend/hooks) use `localhost`, loopback and private network addresses, which o4 refuses otherwise. Link-local addresses, such as `169.254.169.254`, stay blocked.
</ParamField>

<ParamField path="O4_TUI_RENDER_TIMING" type="string">
  Set to `1` (or `true`, `yes`, `on`) to print how long each TUI frame takes to draw, on standard error. The output contains only timings and counts, no text from your session. Use it when you report a slow or laggy interface.
</ParamField>

## Set by o4

o4 sets `O4_SANDBOXED=1` inside the [sandbox](/safety/sandbox) on Linux, so a script can tell it's running there. For sandboxed commands in the `guarded` and `airlock` tiers, it also sets `HTTP_PROXY`, `HTTPS_PROXY`, `http_proxy`, `https_proxy` and `ALL_PROXY` to its egress proxy, unless you turned the proxy off with `proxy.enabled = false` in the [`[sandbox]` section](/reference/configuration#sandbox).
