skip to content

Codex CLI Overview

Install and use OpenAI's Codex CLI — the open-source agentic coding tool. Covers authentication, interactive mode, headless exec, ~/.codex/ layout, and AGENTS.md project memory.

10 min read 52 snippets deep dive

Codex CLI Overview#

What it is#

Codex CLI (github.com/openai/codex) is OpenAI’s open-source agentic coding tool that runs GPT models directly in your terminal. It reads and edits files, executes shell commands, and coordinates multi-step coding tasks through natural-language instructions — either interactively in a TUI or non-interactively via codex exec. Configured entirely through ~/.codex/config.toml, with per-project memory in AGENTS.md files.


Install#

Codex CLI ships as a self-contained binary plus an npm wrapper. The npm install is the simplest cross-platform path; Homebrew is the cleanest on macOS; the GitHub-released prebuilt binaries are the fastest path on a server without Node installed. Whichever channel you choose, the resulting codex binary is identical in capability.

npm (cross-platform)#

npm install -g @openai/codex

Output: (none — installs globally, then codex --version confirms)

Homebrew (macOS)#

brew install --cask codex

Output: (none — downloads pre-built binary)

Prebuilt binaries#

Download from GitHub Releases (github.com/openai/codex/releases). Available for:

  • macOS arm64 / x86_64
  • Linux musl x86_64 / arm64
curl -L https://github.com/openai/codex/releases/latest/download/codex-linux-x86_64 -o ~/.local/bin/codex
chmod +x ~/.local/bin/codex

Output: (none — exits 0)

Verify installation#

codex --version

Output:

codex 0.x.x

Authentication#

Codex supports two authentication paths: a browser-based ChatGPT subscription login (recommended for individuals on a Plus/Pro/Business plan) and direct OPENAI_API_KEY usage (recommended for CI, servers, and shared automation). Credentials are stored in ~/.codex/auth.json after a successful codex login; the API key path bypasses the file entirely and reads the env var on every invocation.

Requires a ChatGPT Plus, Pro, Business, Edu, or Enterprise subscription. No API key needed.

codex login

Output:

Opening browser for authentication…
Logged in as user@example.com

API key#

export OPENAI_API_KEY="sk-..."
codex

Output: (interactive session opens)

Log out#

codex logout

Output:

Logged out.

Check current auth status#

Print the active authentication identity. Useful when scripts behave differently than expected — confirms which login (ChatGPT vs. API key) Codex is currently using.

codex whoami

Output:

Logged in as user@example.com (chatgpt-plus)

Interactive mode#

The interactive TUI is Codex’s primary surface — a streaming chat REPL with file-aware autocomplete, slash-command popup, sandboxed execution, and live diff previews. Launch it with bare codex to drop into the current directory, or pass an initial prompt as an argument to skip the welcome screen.

Start a session in the current directory:

codex

Output: (TUI opens — enter a task at the prompt)

Change the working directory at launch:

codex --cd /path/to/repo

Output: (TUI opens in specified directory)

Run with a specific model:

codex -m gpt-4o

Output: (TUI opens using gpt-4o)

Run with --full-auto (workspace-write sandbox, on-request approvals — see Approvals & Sandbox):

codex --full-auto

Output: (TUI opens in full-auto mode)

Attach an image to the initial prompt:

codex -i screenshot.png "Fix the layout issue shown in this screenshot"

Output: (TUI opens with image attached to first turn)


Pass an initial prompt directly (skips the welcome screen):

codex "Refactor the auth module to use JWT tokens"

Output: (TUI opens and immediately begins working on the prompt)


Non-interactive (exec) mode#

codex exec runs a single task end-to-end and exits — no TUI, no human prompts (unless --ask-for-approval is enabled). It is the primary surface for git hooks, CI pipelines, shell scripts, and editor integrations. See the dedicated exec mode page for the full reference.

Run a task and exit. Useful for scripting and CI pipelines.

codex exec "Add a docstring to every public function in src/"

Output:

[agent output and diffs printed to stdout]

Emit structured NDJSON event stream:

codex exec --json "Run the test suite and summarise failures"

Output:

{"type":"agent-turn-start","turn-id":"t_01"}
{"type":"tool-call","name":"shell","input":{"cmd":"pytest"}}
{"type":"tool-result","name":"shell","output":"..."}
{"type":"agent-turn-complete","last-assistant-message":"..."}

Print only the final assistant message:

codex exec --output-last-message "What does this repo do?"

Output:

This repository implements a REST API for …

Skip git-repo check (e.g., for scratch directories):

