Codex CLI Configuration: config.toml Keys and Precedence

Configure Codex CLI: config.toml precedence, sandbox modes, approval policies, profiles, MCP servers, environment variables, and diagnostics.

October 24, 2026
codex-cliconfigurationconfig-tomlsandboxmcpprofiles

Config files and precedence

Codex reads user defaults from ~/.codex/config.toml and project overrides from .codex/config.toml. Project layers load only for trusted projects; untrusted projects skip project config, hooks, and rules while still loading user and system config.

Values resolve highest-first:

  1. CLI flags and -c / --config overrides
  2. Project .codex/config.toml, from project root down to the current directory (closest wins, trusted projects only)
  3. The profile file selected with --profile, at ~/.codex/profile-name.config.toml
  4. User config: ~/.codex/config.toml
  5. Cloud-managed config.toml defaults for the signed-in workspace
  6. System config: /etc/codex/config.toml on Unix
  7. Built-in defaults

The practical rule: put shared defaults in ~/.codex/config.toml, deviations in a profile file, and repo-specific commands in .codex/config.toml. One-off changes belong on the command line:

codex -c log_dir=./.codex-log
codex -c 'sandbox_workspace_write.network_access=true'

--config values are parsed as TOML, not JSON. Quote the value so the shell does not eat it.

Core keys

Keys worth setting deliberately

model
Default model for the CLI and IDE.

Values: gpt-6.1-sol, gpt-6-luna, gpt-6-astra

review_model
Model used by /review; defaults to the session model.

Values: any available model

model_reasoning_effort
Reasoning effort advertised by the selected model.

Values: low | medium | high | xhigh | max | ultra

approval_policy
When Codex pauses before acting.

Values: on-request | never | granular table

sandbox_mode
Technical filesystem and network boundary.

Values: read-only | workspace-write | danger-full-access

web_search
How web results are fetched. Cached is the default.

Values: cached | indexed | live | disabled

project_doc_max_bytes
Cap on combined AGENTS.md guidance.

Values: default 32768

cli_auth_credentials_store
Where CLI credentials are cached.

Values: file | keyring | auto | ephemeral

Two more keys matter at the edges: openai_base_url overrides the built-in provider endpoint, and model_context_window sets the window Codex assumes for the active model. Leave the window unset unless you run a provider whose window Codex cannot infer; the model default is the safer source of truth.

Three configurations worth copying

Locked-down review session. Read-only sandbox, approvals on request, no network:

approval_policy = "on-request"
sandbox_mode = "read-only"

Use it with codex review --base main or a read-only codex exec when you want findings without any chance of a write.

Normal editing session. The Auto preset with a narrow writable root:

approval_policy = "on-request"
sandbox_mode = "workspace-write"

[sandbox_workspace_write]
network_access = false
writable_roots = ["/Users/you/work/api"]

CI task. Non-interactive, no approvals, read-only unless the job is explicitly allowed to write:

CODEX_API_KEY="$CODEX_API_KEY" codex exec --sandbox read-only --ask-for-approval never --json "triage the failing tests"

Scope the key to that command. A job-wide key is readable by every build script and test in the same environment.

Sandbox modes

ModeFilesystemNetworkUse it for
read-onlyRead inside the sandboxOffPlanning, review, investigation, CI that must not write
workspace-writeWrite inside the workspace and configured rootsOff unless enabledNormal editing sessions
danger-full-accessNo sandboxOnIsolated runners and containers only

The default is workspace-write with network off. Inside a writable workspace, .git/, .agents/, .codex/, and .aws/ may remain read-only, which is why a git commit can still require approval.

Network is a separate opt-in:

[sandbox_workspace_write]
network_access = true
writable_roots = ["/Users/you/.pyenv/shims"]
exclude_slash_tmp = false

To constrain outbound traffic once network is enabled, turn on the network proxy feature and declare destinations:

[features.network_proxy]
enabled = true
domains = { "api.openai.com" = "allow", "example.com" = "deny" }

