- Book: AI Agents Pocket Guide
- Also by me: Thinking in Go (2-book series) — Complete Guide to Go Programming + Hexagonal Architecture in Go
- My project: Hermes IDE | GitHub — an IDE for developers who ship with Claude Code and other AI coding tools
- Me: xgabriel.com | GitHub
In Claude Code, -p means print: run the prompt, write the answer, exit. In Codex CLI, -p is --profile, so codex -p "fix the flaky test" asks for a config profile with that name. -c continues your last conversation in Claude Code. In Codex it sets a config key.
If you run both agents every day, your fingers will pick the wrong one sooner or later. So here are 18 tasks, the Claude Code way and the Codex way, each with a command you can paste. Every row matches the Claude Code CLI reference and the Codex command reference as of October 14, 2026. I haven't run these commands myself, and both tools ship often, so when a flag here disagrees with the docs, the docs win.
Headless runs and output for scripts
| # | Task | Claude Code | Codex CLI |
|---|---|---|---|
| 1 | Run one prompt and exit | claude -p "<task>" |
codex exec "<task>" |
| 2 | Read the prompt from stdin | pipe into claude -p "<task>"
|
pipe into codex exec -
|
| 3 | Machine-readable output |
--output-format json or stream-json
|
--json (JSON Lines events) |
| 4 | Final answer into a file | redirect stdout | -o <file> |
| 5 | Output that matches a schema | --json-schema '<json>' |
--output-schema <file> |
# 1. one shot
claude -p "Summarize what src/auth does"
codex exec "Summarize what src/auth does"
# 2. stdin
cat build-error.txt | claude -p "explain the root cause"
cat prompt.txt | codex exec -
# 3 + 4. JSON for scripts, final message to a file
claude -p "List the TODOs" --output-format json | jq -r '.result'
codex exec --json "List the TODOs" > events.jsonl
codex exec -o todos.txt "List the TODOs"
Claude's json format is one object with the answer in result, plus session_id and total_cost_usd, per its headless guide. Codex's --json streams events instead: thread.started, turn.started, turn.completed, turn.failed, item.* and error, per its non-interactive docs. If you only want Codex's last message, -o is shorter than parsing the stream. The examples pipe into jq.
For row 5, one schema file works for both. Claude takes the schema inline, Codex takes a path:
{
"type": "object",
"properties": {
"functions": { "type": "array", "items": { "type": "string" } }
},
"required": ["functions"],
"additionalProperties": false
}
claude -p "Extract the function names from auth.py" \
--output-format json \
--json-schema "$(cat schema.json)" | jq '.structured_output'
codex exec "Extract the function names from auth.py" \
--output-schema ./schema.json -o names.json
Two defaults differ, and they bite in CI. codex exec runs in a read-only sandbox, so a task that edits files needs row 11. A claude -p run with no permission mode set takes the built-in starting mode, which can be auto, so pass the mode you want.

