AIFreeAPI Logo

Codex config.toml: Safe Defaults, Precedence, and Troubleshooting

A
6 min readAI Development Tools

Put each Codex setting in the layer that owns it, change one block at a time, and verify parsing, precedence, permissions, providers, and MCP as separate systems.

Codex configuration control panel separating user defaults, trusted project overrides, profiles, and one-off CLI settings

The safest way to configure Codex is not to paste a giant “complete” file. Start by deciding who should own the setting, change the smallest possible block, and prove one layer before moving to the next. That approach prevents three common failures: a project value that never loads, a personal provider setting placed where Codex ignores it, and a valid TOML file that still cannot authenticate or start an MCP server.

Personal defaults belong in ~/.codex/config.toml. A trusted repository can add .codex/config.toml for project behavior. Named profiles live in separate files next to the user config, and CLI flags are best kept for one-off runs. The CLI and IDE extension share these layers, so a durable edit can affect both surfaces on the same host. OpenAI documents the locations and shared behavior in Config basics.

Before editing anything, make a backup of the file you will touch. Do not delete the entire .codex directory to recover from one bad table: it may also contain credentials, profiles, rules, or other working state.

Put the setting in the layer that owns it

Codex resolves ordinary values from highest to lowest precedence:

  1. CLI flags and --config overrides;
  2. trusted-project .codex/config.toml files, with the closest directory winning;
  3. the file selected with --profile;
  4. ~/.codex/config.toml;
  5. /etc/codex/config.toml on Unix, when present;
  6. built-in defaults.

That order comes from OpenAI's configuration precedence reference. It explains why editing the user file may appear to do nothing: a trusted project or command-line value can be winning above it.

The layer choice is more important than the syntax:

Setting intentBest homeWhy
Your normal model, reasoning effort, notifications, or personal MCP serversUser configThese defaults should follow you across projects
A repository's safe execution boundary or shared project behaviorTrusted project configThe rule travels with that repository
A reusable “deep review” or “read-only audit” modeSeparate profile fileIt changes a coherent set of values without rewriting your base
A temporary experimentCLI flag or -c key=valueIt disappears after the run and cannot silently become policy
A non-bypassable organizational restrictionAdmin-managed requirementsLocal files are defaults, not enforcement

There is an important exception. Project config cannot override machine-local provider, authentication, profile-selection, notification, or telemetry classes, including model_provider, model_providers, profile, and otel. OpenAI lists the current reserved keys in the configuration reference. Put those values in user-level configuration instead of fighting the project layer.

Codex configuration precedence from CLI overrides through project, profile, user, system, and built-in layers
Codex configuration precedence from CLI overrides through project, profile, user, system, and built-in layers

Start with a restrained personal baseline

A practical personal file can be small:

toml
model = "gpt-5.6" model_reasoning_effort = "high" approval_policy = "on-request" sandbox_mode = "workspace-write" web_search = "cached"

This example expresses five decisions and nothing else. Verify that the model ID is available to your current account and client rather than treating any example model as permanent. Omit keys when you are happy with the installed default; fewer persistent values mean fewer surprises after an update.

approval_policy and sandbox_mode solve different problems. The approval policy controls when Codex pauses. The sandbox controls what commands can reach. OpenAI describes workspace-write plus on-request as the lower-risk local automation combination. In contrast, danger-full-access plus never removes both boundaries and should not be a routine convenience setting. See Configure sandbox defaults for the current mode definitions.

Web access is another separate decision. Current Codex supports top-level web_search values cached, indexed, live, and disabled. Cached mode uses an OpenAI-maintained result index; live mode fetches current pages. Old [features] web-search toggles are deprecated, so do not keep a copied legacy flag merely because TOML accepts it. The current choices and defaults are documented in Config basics.

Use profiles for modes, not inline duplicates

Profiles are separate configuration layers:

toml
# ~/.codex/deep-review.config.toml model_reasoning_effort = "xhigh" approval_policy = "on-request" sandbox_mode = "read-only"

Run it with:

bash
codex --profile deep-review

The profile file only needs values that differ from your base. Project config and CLI flags can still override it. This is also a migration trap: in Codex 0.134.0 and later, --profile no longer reads [profiles.deep-review] from the main file, and the top-level profile = "deep-review" selector is no longer supported. The current format is documented under Advanced Config: Profiles.