codex exec --skip-git-repo-check "Create a hello-world Flask app"

Output: (agent output)


Read a prompt from stdin (useful for piping diffs and other large context):

git diff HEAD~5 | codex exec --output-last-message "Summarise these commits"

Output:

The last 5 commits add JWT auth, refactor the DB pool, fix a flaky test, and bump deps.

Session management#

Every Codex session is assigned a thread ID and persisted under ~/.codex/history/ (unless [history] persistence = "no-save"). You can resume the most recent session, jump back to a named session by ID, or fork a session to branch off without overwriting history. Resume restores the exact context — file changes already on disk are kept, but uncommitted diffs from the previous turn are not rolled back.

Resume the most recent session:

codex resume

Output: (TUI opens at previous session)

Resume a specific session by ID:

codex resume <SESSION_ID>

Output: (TUI opens at that session)

Fork a session (branch a new session from a past point):

codex fork <SESSION_ID>

Output: (TUI opens a new session forked from the given one)


List recent sessions (TUI picker):

codex sessions

Output:

th_01abc  2026-05-25 14:02  myproject  "Refactor auth module"
th_01xyz  2026-05-24 18:11  myproject  "Add unit tests"
th_01def  2026-05-23 09:47  notes      "Outline blog post"

Remote and cloud modes#

Codex supports two flavours of remote execution: --remote connects the local TUI to an arbitrary Codex app server over WebSocket (useful for shared dev environments and SSH-less remote pairing), while codex cloud submits a task to OpenAI-managed infrastructure that runs the agent in their own sandboxes and streams diffs back. Cloud is ideal for very long-running migrations where you don’t want to keep your laptop awake.

Connect to a remote Codex app server (WebSocket):

codex --remote wss://your-server/ws

Output: (TUI connects to remote agent)

Run tasks in the cloud (OpenAI-managed infra):

codex cloud "Refactor the auth module"

Output: (task submitted; stream results to stdout)


Apply a completed cloud task’s diff locally:

codex apply tsk_abc123

Output:

Applying patch from task tsk_abc123…
4 files modified, 1 file created.

Global flags reference#

FlagShortDescription
--model <model>-mOverride the model for this session
--sandbox <mode>-sSet sandbox mode (read-only, workspace-write, danger-full-access)
--ask-for-approval <policy>-aOverride approval policy
--config <path>-cUse an alternate config file
--full-autoworkspace-write sandbox + on-request approvals
--cd <dir>-CStart in this directory
--image <path>-iAttach image to the initial prompt
--profile <name>-pUse a named profile from config.toml
--searchEnable live web search during the session

Environment variables#

VariableEffect
OPENAI_API_KEYAPI key for non-ChatGPT auth
CODEX_HOMEOverride base dir (default ~/.codex)
CODEX_LOG_LEVELtrace | debug | info | warn | error
CODEX_NO_TELEMETRYSet to 1 to disable usage telemetry
EDITOREditor used by /edit and file_opener fallback
HTTP_PROXY / HTTPS_PROXYOutbound proxy for API calls
NO_PROXYHosts to bypass the proxy
export CODEX_HOME=/srv/shared-codex
export CODEX_LOG_LEVEL=debug
codex --version

Output:

codex 0.x.x

~/.codex/ layout#

~/.codex/
├── config.toml        # Main user configuration
├── auth.json          # OAuth tokens (created by `codex login`)
├── history/           # Persisted session transcripts
├── logs/              # Diagnostic logs (when CODEX_LOG_LEVEL is set)
└── hooks.json         # Optional global hooks (experimental)

Project-level override (loaded when in a trusted project):

<project-root>/.codex/
├── config.toml        # Project-specific overrides
└── AGENTS.md          # (also discovered at repo root as AGENTS.md)

AGENTS.md#

AGENTS.md is Codex’s per-project instruction file — a plain Markdown document describing build commands, file layout, conventions, and off-limits paths. Codex auto-discovers AGENTS.md by walking the directory tree from the cwd upward, merging all found files (closest wins for conflicts). Scaffold one in the current directory:

codex
# then type: /init

Output: (AGENTS.md created in current directory)

Typical sections to include:

# Project: my-api

## Build & test
- Install: `pip install -e ".[dev]"`
- Tests: `pytest -x`
- Lint: `ruff check . && mypy src/`

## Conventions
- Docstrings: Google style
- Line length: 100
- No print() in library code — use logging

## Off-limits
- Never edit migrations directly; run `alembic revision --autogenerate` instead

Key differences from Claude Code#

