Codex config.toml: location, example and options

Updated 24 October 2026

Codex CLI, the IDE extension and the Codex desktop app all read their settings from config.toml. It decides which model Codex uses, when it stops to ask you, what its commands can touch, which MCP servers it starts and how it notifies you. This guide covers where the file lives, a starter file you can copy, the options worth setting, and the mistakes that make a setting quietly do nothing. Everything here was checked against Codex CLI 0.163.

The short answer

FilePathApplies to
User~/.codex/config.toml (Windows: %USERPROFILE%\.codex\config.toml)You, in every project
Project.codex/config.toml in a repositoryThat project, once you trust it
Profile~/.codex/<name>.config.tomlRuns started with --profile <name>
System/etc/codex/config.tomlEvery user on a macOS or Linux machine
One runcodex -c key=valueThat run only

Run codex doctor after any edit. It parses the file without starting a session and names many keys Codex is ignoring.

1. Codex config.toml location

Codex keeps its config, login, logs and session history in one folder, CODEX_HOME, which defaults to ~/.codex. Your config is config.toml inside it:

If the file isn’t there, create it. Commands that change settings, such as codex mcp add and codex features enable, write to it for you and create it if needed. In the IDE extension, the gear icon opens it from Codex Settings → Open config.toml.

Project config files

A repository can carry its own .codex/config.toml. Codex walks from the project root (the folder with .git) down to the folder you started in and loads every one it finds; the closest file wins. Project files load only when the project is trusted, so a cloned repo can’t change your settings until you say so.

Some keys are refused in a project file, and Codex prints a startup warning instead: model_provider, model_providers, openai_base_url, notify, profile, profiles and otel, among others. Keep those in your user file.

Which file wins

When a key is set in several places, the highest one in this list wins:

  1. CLI flags and -c overrides
  2. Project .codex/config.toml, closest folder first (trusted projects only)
  3. The profile file you picked with --profile
  4. ~/.codex/config.toml
  5. Config managed by your workspace, then /etc/codex/config.toml
  6. Built-in defaults

On a work machine, an admin’s requirements.toml sits above all of this and can forbid values such as approval_policy = "never".

2. A full config.toml example

A starter file with the settings most people change. Everything is optional; delete what you don’t need. Note the order: plain key = value lines first, then the [tables].

~/.codex/config.toml#:schema https://developers.openai.com/codex/config-schema.json

# Model
model = "gpt-6.1-sol"              # pick a model your account can use
model_reasoning_effort = "medium"  # low, medium, high, xhigh... depends on the model

# Approvals and sandbox
approval_policy = "on-request"     # or "never"
sandbox_mode = "workspace-write"   # read-only, workspace-write, danger-full-access

# Search: "cached" (default), "live", or "disabled"
web_search = "cached"

# Run a program when a turn finishes (user config only)
notify = ["python3", "/Users/you/.codex/notify.py"]

[sandbox_workspace_write]
network_access = true              # let commands reach the network

[tui]
notifications = ["agent-turn-complete", "approval-requested"]
notification_method = "auto"       # auto, osc9 or bel

[features]
hooks = true                       # on by default; false turns hooks off

[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]

[projects."/Users/you/code/my-app"]
trust_level = "trusted"

The #:schema line is optional. With the Even Better TOML extension in VS Code or Cursor, it gives you autocomplete and flags unknown keys while you type. Replace the paths with your own; codex doctor reports this file as config.toml parse ok with one MCP server.

3. Codex config.toml options worth knowing

The full reference lists hundreds of keys. These are the ones you’re likely to set:

