Configuring OpenAI Codex CLI
OpenAI Codex CLI is OpenAI’s open-source Rust agent. It is distinct from the deprecated 2021 OpenAI Codex API. The current tool ships under @openai/codex on npm and uses GPT-5 codex-family models.
This page walks through the configuration you will customise most often.
Install and authenticate
Section titled “Install and authenticate”npm install -g @openai/codexOther paths: brew install --cask codex, or download a prebuilt binary from the GitHub releases. System requirements: macOS, Linux, or Windows with PowerShell or WSL2.
Two authentication methods, switchable any time:
codex login # ChatGPT Plus / Pro / Businesscodex login --api-key # paste an OpenAI API key (prompted on stdin)codex logout # clear credentialsChatGPT login is the typical default. The API-key path is required for some headless and CI workflows. The /logout slash command works mid-session.
Model selection
Section titled “Model selection”Codex defaults change between ChatGPT and API auth. Set explicitly in three places:
codex -m gpt-5.4 # one-offcodex --config model='"gpt-5.3-codex"' # one-off, full config overridemodel = "gpt-5.4"model_reasoning_effort = "high" # minimal | low | medium | high | xhighmodel_verbosity = "concise"Common identifiers as of 2026: gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.3-codex. Verify against /model because OpenAI rotates these.
Project memory: AGENTS.md
Section titled “Project memory: AGENTS.md”Codex pioneered the AGENTS.md convention several other agents have since adopted. The discovery walks from the working directory up to the project root marker (.git, .hg, .sl).
Filename precedence per directory: AGENTS.override.md then AGENTS.md then a fallback list configured by project_doc_fallback_filenames.
Loading order, concatenated with blank lines between:
~/.codex/AGENTS.md(global)- Project-root
AGENTS.md - Each directory between root and current working directory
- Current directory
Closer-to-cwd files appear later, so they override earlier guidance.
A starter AGENTS.md for a bioinformatics project:
# Project
Single-cell RNA-seq atlas integration across three studies.
## Build and test
- Env: `uv sync`- Run pipeline: `uv run python -m sc_atlas.cli`- Tests: `uv run pytest`
## Conventions
- Reference assembly: GRCh38, Ensembl 110.- Single-cell workflow: follow `single-cell-best-practices.org`, not bare scanpy.- Pipeline orchestration: nf-core/scrnaseq when an nf-core option exists.- All R code runs in the Bioconductor container, not on the host.- Add Python deps with `uv add`; never `pip install`.Truncated at project_doc_max_bytes (default 32 KiB).
Config file: config.toml
Section titled “Config file: config.toml”Location: ~/.codex/config.toml (override the home directory with the CODEX_HOME env var). Project overlays go at <repo>/.codex/config.toml and load only for trusted projects.
A representative config.toml:
model = "gpt-5.4"model_reasoning_effort = "medium"sandbox_mode = "workspace-write"approval_policy = "on-request"
[sandbox_workspace_write]network_access = falsewritable_roots = ["/tmp/codex"]
[shell_environment_policy]inherit = "core"exclude = ["AWS_*", "OPENAI_API_KEY"]
[features]codex_hooks = true
profile = "default"
[profiles.deep-review]model = "gpt-5.4"model_reasoning_effort = "high"approval_policy = "never"sandbox_mode = "read-only"Profiles let you switch behaviour on demand:
codex --profile deep-reviewThe full JSON schema is at https://developers.openai.com/codex/config-schema.json.
Sandbox and approvals
Section titled “Sandbox and approvals”Three sandbox modes:
| Mode | Read | Write | Network |
|---|---|---|---|
read-only |
Anywhere | None | No |
workspace-write (default) |
Anywhere | CWD plus /tmp |
Off by default |
danger-full-access |
Anywhere | Anywhere | Yes |
Within workspace-write, the .git, .codex, and .agents directories stay read-only by default to protect repository state.
Approval policies:
| Policy | When Codex prompts |
|---|---|
untrusted |
Every action |
on-request (default) |
When the model asks for elevated access |
on-failure |
After a sandboxed action fails |
never |
Never (combine with read-only for safety) |
Implementation per platform: macOS Seatbelt, Linux bwrap (bubblewrap) with optional AppArmor on Ubuntu 25.04+, Windows native sandbox or WSL2.
codex --sandbox workspace-write --ask-for-approval on-requestcodex --sandbox read-only --ask-for-approval never # safe browsingcodex --yolo # disables both, use with careEnable network and extend writable paths in config.toml:
sandbox_mode = "workspace-write"
[sandbox_workspace_write]network_access = truewritable_roots = ["/Users/me/.pyenv/shims"]Custom commands and skills
Section titled “Custom commands and skills”Codex shipped slash-command “custom prompts” stored in ~/.codex/prompts/. These are now deprecated in favour of Skills, which Codex can call explicitly or implicitly.
Skill paths and frontmatter syntax are evolving. Check the latest on the Codex CLI features page before relying on a specific format. Useful built-in slash commands include /model, /permissions, /agent, /plan, /diff, /review, /mcp, /compact.
MCP servers
Section titled “MCP servers”Configured under [mcp_servers.<id>] tables. Both stdio (command) and HTTP (url) transports are supported.
[mcp_servers.filesystem]command = "npx"args = ["-y", "@modelcontextprotocol/server-filesystem", "/data"]enabled = truestartup_timeout_sec = 30enabled_tools = ["read_file", "list_directory"]
[mcp_servers.docs]url = "https://mcp.example.com/sse"Manage with the codex mcp subcommand. Inspect from inside a session with /mcp.
Stable as of recent releases. Enable with [features] codex_hooks = true and define in ~/.codex/hooks.json or inline in config.toml.
Events:
SessionStart(matchers:startup,resume,clear)UserPromptSubmitPreToolUse(matcher = tool-name regex, can return allow or deny)PermissionRequestPostToolUseStop
Example: log every Bash invocation.
[features]codex_hooks = true
[[hooks.PreToolUse]]matcher = "^Bash$"
[[hooks.PreToolUse.hooks]]type = "command"command = "/usr/bin/python3 ~/.codex/hooks/log_bash.py"timeout = 5statusMessage = "Logging command"Hook scripts get JSON on stdin (session_id, cwd, hook_event_name, model, plus turn_id for turn-scoped events). Exit 0 is OK, exit 2 is a blocking decision with the reason on stderr.
Headless mode
Section titled “Headless mode”codex exec runs a one-shot prompt without the TUI. Useful in CI and shell pipelines.
codex exec --sandbox workspace-write \ "refactor scripts/load_counts.py to use polars instead of pandas"
codex exec --json \ "run pytest and summarise failures" > out.jsonl
codex exec --output-last-message reply.md \ "summarise the last commit"
codex exec resume <SESSION_ID> "follow-up prompt"Other useful exec subcommands: --ephemeral, --ignore-rules, plus the global flags --model, --profile, --sandbox, --ask-for-approval, --cd, --config.
Bioinformatics-flavoured config
Section titled “Bioinformatics-flavoured config”A workstation ~/.codex/config.toml aimed at bioinformatics looks like:
model = "gpt-5.4"model_reasoning_effort = "high"sandbox_mode = "workspace-write"approval_policy = "on-request"
[sandbox_workspace_write]network_access = falsewritable_roots = ["/tmp/codex", "/scratch"]
[shell_environment_policy]inherit = "core"exclude = ["KAGGLE_API_TOKEN", "OPENAI_API_KEY"]
[mcp_servers.filesystem]command = "npx"args = ["-y", "@modelcontextprotocol/server-filesystem", "/data/refs"]
[features]codex_hooks = trueThe shell_environment_policy excludes secret env vars from the agent’s process so an accidental env in a shell command does not leak them.
Gotchas
Section titled “Gotchas”- Skills are evolving: the older
~/.codex/prompts/markdown commands are deprecated. Verify the current Skills format against the official docs before relying on it. - Project trust: project-level
config.tomlonly loads in trusted projects. Codex prompts the first time you run in a new repo. web_searchconfig: appears twice in older docs with different shapes. The current top-levelweb_search = "disabled" | "cached" | "live"form is correct; the[features] web_searchform is deprecated.- Hook return codes: same convention as Claude Code: exit
0to allow, exit2to deny with a stderr reason.