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:
- CLI flags and
--configoverrides; - trusted-project
.codex/config.tomlfiles, with the closest directory winning; - the file selected with
--profile; ~/.codex/config.toml;/etc/codex/config.tomlon Unix, when present;- 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 intent | Best home | Why |
|---|---|---|
| Your normal model, reasoning effort, notifications, or personal MCP servers | User config | These defaults should follow you across projects |
| A repository's safe execution boundary or shared project behavior | Trusted project config | The rule travels with that repository |
| A reusable “deep review” or “read-only audit” mode | Separate profile file | It changes a coherent set of values without rewriting your base |
| A temporary experiment | CLI flag or -c key=value | It disappears after the run and cannot silently become policy |
| A non-bypassable organizational restriction | Admin-managed requirements | Local 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.

Start with a restrained personal baseline
A practical personal file can be small:
tomlmodel = "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:
bashcodex --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:
bashcodex 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:
- File boundary: confirm you edited the intended user, project, or profile file.
- TOML boundary: ask the current CLI to reject unknown configuration where supported.
- Precedence boundary: remove one-off flags and check whether a trusted project or profile is overriding the value.
- Permission boundary: confirm the selected sandbox and approval behavior match the job.
- Provider boundary: test environment-variable presence, auth owner, endpoint, model, and network separately.
- 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:
bashcodex --version codex --help codex doctor --help
Where available, a useful read-only pass is:
bashcodex --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.

Diagnose the symptom instead of rewriting the file
| Symptom | Most likely boundary | First useful check |
|---|---|---|
| A value is ignored only in one repo | Trust or project precedence | Confirm the repo is trusted and inspect closer .codex/config.toml layers |
| A provider block works in CLI but not IDE | Environment visibility | Confirm the IDE process can see the named environment variable |
| “Unknown field” or startup parse failure | Version or TOML | Compare the key with the current reference and run strict config if available |
| Model changed but requests still use another route | Provider ownership or higher override | Check model_provider, profile, project layer, and CLI flags separately |
| MCP is listed but unavailable | Process, URL, auth, or timeout | Run codex mcp list, then verify the executable/URL and credential source |
| A risky mode will not enable on a work machine | Managed requirements | Ask 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:
- identify the one behavior you want to change;
- choose user, trusted project, profile, or one-off scope;
- back up only that file;
- edit one coherent block;
- parse and inspect with the installed CLI;
- start a low-risk task that makes the setting observable;
- if it fails, return to the first unproven boundary;
- 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.