KeyWhat it does
modelModel for new sessions. Same as --model.
model_reasoning_effortlow, medium, high, xhigh and higher levels where the model offers them
approval_policyWhen Codex stops to ask: on-request, never or { granular = { … } }
sandbox_modeWhat commands can touch: read-only, workspace-write, danger-full-access
[sandbox_workspace_write]network_access = true for the network, writable_roots for extra folders
approvals_revieweruser, or auto_review to let a reviewer agent answer prompts
default_permissions, [permissions.<name>]Beta permission profiles; an alternative to sandbox_mode, not an addition
web_searchcached (default), indexed, live or disabled
notifyA program to run when a turn finishes; it gets one JSON argument
[tui] notificationsBuilt-in terminal notifications: true or a list of events, plus notification_method and notification_condition
[features]Optional features by name, such as hooks = false or memories = true. codex features list shows them all.
[mcp_servers.<name>]MCP servers, with command and args or a url
model_provider, [model_providers.<id>]Send requests to a proxy, Azure, a local model or another API
[projects."<path>"] trust_level"trusted" or "untrusted"; Codex writes this when you answer the trust prompt
[shell_environment_policy]Which environment variables commands Codex runs can see
cli_auth_credentials_storeWhere your login is cached: file, keyring, auto or ephemeral
[history] persistence"none" stops Codex saving transcripts to history.jsonl
file_openerWhich editor opens file citations: vscode, cursor, windsurf, vscode-insiders or none

For notifications in more detail, see How to get Codex notifications. Hooks live in their own file, ~/.codex/hooks.json, or inline under [hooks]; see the Codex hooks guide.

4. Approval policy, sandbox and permissions

approval_policy and sandbox_mode work as a pair. The sandbox is the fence, and the approval policy decides whether Codex can ask you to let a command past it. The usual setup in a Git repository is workspace-write with on-request, plus network_access = true if your work needs package installs. Two values from older guides no longer work: approval_policy = "untrusted" is retired and can stop Codex from starting, and on-failure is deprecated.

Codex also has beta permission profiles, which describe folders and network rules in more detail than sandbox_mode. This one starts from the built-in :workspace profile and blocks .env files:

~/.codex/config.tomlapproval_policy = "on-request"
default_permissions = "no-env"

[permissions.no-env]
extends = ":workspace"

[permissions.no-env.filesystem.":workspace_roots"]
"**/*.env" = "deny"

Permission profiles don’t mix with the older settings. If sandbox_mode or [sandbox_workspace_write] appears in any loaded config, or you pass --sandbox, Codex uses those and ignores default_permissions. Every value, flag and combination is covered in Codex approval modes and sandbox settings.

5. Profiles are separate files now

A profile is a second config file layered on top of yours. codex --profile review loads ~/.codex/config.toml, then ~/.codex/review.config.toml. Put only the keys that differ, at the top level:

~/.codex/review.config.tomlmodel_reasoning_effort = "high"
approval_policy = "on-request"
sandbox_mode = "read-only"

Since Codex 0.134, --profile no longer reads [profiles.<name>] tables inside config.toml, and a top-level profile = "…" line is no longer supported. Most profile examples online still use the old tables, which is why a copied profile often seems to do nothing. Move each one into its own file. Profile names can use letters, numbers, hyphens and underscores.

6. MCP servers in config.toml

Each server is a [mcp_servers.<name>] table. A local server runs a command; a remote one has a url:

~/.codex/config.toml[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]

[mcp_servers.figma]
url = "https://mcp.figma.com/mcp"
bearer_token_env_var = "FIGMA_OAUTH_TOKEN"
tool_timeout_sec = 45

codex mcp add context7 -- npx -y @upstash/context7-mcp writes the first table for you. bearer_token_env_var holds the name of a variable, not the token, so the file stays safe to share. Other useful keys: env, enabled = false to switch a server off without deleting it, enabled_tools and disabled_tools, and startup_timeout_sec (default 10). Type /mcp in a session to see what’s running.

7. API keys, login and model_providers

Your OpenAI login doesn’t go in config.toml. Codex keeps it separately:

The login is cached in ~/.codex/auth.json or your OS credential store; cli_auth_credentials_store picks which. Treat auth.json like a password. To see which login is active without printing it, run codex login status.

For anything other than OpenAI’s own endpoint, define a provider and point model_provider at it. env_key names the environment variable that holds the key:

~/.codex/config.tomlmodel = "gpt-6.1-sol"
model_provider = "proxy"

[model_providers.proxy]
name = "Company LLM proxy"
base_url = "https://llm-proxy.example.com/v1"
env_key = "PROXY_API_KEY"

If PROXY_API_KEY isn’t set, codex doctor says so: “active model provider auth env var is missing”. A few rules:

8. One-off overrides with -c

-c key=value (or --config) changes any key for one run without touching the file. Use dots for keys inside tables:

Terminalcodex -c model_reasoning_effort=high
codex -c sandbox_workspace_write.network_access=true
codex -c 'tui.notifications=["approval-requested"]'
codex -c mcp_servers.context7.enabled=false

The value is parsed as TOML, not JSON. If it doesn’t parse, Codex uses the raw text as a string, which is why -c model_reasoning_effort=high works without quotes. Lists and anything with spaces need single quotes around the whole argument so your shell passes it through intact. --enable <feature> and --disable <feature> are shortcuts for -c features.<name>=true and false.

9. Check your file with codex doctor

codex doctor loads your config the way a session would, without starting one, and reports on config, login, MCP servers and the sandbox. A good file shows:

  [ok] config       loaded
      config.toml parse        ok

A key in the wrong place gets named:

startup warning          Codex is ignoring 1 unrecognized configuration setting. Check for typos or deprecated settings.
user (~/.codex/config.toml): `sandbox_workspace_write.approval_policy` is ignored.

And a file that doesn’t parse shows the line and column, while any other command stops with the full error:

Error: failed to load bootstrap configuration

Caused by:
    0: ~/.codex/config.toml:1:9: string values must be quoted, expected literal string

codex doctor --summary prints just the check rows, and --json gives a redacted report you can share. Inside a session, /debug-config shows which config layers loaded and /status shows the model and approval policy in effect. Start Codex with --strict-config to make unknown keys an error instead of a warning.

10. Common mistakes

A top-level key below a table header. This is the classic one. In TOML, every line after [tui] belongs to tui until the next header, so this model is tui.model:

~/.codex/config.toml (wrong)[tui]
notifications = true
model = "gpt-6.1-sol"   # read as tui.model, not model

Move model, approval_policy, sandbox_mode, notify and the other top-level keys above the first [header]. Don’t rely on codex doctor to catch this one: it names a stray key under [sandbox_workspace_write], but in our test a model line under [tui] was dropped without any warning.

The other usual suspects:

Answer Codex approvals from your browser

With approval_policy = "on-request", Codex waits in the terminal until you answer, and [tui] notifications only tells you to go back to it. Agent Pets turns each Codex session into a pet that walks along the bottom of every Chrome page:

npx getagentpets init adds hooks to ~/.codex/hooks.json; open Codex once and trust them with /hooks. It doesn’t edit your config.toml, so just make sure you haven’t set hooks = false under [features]. The terminal prompt keeps working, and everything runs on your computer.

Get Agent Pets — was $25, now $6Get Agent Pets — $25

Questions

Where is the Codex config.toml file?

Your user config is ~/.codex/config.toml on macOS and Linux and %USERPROFILE%\.codex\config.toml on Windows. If CODEX_HOME is set, Codex reads config.toml from that folder instead. A repository can add .codex/config.toml, which loads only when you trust the project.

How do I set an API key for Codex?

Not in config.toml. Run printenv OPENAI_API_KEY | codex login --with-api-key once, and Codex stores the credential in ~/.codex/auth.json or your OS credential store. For a single codex exec run, set CODEX_API_KEY inline. A custom provider names its variable with env_key.

Why is my Codex config.toml setting ignored?

Usually the key sits below a [table] header, so TOML reads it as part of that table. Move top-level keys like model and approval_policy above the first header. Also check for a project file or -c flag that overrides it, an untrusted project, or an old [profiles] table. codex doctor names many ignored keys.

Where did profiles go in Codex config.toml?

Since Codex 0.134, --profile reads a separate file, ~/.codex/<name>.config.toml, instead of a [profiles.<name>] table. Move each table’s keys to the top level of its own file and delete the old table and any profile = line.

How do I change one Codex setting for a single run?

Use -c key=value, for example codex -c model_reasoning_effort=high or codex -c sandbox_workspace_write.network_access=true. The value is parsed as TOML; if it doesn’t parse, Codex uses it as a plain string.

Sources: Codex documentation on config basics, advanced configuration, the configuration reference, environment variables, authentication, non-interactive mode, permissions, MCP, the CLI reference, slash commands and the Windows app; codex --help and codex doctor for Codex CLI 0.163.0, run against each example file on this page.

More guides