Treat MCP as a process or connection, not just TOML

An MCP table can be syntactically valid while its process fails immediately. For a local STDIO server, keep the command, arguments, and forwarded environment explicit:

toml
[mcp_servers.docs] command = "docs-server" args = ["--mode", "read-only"] env_vars = ["DOCS_TOKEN"] startup_timeout_sec = 20 tool_timeout_sec = 60 enabled = true

For a streamable HTTP server, use a URL and refer to a token by environment-variable name:

toml
[mcp_servers.issue_tracker] url = "https://mcp.example.internal/mcp" bearer_token_env_var = "ISSUE_TRACKER_TOKEN" enabled = true

Do not paste real tokens into an article, repository config, or support message. The official MCP configuration guide documents STDIO and streamable HTTP transports, OAuth, environment-based headers, allow/deny tool lists, timeouts, and required.

After an edit, use the commands exposed by your installed version:

bash
codex mcp list codex mcp --help

For OAuth-capable servers, the CLI also provides codex mcp login SERVER_NAME. A server appearing in the list proves that Codex parsed its definition; it does not prove the executable exists, the URL is reachable, authentication succeeds, or every tool behaves correctly.

Verify one boundary at a time

Use a short ladder rather than one “does Codex work?” test:

  1. File boundary: confirm you edited the intended user, project, or profile file.
  2. TOML boundary: ask the current CLI to reject unknown configuration where supported.
  3. Precedence boundary: remove one-off flags and check whether a trusted project or profile is overriding the value.
  4. Permission boundary: confirm the selected sandbox and approval behavior match the job.
  5. Provider boundary: test environment-variable presence, auth owner, endpoint, model, and network separately.
  6. MCP boundary: check definition, process startup or HTTP reachability, authentication, then tool calls.

Recent Codex CLI builds expose --strict-config and a doctor command. Check your installed help before relying on them:

bash
codex --version codex --help codex doctor --help

Where available, a useful read-only pass is:

bash
codex --strict-config doctor --summary

--strict-config is meant to fail on unrecognized fields, while doctor checks local installation, configuration, auth, and runtime health. If your version does not expose either option, use the exact commands shown by its --help and the configuration reference that matches that release.

Diagnostic ladder separating file, TOML, precedence, permission, provider, and MCP failures
Diagnostic ladder separating file, TOML, precedence, permission, provider, and MCP failures

Diagnose the symptom instead of rewriting the file

SymptomMost likely boundaryFirst useful check
A value is ignored only in one repoTrust or project precedenceConfirm the repo is trusted and inspect closer .codex/config.toml layers
A provider block works in CLI but not IDEEnvironment visibilityConfirm the IDE process can see the named environment variable
“Unknown field” or startup parse failureVersion or TOMLCompare the key with the current reference and run strict config if available
Model changed but requests still use another routeProvider ownership or higher overrideCheck model_provider, profile, project layer, and CLI flags separately
MCP is listed but unavailableProcess, URL, auth, or timeoutRun codex mcp list, then verify the executable/URL and credential source
A risky mode will not enable on a work machineManaged requirementsAsk whether organizational requirements.toml restricts that value

On managed Business or Enterprise machines, requirements.toml can constrain approval policies, permission profiles, web-search modes, MCP allowlists, plugins, and feature flags. A user value that conflicts with an enforced rule can fall back to an allowed value with a notice. That behavior is documented in Admin-enforced requirements. Do not “fix” it by moving the same forbidden value to another local layer.

A safe change sequence

For routine work, use this order:

  1. identify the one behavior you want to change;
  2. choose user, trusted project, profile, or one-off scope;
  3. back up only that file;
  4. edit one coherent block;
  5. parse and inspect with the installed CLI;
  6. start a low-risk task that makes the setting observable;
  7. if it fails, return to the first unproven boundary;
  8. keep the change only after the expected behavior is visible.

That sequence is slower than copying a full template for about a minute. It is much faster than debugging a file that changed the model, provider, permissions, features, MCP servers, and environment policy at once.

If the real decision is whether Codex is the right coding-agent surface rather than how to configure it, use the separate Claude Code vs Codex comparison. If your provider is specifically Microsoft Foundry, follow the dedicated Azure OpenAI for Codex route instead of mixing an Azure deployment block into a general baseline.