The proxy does not grant network access. Network on plus proxy off means unrestricted outbound access; network off plus proxy on means the proxy does nothing.

On Windows, the preferred sandbox is MXC:

[windows]
sandbox = "elevated" # legacy fallback

[features]
prefer_mxc = true

Use unelevated only when elevated setup is unavailable and policy permits it.

Approval policies

approval_policy controls interruptions, not capabilities.

  • on-request — commands allowed by the sandbox run without approval; leaving the sandbox, using the network, or other escalations pauses for a decision.
  • never — no approval prompts. Appropriate for read-only automation; dangerous anywhere the agent can write.
  • Granular table — allow or auto-reject individual prompt categories, useful when some escalations should fail closed.
approval_policy = "on-request"
approvals_reviewer = "user" # or auto_review
allow_login_shell = false   # optional hardening

approval_policy = "untrusted" is retired and can prevent the client from starting. Remove it from user and project config, profiles, and startup scripts. If you want stricter command approval for a specific repository, use a project entry in your user config instead:

[projects."/path/to/repo"]
trust_level = "untrusted"

approvals_reviewer = "auto_review" routes eligible requests through automatic review; it changes the reviewer, not the sandbox boundary.

Profiles

Profiles are separate TOML files, not tables inside config.toml. Create ~/.codex/deep-review.config.toml with top-level keys only:

model = "gpt-6.1-sol"
model_reasoning_effort = "high"
approval_policy = "on-request"
sandbox_mode = "read-only"
codex --profile deep-review
codex exec --profile deep-review "review this change"

The profile layer sits above user config and below project and CLI config, so it should contain only the values that differ. Since Codex 0.134.0, --profile no longer reads [profiles.profile-name] from config.toml, and the top-level profile = "name" selector is gone. Move legacy tables into profile-name.config.toml files.

MCP servers

The CLI, desktop app, and IDE extension share MCP configuration on the same host. Add a STDIO server from the command line:

codex mcp add context7 -- npx -y @upstash/context7-mcp

Or declare it directly:

[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]
env = { LOG_LEVEL = "warn" }

Streamable HTTP servers use url instead of command:

[mcp_servers.docs]
url = "https://mcp.example.com/mcp"
bearer_token_env_var = "DOCS_MCP_TOKEN"

Supported options include auth = "oauth" | "chatgpt", http_headers, env_http_headers, env_vars, cwd, and required. Setting required = true makes codex exec exit with an error if that server fails to initialize instead of continuing without it — the right default for automation that depends on a tool.

Inspect and authenticate:

codex mcp list
codex mcp login docs

Inside the TUI, /mcp shows the active servers. Codex reads the MCP instructions field at initialization and treats it as server-wide guidance; keep the first 512 characters self-contained if you maintain a server.

Environment variables

VariableUsed for
CODEX_HOMEAlternate config directory, default ~/.codex
CODEX_API_KEYA single run's API key; scope it to the invocation
OPENAI_API_KEYPipe into codex login --with-api-key
CODEX_ACCESS_TOKENEnterprise access tokens for automation
VISUAL / EDITOROpen longer prompts in your editor

Do not set OPENAI_API_KEY or CODEX_API_KEY job-wide in CI that checks out or runs repository-controlled code. Build scripts, tests, and dependency lifecycle hooks can read the environment; scope the key to the Codex step.

Verify the effective configuration

codex doctor
codex debug models
codex debug prompt-input "Summarize this repo"

codex doctor checks installation, config, auth, runtime, Git, terminal, app-server, and thread inventory. codex debug models prints the model catalog Codex sees as JSON, which settles "why is this model unavailable" faster than reading config. codex debug prompt-input renders the exact model-visible prompt input, which is the ground truth for instruction discovery.

If a value is not taking effect, check precedence before editing: a project file beats a profile, and a CLI flag beats both. -c overrides are the fastest way to test a hypothesis without touching disk.

If you are porting configuration from Claude Code or OpenCode, keep the conceptual split — instruction file, permissions, MCP servers — and map the keys instead of copying them. The tool comparison lists which surfaces each client supports.

Sources