cheat sheet

Codex Configuration

Complete config.toml reference for Codex CLI — model selection, approval policies, sandbox modes, profiles, MCP server stubs, shell environment, notify hooks, and project trust levels.

Codex Configuration

What it is

Codex CLI is configured via a TOML file at ~/.codex/config.toml. A project-level .codex/config.toml inside a trusted project directory is merged on top of the user config, letting you set per-repo model, approval, and sandbox overrides without touching your global defaults.


File location

Codex resolves configuration by reading the global config first, then layering the project-level config on top if the current project is trusted. The merge is a deep merge — tables compose, but scalar keys are overwritten from highest priority (project) to lowest (global). Set CODEX_HOME to relocate the entire configuration tree (handy for project-scoped sandboxes or testing).

FilePurpose
~/.codex/config.tomlGlobal user configuration
<project>/.codex/config.tomlProject-level overrides (requires trust)
CODEX_HOME/config.tomlOverride base dir via env var CODEX_HOME

Inspect the merged active config:

bash
codex --print-config

Output:

text
model                  = "gpt-4o"
approval_policy        = "on-request"
sandbox_mode           = "workspace-write"
profile                = "sprint"
project_doc_max_bytes  = 65536
[history]
persistence = "save"
...

Minimal config

A three-line config.toml is enough to fully configure Codex for day-to-day development. Everything else has sane defaults. Start here and add keys only when the default behaviour does not match what you need.

toml
model = "gpt-4o"
approval_policy = "on-request"
sandbox_mode = "workspace-write"

Output: (none — config file, not a runnable command)

Verify it parses:

bash
codex --print-config | head -3

Output:

text
model           = "gpt-4o"
approval_policy = "on-request"
sandbox_mode    = "workspace-write"

Model settings

Sets the default model and provider for all Codex sessions. The model key takes the model name; model_provider selects the API backend ("openai" by default, or "azure" / a custom endpoint); model_reasoning_effort controls how much compute reasoning models spend before responding.

toml
# The model to use for all sessions
model = "gpt-4o"

# Alternative provider (e.g., "azure", "custom")
model_provider = "openai"

# Reasoning effort: "minimal" | "low" | "medium" | "high" | "xhigh"
model_reasoning_effort = "medium"

GPT-5 family models (as of 2026): gpt-5, gpt-5-pro, gpt-5.5, gpt-5.4, gpt-5.3-codex.

Per-model effort overrides

You can override model_reasoning_effort per profile, so a "deep" profile spends more compute and a "quick" profile spends less:

toml
[profiles.deep]
model                  = "gpt-5-pro"
model_reasoning_effort = "xhigh"

[profiles.quick]
model                  = "gpt-5"
model_reasoning_effort = "minimal"

Listing available models

bash
codex models

Output:

text
gpt-4o            general purpose, vision
gpt-4o-mini       cheap and fast
gpt-5             reasoning model, default
gpt-5-pro         flagship reasoning
gpt-5.3-codex     code-tuned variant

Approval policy

Controls when Codex asks for your approval before executing commands. The default for interactive sessions is "on-request" (Codex only asks when sandbox escalation would be needed), and the default for codex exec is "never". The approval_policy setting in config.toml overrides both defaults; pass -a on the command line to override per-invocation.

toml
# "untrusted"   — always prompt on mutating commands (safest)
# "on-request"  — prompt when sandbox escalation is needed (default interactive)
# "on-failure"  — prompt after a command fails (deprecated)
# "never"       — never prompt (default for codex exec / non-interactive)
approval_policy = "on-request"

See Approvals & Sandbox for full detail.


Sandbox mode

Controls what the agent is allowed to do to your filesystem and network without an explicit approval. "workspace-write" is the practical default for most development work — it confines writes to the current working directory and blocks outbound network. Use "read-only" for untrusted code review and "danger-full-access" only inside disposable containers.

toml
# "read-only"          — no filesystem writes, no network
# "workspace-write"    — writes confined to cwd, network blocked by default
# "danger-full-access" — no restrictions (use only in trusted containers)
sandbox_mode = "workspace-write"

Shell environment

Determines which environment variables are visible to the commands Codex runs. "inherit" (the default) passes your full shell env through, which is convenient but may leak secrets; "clean" starts with a minimal env; "custom" uses only the variables you define in the [env] table below.

toml
[shell_environment_policy]
# "inherit"  — pass through the parent shell's env vars (default)
# "clean"    — start with a minimal env
# "custom"   — set only the vars in [env] below
inherit = "inherit"

[env]
MY_VAR = "value"

History persistence

Controls whether session transcripts are written to disk. With "save", full conversation history is stored under ~/.codex/history/ and can be resumed or audited later. Use "no-save" when working with sensitive data you do not want persisted locally.