Same keys, different jobs: -p and -c mean different things in the two CLIs.
Resume and continue
| # | Task | Claude Code | Codex CLI |
|---|---|---|---|
| 6 | Continue the latest session here | claude -c |
codex resume --last |
| 7 | Open a specific session |
claude -r (picker) or claude -r <id or name>
|
codex resume (picker) or codex resume <id>
|
| 8 | Scripted follow-up | claude -p "<task>" --resume "$id" |
codex exec resume --last "<task>" |
# 6. pick up where you left off, in this directory
claude -c
codex resume --last
codex resume --last --all # latest from any directory
# 7. a specific session
claude -n auth-refactor # name it when you start
claude -r auth-refactor # come back to it later
codex resume # picker
codex resume --include-non-interactive
# 8. scripted follow-up
id=$(claude -p "Find N+1 queries in src/" \
--output-format json | jq -r '.session_id')
claude -p "Rank them by impact" --resume "$id"
codex exec "Find N+1 queries in src/"
codex exec resume --last "Rank them by impact"
claude -c skips sessions started with -p, and claude -p --continue includes them (CLI reference). codex resume --last looks only in the current directory unless you add --all, and both the codex resume picker and its --last leave out codex exec sessions unless you add --include-non-interactive (Codex reference). That filter is on codex resume only: codex exec resume --last, used in row 8, is the scripted path and picks up exec runs (non-interactive docs). codex exec resume also takes a session name in place of the ID.
Model, effort and approvals
| # | Task | Claude Code | Codex CLI |
|---|---|---|---|
| 9 | Pick the model | --model opus |
-m <model> |
| 10 | Reasoning effort | --effort high |
-c model_reasoning_effort='"high"' |
| 11 | Let it edit files | --permission-mode acceptEdits |
--sandbox workspace-write |
| 12 | No permission prompts | --dangerously-skip-permissions |
--yolo |
# 9 + 10. model and effort for one session
claude --model opus --effort high
codex -m gpt-6.1-sol -c model_reasoning_effort='"high"'
# 11. let it edit, headless
claude -p "Apply the lint fixes" --permission-mode acceptEdits
codex exec --sandbox workspace-write "Apply the lint fixes"
# 12. only inside a throwaway container or VM
claude --dangerously-skip-permissions
codex --yolo
Claude Code takes aliases (sonnet, opus, haiku, fable) or a full model name. gpt-6.1-sol is the example model in Codex's own config docs, so swap in a model your account can use.
Effort is where the two differ most. Claude's --effort accepts low, medium, high, xhigh, max or ultracode, depending on the model, and lasts for that session only. The Codex reference lists no effort flag, so you set the model_reasoning_effort key, whose documented values include low through xhigh, max and ultra, again depending on the model. Codex parses -c values as TOML and falls back to a plain string, and the extra quotes are the form its advanced config page uses. Inside a session, Claude has /model and /effort, and Codex's /model picks both, where the model supports effort.
Claude's acceptEdits writes files without asking and auto-approves common filesystem commands such as mkdir, touch, mv and cp. Apart from read-only commands, other shell commands still need an allow rule (headless guide).
Codex splits the decision in two: --sandbox (read-only, workspace-write, danger-full-access) sets what commands can touch, and --ask-for-approval sets when it stops to ask. If your muscle memory types -a untrusted or -a on-failure, the config reference now lists untrusted as unsupported and on-failure as deprecated. Use on-request or never.
Claude Code has an OS-level sandbox for shell commands as well, but it is off by default: run /sandbox to turn it on (macOS, Linux and WSL2).
For row 12, --dangerously-skip-permissions equals --permission-mode bypassPermissions, and Codex's reference says to use --yolo "only inside an externally hardened environment".
MCP servers, instruction files and config
| # | Task | Claude Code | Codex CLI |
|---|---|---|---|
| 13 | Add a local (stdio) MCP server | claude mcp add <name> -- <cmd> |
codex mcp add <name> -- <cmd> |
| 14 | Add a remote (HTTP) MCP server | claude mcp add --transport http <name> <url> |
codex mcp add <name> --url <url> |
| 15 | Project instructions | CLAUDE.md |
AGENTS.md |
| 16 | Config files |
~/.claude/settings.json, .claude/settings.json
|
~/.codex/config.toml, .codex/config.toml
|
| 17 | Override config for one run | --settings <file or json> |
-c key=value or --profile <name>
|
# 13. the same server in both agents
claude mcp add context7 -- npx -y @upstash/context7-mcp
codex mcp add context7 -- npx -y @upstash/context7-mcp
# 14. a remote server
claude mcp add --transport http notion https://mcp.notion.com/mcp
codex mcp add notion --url https://mcp.notion.com/mcp
claude mcp list
codex mcp list
In both tools, everything after -- is the command that starts the Context7 server in the example. Claude's default scope is local, meaning this project only, stored in ~/.claude.json. Add --scope user for every project, or --scope project to write a .mcp.json your team commits (Claude MCP docs). Codex keeps MCP servers in config.toml with the rest of its settings, ~/.codex/config.toml by default, and a project's .codex/config.toml can add servers only once you trust that project (Codex MCP docs).
For row 15 you can keep one file. Codex reads AGENTS.md from your Codex home, then from the project root down to your working directory, and stops at 32 KiB by default (AGENTS.md docs). Claude Code v2.1.277 and later reads AGENTS.md directly, but only when there is no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md in your working directory or above it. Your ~/.claude/CLAUDE.md doesn't count (memory docs). If you already have a CLAUDE.md, put this line at the top:
@AGENTS.md
/init exists in both and writes each agent's own file: CLAUDE.md for Claude, an AGENTS.md scaffold for Codex.
For rows 16 and 17, Claude Code's precedence runs from managed settings, through --settings, .claude/settings.local.json and .claude/settings.json, down to ~/.claude/settings.json (settings docs). Codex reads .codex/config.toml only in trusted projects, and a profile is now its own file next to config.toml (config basics):
# ~/.codex/ci.config.toml
model_reasoning_effort = "low"
approval_policy = "never"
sandbox_mode = "read-only"
claude -p "Check for type errors" --settings ./ci-settings.json
codex exec --profile ci "Check for type errors"
If you still have [profiles.ci] tables inside config.toml, Codex 0.134.0 and later no longer reads them, per the advanced config page. Move each one into its own file.
Worktrees, and both agents side by side in Hermes
| # | Task | Claude Code | Codex CLI |
|---|---|---|---|
| 18 | Start in a fresh git worktree | claude -w <name> |
codex --worktree |
claude -w fix-login # .claude/worktrees/fix-login
codex --worktree "Fix the flaky login test"
Claude puts the worktree at <repo>/.claude/worktrees/<name>. Codex starts "in a new managed Git worktree", and codex exec --worktree can't be combined with resume (Codex reference). Each agent manages its own, so running both still leaves you with two sets of worktrees and two terminals to watch.
I build Hermes IDE, so weigh this section with that in mind. Hermes runs each agent's own interface in a real terminal, so the slash commands above work there unchanged, and a plain shell session runs the headless commands from the tables. Press ⌘N (Ctrl+Shift+N on Windows and Linux) and describe the task. Hermes starts the agent on its own hermes/<name> branch in its own worktree, with the task as the first prompt. You pick the agent, model, effort and account per task. Do it once for Claude Code and once for Codex, and each works in its own checkout, on its own branch.

The ⌘N New task sheet in Hermes 2.3: Claude Code on a new hermes/ worktree with Accept edits, the extra-folder chips, and the "Hermes will run" preview of the claude command.
Then put them next to each other. Split right with ⌘D (Ctrl+Shift+D), or down with ⌘⇧D (Ctrl+Shift+S), and move between panes with ⌘⌥→ (Alt+→), per the shortcuts list. When one of them stops for an approval, ⌘I (Ctrl+Shift+I) jumps to the agent that has waited longest, and you answer in that agent's own terminal. Hermes never answers a permission prompt for you.
Hermes is free, source-available under BSL 1.1, and runs on macOS, Windows and Linux. The latest release, 2.3.3, shipped on October 13, 2026. It is not affiliated with Anthropic, OpenAI or Nous Research.
If this was useful
Keep the tables open the next time you switch agents mid-task, and download Hermes IDE if you want Claude Code and Codex in split panes on separate worktrees. If it saves you a mix-up, a star on GitHub helps other developers find it. For the patterns underneath these flags, such as approval gates, sandboxes and resumable agent loops, the AI Agents Pocket Guide is the short read.

Top comments (0)