Codex config.toml: set the model, model_reasoning_effort (low to ultra) and per-task profiles
Change model and reasoning effort in ~/.codex/config.toml (model_reasoning_effort = "high"), switch per-task profiles with --profile, and see which layer wins when settings overlap
Contents
Almost everything about how Codex CLI behaves is decided in ~/.codex/config.toml: model, reasoning effort, approval policy, sandbox, MCP servers. This article focuses on the settings you will actually touch day to day.
KEY POINT
What you will learn
- Setting
modelandmodel_reasoning_effort, and how to choose - Defining profiles for different tasks and switching with
--profile - How options, profiles and top-level values take precedence
Location and structure
# ~/.codex/config.toml
model = "gpt-5-codex"
model_reasoning_effort = "medium"
approval_policy = "on-request"
sandbox_mode = "workspace-write"
The file is TOML: top-level keys are defaults; tables such as [profiles.name] and [mcp_servers.name] hold specific settings.
用語解説
TOML: A config format of key = value lines. Strings are double-quoted, booleans are true / false, and sections are written as [name].
Model and reasoning effort
| Key | Example | Meaning |
|---|---|---|
model | "gpt-5-codex" etc. | The model to use. Check available names with /model |
model_reasoning_effort | "low" / "medium" / "high" / "xhigh" / "max" / "ultra" | How much reasoning to spend. Higher is more careful but slower and costlier. The reference notes that the available levels depend on the model and client |
Model names change with each release. If the one in your config.toml stops working, run /model and update it.
Rules of thumb for effort:
low: routine edits, comments, small refactorsmedium: everyday developmenthigh: design decisions, hard bugs, large changes
/model changes both temporarily inside a session; config.toml sets the default for the next start.
How to change effort in Codex CLI
There are three places to change reasoning effort, depending on how long you want the change to last:
| You want to | Do this |
|---|---|
| Change it permanently | Set model_reasoning_effort in ~/.codex/config.toml |
| Change it for one run | codex -c model_reasoning_effort='"high"' "<your prompt>" |
| Change it mid-session | Run /model |
The configuration reference describes the value as the "reasoning effort advertised by the selected model, such as low, medium, high, xhigh, max, or ultra", and adds that the available levels depend on the model and client. (minimal, listed in earlier versions of the reference, is no longer there.) Separate keys exist for plan mode (plan_mode_reasoning_effort) and spawned agents (agents.default_subagent_reasoning_effort). All of this is covered in detail in How to change reasoning effort in Codex CLI.
Profiles for different tasks
Instead of repeating options, define profiles:
model = "gpt-5-codex"
model_reasoning_effort = "medium"
approval_policy = "on-request"
sandbox_mode = "workspace-write"
[profiles.quick]
model_reasoning_effort = "low"
approval_policy = "on-failure"
[profiles.deep]
model_reasoning_effort = "high"
approval_policy = "on-request"
[profiles.readonly]
sandbox_mode = "read-only"
approval_policy = "on-request"
codex --profile quick "Fix the typos"
codex --profile deep "Review the authentication design"
codex --profile readonly "List every caller of this function"
Keys missing from a profile fall back to the top-level values. Choosing approval and sandbox settings is covered in Codex CLI approval modes versus sandbox modes.
Setting a default profile
profile = "quick"
makes quick the profile used when --profile is not given.
Precedence
When the same setting appears in several places:
- Command-line options (
--model,--sandbox, ...) - The profile selected with
--profile - Top-level values in config.toml
- Codex's built-in defaults
Remember "option > profile > top level > default" and unexpected values become easy to trace.
Other useful keys
# Maximum total size of AGENTS.md files loaded at start (bytes)
project_doc_max_bytes = 32768
# Notification command on supported systems
notify = ["notify-send", "Codex"]
# History persistence
[history]
persistence = "save-all"
Key names change between versions; if a setting has no effect, check the current configuration reference.
Keep the API key out of config.toml
Provide OPENAI_API_KEY through the environment or codex login --api-key. A key written into config.toml leaks easily when the file is shared or backed up.
yolo mode (--yolo) does not belong in config.toml
codex --yolo is documented as an alias of --dangerously-bypass-approvals-and-sandbox. It runs commands with no approval prompts and no sandbox. The docs say to "use caution before doing so", and note that with --yolo or another full access sandbox setting, web search defaults to live results.
It is a per-invocation flag, not something to make permanent in config.toml. To approach it through settings, set approval_policy and sandbox_mode explicitly, and keep that to disposable containers or CI runners. The combinations are covered in Codex approval modes and sandbox.
MCP servers
MCP servers are also configured in config.toml under [mcp_servers.name] with command, args and env.
Checking what is active
/status shows the current model, reasoning effort, approval policy, sandbox and the AGENTS.md files that were loaded. Check it after editing config.toml.
Summary
- Settings live in
~/.codex/config.toml: defaults at the top level, task-specific ones in[profiles.name] - Use names from
/modelformodel, and pickmodel_reasoning_effortper task - Switch with
codex --profile name, or setprofile = "name"as default - Precedence: command-line option > profile > top level > default
FAQ
- Where is config.toml?
- At ~/.codex/config.toml in your home directory. Create it if it does not exist.
- Can I have different settings per project?
- Define profiles and switch with --profile. Some versions also read project-level configuration under .codex/; check the official docs for your version.
- How do I change effort in Codex CLI?
- Set model_reasoning_effort in ~/.codex/config.toml to low, medium, high, xhigh, max or ultra. To change effort for one run pass codex -c model_reasoning_effort='"high"', and during a session run /model.
- What is yolo mode in Codex CLI?
- The docs list --yolo as an alias of --dangerously-bypass-approvals-and-sandbox: it runs without approval prompts or the sandbox. Keep it to disposable containers, not your host machine.
Questions & answers
Q. My Codex PreToolUse hook calls sys.exit(2) but nothing is blocked on Windows — the command runs anyway, and PowerShell seems to turn exit 2 into 1. Is there a way to deny reliably?
Codex documents two ways for a PreToolUse hook to signal a block. Use the one that does not depend on the exit code and a shell rewriting it stops mattering.
Option 1 (exit code): the documentation says "You can also use exit code 2 and write the blocking reason to stderr." The word also is a hint that this is the secondary form.
Option 2 (JSON on stdout): emit a hookSpecificOutput object. This works at exit 0.
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Production config files cannot be modified"
}
}
The docs also accept an older form with a top-level decision set to "block" and a reason string. Note that for PreToolUse, "Plain text on stdout is ignored" — it has to be JSON.
There is also a Windows-specific command override. Hook configuration takes commandWindows (written command_windows in TOML), documented as "an optional Windows-only command override". The managed-hooks example uses py -3 against a script path as its Windows command. If a shell difference is what mangles your exit code, that is the right place to put an invocation that preserves it.
Which shell runs a hook is not documented
The official hooks page says only that commands "run with the session cwd as their working directory"; it does not name the shell, and it never mentions PowerShell. So "Windows PowerShell 5.1 turns exit 2 into 1" could not be confirmed in the official documentation. That uncertainty is itself the argument for the JSON form: it does not depend on how the exit code travels.
Hooks also have to be enabled. The configuration reference describes features.hooks as "Enable lifecycle hooks loaded from hooks.json or inline [hooks] config".
More detail: What you can configure in Codex's config.toml.
Primary sources
This article was drafted by AI from official documentation and reviewed by the site operator before publishing. Found a mistake? Let us know via the contact page.