toml
[history]
# "save"    — persist session transcripts to ~/.codex/history/
# "no-save" — ephemeral sessions only
persistence = "save"

Profiles

A "profile" is a named bundle of overrides — model, reasoning effort, approval policy, sandbox mode — that you activate per-invocation with -p <name>. Profiles let you keep a conservative default (e.g., on-request + workspace-write) while still having a one-flag escape hatch for read-only review or CI use. Profile values override the top-level keys but are themselves overridden by command-line flags. Named profiles let you switch model/approval/sandbox combos with -p <name> or codex --profile <name>.

toml
[profiles.quick]
model = "gpt-4o-mini"
approval_policy = "never"
sandbox_mode = "workspace-write"

[profiles.deep]
model = "gpt-5-pro"
model_reasoning_effort = "xhigh"
approval_policy = "on-request"
sandbox_mode = "workspace-write"

[profiles.safe-review]
model = "gpt-4o"
approval_policy = "untrusted"
sandbox_mode = "read-only"

Activate a profile:

bash
codex --profile deep

Output: (TUI opens using gpt-5-pro at xhigh reasoning)

Set a default profile:

toml
profile = "quick"

List defined profiles:

bash
codex profiles

Output:

text
quick        gpt-4o-mini  never        workspace-write
deep         gpt-5-pro    on-request   workspace-write
safe-review  gpt-4o       untrusted    read-only
ci           gpt-4o-mini  never        workspace-write

Inspect a single profile:

bash
codex profiles show deep

Output:

text
[profiles.deep]
model                  = "gpt-5-pro"
model_reasoning_effort = "xhigh"
approval_policy        = "on-request"
sandbox_mode           = "workspace-write"

Project trust

Project trust is Codex's escape hatch for "should I load arbitrary config and hooks from this directory?". A new directory is untrusted by default; loading its .codex/config.toml would let a malicious repo silently disable your sandbox or wire up a hook that exfiltrates env vars. Trusting a directory in ~/.codex/config.toml opts it in to those overrides. Codex only loads .codex/config.toml and .codex/hooks.json from a project directory if the project is trusted.

toml
[projects."/home/alice/myproject"]
trust_level = "trusted"

[projects."/home/alice/untrusted-repo"]
trust_level = "untrusted"

Trust a project interactively on first run — Codex prompts you to trust the directory and writes the entry automatically.

List trusted projects:

bash
codex projects list

Output:

text
/home/alice/myproject       trusted
/home/alice/work/api        trusted
/home/alice/notes           untrusted

Trust a project from the CLI:

bash
codex projects trust /home/alice/myproject

Output:

text
Trusted /home/alice/myproject

Revoke trust:

bash
codex projects untrust /home/alice/myproject

Output:

text
Removed trust for /home/alice/myproject

Notify (turn-complete callback)

Run an external command whenever an agent turn completes. Useful for desktop notifications or logging.

toml
notify = ["python3", "/path/to/notify.py"]

The command receives a JSON payload on stdin:

json
{
  "type": "agent-turn-complete",
  "thread-id": "th_01abc",
  "turn-id": "t_01xyz",
  "cwd": "/home/alice/myproject",
  "input-messages": [...],
  "last-assistant-message": "Done. Added docstrings to 12 functions."
}

Example notify script:

python
import json, sys, subprocess
data = json.load(sys.stdin)
msg = data.get("last-assistant-message", "Codex turn complete")
subprocess.run(["osascript", "-e", f'display notification "{msg}" with title "Codex"'])

Output: (none — stdout from notify.py is discarded)


File opener

Specifies the editor command Codex invokes when you ask it to open a file (e.g., "open that file in my editor"). Accepts any command on your PATH"cursor", "code", "vim", "nvim", etc. Defaults to the value of $EDITOR if unset.

toml
file_opener = "cursor"   # or "code", "vim", "nvim", etc.

AGENTS.md config

AGENTS.md (or a fallback like CLAUDE.md) is a per-project instruction file that Codex reads automatically when it starts in a trusted directory. These keys control how large that file may be and what filenames to look for, letting you standardize on a single instruction file name across a mixed-agent workflow.

toml
# Max bytes to read from AGENTS.md (default 32768)
project_doc_max_bytes = 65536

# Filenames to look for as project instructions (in order)
project_doc_fallback_filenames = ["AGENTS.md", "CLAUDE.md", "COPILOT-INSTRUCTIONS.md"]

Telemetry and updates

Codex sends anonymous usage telemetry by default. Disable globally:

toml
[telemetry]
enabled = false

Or per-invocation via env var:

bash
CODEX_NO_TELEMETRY=1 codex

Output: (TUI opens; no telemetry pings sent)