FeatureCodex CLIClaude Code
Config file~/.codex/config.toml (TOML)~/.claude/settings.json (JSON)
Project memoryAGENTS.mdCLAUDE.md
AuthChatGPT plan or API keyAPI key / Anthropic Console plan
SandboxingOS-native (Seatbelt / bwrap+seccomp)Permission-prompt based
HooksExperimental ([features] codex_hooks = true)Stable (PreToolUse/PostToolUse/Stop)
Slash commands30+ (TUI-focused)~25 (workflow-focused)
Remote/cloudcodex cloud, codex --remoteNot built-in
Sub-agentsExperimental /agentTask tool (stable)
MCP setupTOML-onlyclaude mcp add CLI + JSON

Common pitfalls#

  1. Untrusted projects silently ignore .codex/config.toml. A project’s .codex/config.toml is only loaded when [projects."<path>"] trust_level = "trusted" is set in ~/.codex/config.toml. If a project’s local overrides “don’t seem to work,” check codex /debug-config to confirm whether the project is trusted.

  2. codex (bare) inherits the cwd, not the project root. If you launch Codex from a subdirectory of your repo, it begins there. AGENTS.md discovery still walks upward, but the sandbox workspace-write boundary defaults to that subdirectory. Use --cd /path/to/repo or move to the repo root before launching.

  3. workspace-write blocks outbound network by default. A surprising number of build steps (npm install, pip install, go mod tidy) need network. Either run them yourself before invoking Codex, or pass --sandbox danger-full-access for that session (inside a disposable container).

  4. The auth.json token expires. ChatGPT login refreshes silently most of the time, but if Codex returns 401 on every call, run codex login again to refresh.

  5. codex exec ignores approval_policy = "on-request". In non-interactive mode the effective default is "never". Pass --ask-for-approval on-request if you want a pipe-and-wait behaviour, but be aware it will hang in CI.

  6. -i image.png requires a vision-capable model. Older gpt-4o-mini deployments accept the image but emit an error after the first turn. Use gpt-4o, gpt-5, or any model whose card explicitly lists “vision” support.

  7. codex resume does NOT roll back files on disk. A resumed session sees the current state of the filesystem, not the state at the previous turn. Use git stash/git restore to roll back disk state before resuming.


Real-world recipes#

One-shot fixer in a pre-push hook#

A safe, idempotent fixer that runs in the workspace-write sandbox before every push. Catches forgot-to-format and forgot-to-lint mistakes without touching files outside the cwd.

# .git/hooks/pre-push (chmod +x)
#!/usr/bin/env bash
codex exec --full-auto -p ci "Run ruff format and ruff check --fix on staged files"
git add -u

Output:

[agent] Running ruff format src/…
[agent] Running ruff check --fix src/…
[agent] No further changes required.

Read-only daily standup summary#

Walk through the git log and open PRs for the day; produce a 3-bullet standup brief. Read-only sandbox guarantees no files are touched.

codex exec --sandbox read-only --ask-for-approval never \
  "Summarise yesterday's commits and open PRs as 3 bullets for standup."

Output:

- Merged PR #142 (auth refactor — JWT cookies).
- Opened PR #145 (rate-limit middleware, awaits review).
- Fixed flaky test in tests/test_auth.py::test_refresh_token.

Two-pane workflow — TUI + watcher#

Run the agent in one terminal and tail its log in another. Useful for debugging hooks and MCP servers.

# Terminal 1
CODEX_LOG_LEVEL=debug codex

# Terminal 2
tail -F ~/.codex/logs/codex.log

Output:

[debug] mcp-server filesystem started (pid=4421)
[debug] tool-call shell {"cmd":"pytest -x"}
[debug] sandbox-policy workspace-write granted

Quick aliases#

# ~/.zshrc or ~/.bashrc
alias cx='codex exec --full-auto'
alias cxr='codex exec --sandbox read-only --ask-for-approval never'
alias cxp='codex --profile sprint'

Output: (none — defines shell aliases)

Then:

cxr "What does this repo do?"

Output:

This repository is a personal cheat-sheet site built with Astro 4 …

Switch ChatGPT account between projects#

If you have multiple ChatGPT accounts (personal + work), set CODEX_HOME per project so each gets its own auth.json:

# ~/.zshrc
function cx-work() { CODEX_HOME="$HOME/.codex-work" codex "$@" }
function cx-personal() { CODEX_HOME="$HOME/.codex-personal" codex "$@" }

Output: (none — defines shell functions)

Each function uses a separate auth file, profile set, and history directory.