Codex config.toml: set the model, model_reasoning_effort (low to ultra) and per-task profiles

Codex Published: Updated:

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

Verified on Oct 18, 2026 These tools change quickly. Please also check the latest official documentation. How articles are researched and verified
Contents
  1. Location and structure
  2. Model and reasoning effort
    1. How to change effort in Codex CLI
  3. Profiles for different tasks
  4. Setting a default profile
  5. Precedence
  6. Other useful keys
    1. yolo mode (--yolo) does not belong in config.toml
  7. MCP servers
  8. Checking what is active
  9. Summary

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 model and model_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

KeyExampleMeaning
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 refactors
  • medium: everyday development
  • high: 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 toDo this
Change it permanentlySet model_reasoning_effort in ~/.codex/config.toml
Change it for one runcodex -c model_reasoning_effort='"high"' "<your prompt>"
Change it mid-sessionRun /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:

  1. Command-line options (--model, --sandbox, ...)
  2. The profile selected with --profile
  3. Top-level values in config.toml
  4. 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 /model for model, and pick model_reasoning_effort per task
  • Switch with codex --profile name, or set profile = "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?

Answer by the editorsSource: GitHub openai/codex Issue #54072

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.