Disable update checks:

toml
[updates]
check_for_updates = false

Full annotated example

A representative ~/.codex/config.toml showing how the top-level keys, profiles, projects, and MCP server blocks fit together. Copy this as a starting point and trim what you don't need.

toml
# ~/.codex/config.toml

model                  = "gpt-4o"
model_reasoning_effort = "medium"
approval_policy        = "on-request"
sandbox_mode           = "workspace-write"
profile                = "quick"
file_opener            = "code"
project_doc_max_bytes  = 65536

notify = ["python3", "/home/alice/.codex/notify.py"]

[history]
persistence = "save"

[shell_environment_policy]
inherit = "inherit"

[env]
EDITOR = "vim"

[telemetry]
enabled = false

[profiles.quick]
model              = "gpt-4o-mini"
approval_policy    = "never"

[profiles.deep]
model                  = "gpt-5-pro"
model_reasoning_effort = "xhigh"

[profiles.safe-review]
model           = "gpt-4o"
approval_policy = "untrusted"
sandbox_mode    = "read-only"

[projects."/home/alice/work/prod"]
trust_level = "trusted"

[mcp_servers.filesystem]
command = "npx"
args    = ["-y", "@modelcontextprotocol/server-filesystem", "/home/alice/work"]
enabled = true

Output: (none — TOML config file)


Common pitfalls

  1. TOML is whitespace-sensitive around tables. [profiles.quick] and [ profiles.quick ] parse the same, but [profiles . quick] is a syntax error. Run codex --print-config after edits to confirm the file parsed.

  2. Top-level keys must precede [table] headers. Once you open a table (e.g., [history]), every subsequent key belongs to that table until the next header. If model = "gpt-4o" is below [history], it becomes history.model and Codex ignores it.

  3. Profile keys override top-level keys, but flags override both. Order of precedence is: command-line flag > active profile > top-level config > built-in default. If a setting "doesn't take effect," check which layer is winning.

  4. [env] is set, not merged. Listing EDITOR = "vim" under [env] does NOT add to your inherited env — it sets EDITOR after the inherit step. Use this for variables you want to force regardless of the parent shell.

  5. project_doc_max_bytes silently truncates. If your AGENTS.md is larger than the configured limit, Codex truncates mid-line without warning. Increase the limit or split into includes.

  6. A trusted project's .codex/config.toml cannot upgrade sandbox mode beyond what the global config permits. Codex only allows the project config to narrow the sandbox (e.g., from workspace-write to read-only). It cannot widen it to danger-full-access — that always requires a flag.

  7. notify runs synchronously. A slow notify script blocks the next turn. Keep it under 1 second of work, or fork into a subshell (subprocess.Popen with start_new_session=True).


Real-world recipes

Profile per branch via direnv

Drop a .envrc into your repo that sets CODEX_HOME to a project-scoped config. Each git worktree gets its own profile set, MCP servers, and history.

bash
# .envrc
export CODEX_HOME="${PWD}/.codex"

Output: (none — direnv-allowed file)

Then place a config.toml at .codex/config.toml with the per-branch overrides you want.

CI profile that fails fast

A CI profile that refuses to escalate the sandbox and exits 1 on the first unrecoverable error. Combine with codex exec in your pipeline.

toml
[profiles.ci]
model              = "gpt-4o-mini"
approval_policy    = "never"
sandbox_mode       = "workspace-write"
model_reasoning_effort = "minimal"
bash
codex exec -p ci "Run pytest and apply mechanical fixes; exit 1 if any test still fails."

Output:

text
Ran 142 tests, 142 passed. No edits required.

Per-machine override via include

Codex itself has no include directive, but you can simulate one by symlinking a shared snippet:

bash
ln -s /shared/codex-team-base.toml ~/.codex/team-base.toml
codex --config ~/.codex/team-base.toml --config ~/.codex/config.toml

Output: (TUI opens with both configs merged, later override earlier)

Disable sandbox for a single ad-hoc invocation

Useful for one-off npm install-driven debugging without modifying global config.

bash
codex --sandbox danger-full-access "Run npm install and tell me what failed"

Output:

text
[agent] Running npm install…
[agent] Failed at step "node-gyp rebuild" — Python 3.13 is incompatible.

Useful when sharing your setup with a teammate or filing a bug.

bash
codex --print-config > /tmp/codex-effective.toml

Output: (none — writes resolved config to file)

Switch model mid-CI based on diff size

bash
LINES=$(git diff origin/main...HEAD | wc -l)
if [ "$LINES" -gt 500 ]; then
  codex exec -p deep "Review this diff for correctness."
else
  codex exec -p quick "Review this diff for correctness."
fi

Output:

text
[agent review output]