Migrating from Claude Code to Codex is mostly a rename-and-reformat job, and Codex now ships a one-command importer that does most of it for you. The trouble hides in what it leaves behind — and one item in there is not a config file at all.
The two tools solve the same problem with different file dialects. Claude Code leans on JSON and Markdown; Codex leans on a single TOML file plus AGENTS.md. The migration is largely a translation between those two dialects, with one structural mismatch that most guides skip.
This walkthrough maps every config surface, names the one that genuinely breaks, and gives you the vendor-neutral fix for the only dead end: keeping the Anthropic models you migrated for.
Versions this guide was tested against: Codex CLI 0.142.5 (July 1, 2026) and Claude Code 2.1.178. If you are on an older Codex, upgrade first — the /import command did not exist before 0.140.0.
30-Second Verdict
30-Second Migration Verdict
You can move nearly your whole Claude Code setup to Codex in about 20 minutes. Here is the decision before you scroll:
| Question | Answer |
|---|---|
| Can most of my config move? | Yes. 9 of 12 surfaces transfer or reshape cleanly. |
| Fastest path? | Run codex → /import (Codex 0.140+), then hand-fix 3 items. |
| What auto-transfers? | Memory files, MCP servers, skills, slash commands, custom endpoints. |
| What needs manual work? | The permissions model, hooks format, and subagent wrappers. |
| The one dead end? | Anthropic Claude models. Vanilla Codex is OpenAI-only. |
| The fix for the dead end? | Register a gateway as a model_provider and keep running Claude inside Codex. |
Surface Map
What You Can Move Today (And What You Can't)
Almost everything moves, because the two tools solve the same problem with different file formats. The migration is largely a translation between two dialects.
What you can move:
- Repo and personal instructions (CLAUDE.md content)
- MCP servers, verbatim command and args
- Skills, which already follow the shared Agent Skills convention
- Slash commands and reusable prompts
- Custom API endpoints and keys
What you cannot move without a workaround:
- Claude Code's per-command permission allowlist, which has no direct Codex analog
- The ConfigChange hook event (Codex has PreCompact/PostCompact, but nothing that fires on a config-file change)
- Output styles, which Codex does not model
- The Anthropic models themselves — the real blocker and the reason for the last section
Here is the full surface map. Save this table; it is the whole migration in one screen.
| # | Claude Code | Codex equivalent | Verdict |
|---|---|---|---|
| 1 | CLAUDE.md memory | AGENTS.md (or fallback filename) | Transfers |
| 2 | .mcp.json (JSON) | [mcp_servers.*] in config.toml | Transfers, reformat |
| 3 | .claude/skills/ | Codex skills ([[skills.config]]) | Transfers |
| 4 | .claude/commands/ | Codex slash commands / prompts | Transfers, re-author |
| 5 | .claude/agents/ (Markdown) | .codex/agents/*.toml files | Reshapes |
| 6 | settings.json (JSON) | config.toml + profiles (TOML) | Reshapes |
| 7 | permissions.allow/ask/deny | approval_policy + sandbox_mode | Breaks |
| 8 | hooks (PreToolUse, Stop, …) | [[hooks.*]] in config.toml | Reshapes |
| 9 | ConfigChange hook | none | No equivalent |
| 10 | ANTHROPIC_BASE_URL endpoint | [model_providers.*] | Transfers |
| 11 | outputStyle | none | No equivalent |
| 12 | Anthropic Claude models | OpenAI models only | Dead end (see fix) |
Rows 9 and 11 are cosmetic. You will not miss outputStyle, and ConfigChange only matters if you built automation that reacts to a config file changing mid-session. Row 12 is the one that stops people, and it has a clean fix most migration guides skip.
Decision Frame
When to Migrate (and When to Stay)
Migrate when your work is task-shaped and you want tighter sandboxing; stay on Claude Code when your work is conversation-shaped and hook-driven. The two tools carry different mental models, and the config differences follow from that.
When to Migrate
- You run agents non-interactively in CI and want a read-only or workspace-write sandbox as the default posture.
- Your team wants one committed config.toml with profiles per risk level, instead of settings.json plus a pile of settings.local.json overrides.
- You want OpenAI's current Codex models (gpt-5.5) as the default driver. The older gpt-5.3-codex was deprecated as a user-selectable Codex model on 2026-05-26, so pick gpt-5.5 or gpt-5.4.
When NOT to Migrate
- You depend on ConfigChange hooks or output styles. Those have no home in Codex, so budget rework or stay put.
- Your whole workflow is a long interactive pairing session. Claude Code's conversational model fits that better than Codex's task-and-review loop.
- You have a large hand-tuned permission allowlist. Codex's coarse sandbox tiers will feel blunt, and porting the intent takes real thought (see Step 5).
The Stop Rule: If your only goal is to try Codex's models against your existing repo, you do not need to migrate config at all. Point Codex at your repo, run /import, and stop. The rest of this guide is for people making Codex their primary tool.
Prerequisites
System Requirements
Before you touch config, confirm the four prerequisites below. A stale Codex is the most common reason /import and the [features] blocks silently do nothing.
- Codex CLI 0.140.0 or newer. Check with codex --version. The /import command landed in 0.140.0; this guide was tested on 0.142.5.
- Your existing Claude Code project, with its .claude/ directory and CLAUDE.md intact. Do not delete it until the migration is verified.
- An API key for whichever provider will drive Codex. OpenAI by default, or a gateway key if you are keeping Claude models.
- Write access to ~/.codex/. Codex reads ~/.codex/config.toml on every invocation and, in trusted projects, .codex/config.toml at the repo root.
The migration path looks like this end to end:
- 1Audit CLAUDE.md + settings.json→
- 2Run codex /import→
- 3Review the conflict report→
- 4Hand-fix permissions + hooks→
- 5Add a model_provider for Claude models→
- 6Test with a read-only profile
Step-by-Step
Mapping Every Config Surface
Run the automated importer first, then walk the five surfaces it cannot fully handle. Do not skip the manual passes — the importer is honest about what it leaves behind, but it does leave things behind.
Step 1: Run the Importer
Start Codex in your project and import. Codex 0.140 added /import for selectively pulling setup, project configuration, and recent chats from Claude Code. Pick the surfaces you want.
cd my-project codex # then, inside the session: /import
Expected result: a populated ~/.codex/config.toml, an AGENTS.md draft, and a short report listing anything it skipped or flagged as a conflict.
Step 2: Instructions, CLAUDE.md to AGENTS.md
Codex reads AGENTS.md, not CLAUDE.md. If the importer did not already create one, either rename your file or tell Codex to keep reading the old name.
# ~/.codex/config.toml project_doc_fallback_filenames = ["AGENTS.md", "CLAUDE.md"] project_doc_max_bytes = 32768
Expected result: your repo-level instructions load into Codex context on the next run. The content carries over unchanged; only the filename and load path differ — which is why the AGENTS.md convention exists across tools in the first place.
Step 3: MCP Servers, JSON to TOML
The MCP processes are identical. Only the declaration changes shape. A Claude Code .mcp.json entry like this:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"]
}
}
}becomes a TOML table in ~/.codex/config.toml:
[mcp_servers.github] command = "npx" args = ["-y", "@modelcontextprotocol/server-github"]
Expected result: codex lists the github MCP tools on startup. If a server needs environment variables, add them inline: env = { "GITHUB_TOKEN" = "..." }. Both transports carry over: Codex accepts the same STDIO command-based servers you ran in Claude Code, and it also takes streaming HTTP servers in the same table, so a remotely hosted MCP endpoint moves without spawning a local process.
Step 4: Subagents to .codex/agents/
Claude Code stores subagents as Markdown in .claude/agents/. Codex stores each subagent as its own TOML file, one file per agent, under ~/.codex/agents/ (personal) or .codex/agents/ (project-scoped). Subagents are enabled by default, so there is no feature flag to flip.
# .codex/agents/reviewer.toml name = "reviewer" description = "Reviews diffs for correctness and style" developer_instructions = """ Review the diff for correctness and style. Cite file and line for each issue. """
Expected result: the reviewer role becomes available through Codex's subagent workflow, which Codex invokes only when you explicitly ask for it. The prompt body from your old Markdown file moves into developer_instructions; the wrapper is what changes. If you had many subagents, this is the most tedious manual pass, but it is mechanical.
Step 5: Permissions to Sandbox and Approval
This is the surface that genuinely breaks, because the two tools model safety differently. Claude Code uses a per-command allowlist with glob rules. Codex uses two coarse dials: a filesystem sandbox and an approval policy. There is no clean one-to-one mapping, so you port intent, not rules.
| Claude Code | Codex intent | Codex setting |
|---|---|---|
| allow: ["Bash(npm run test *)"] | run commands in the repo without asking | sandbox_mode = "workspace-write", approval_policy = "on-request" |
| ask: ["Bash(python *)"] | prompt before risky commands | approval_policy = "on-request" |
| deny: ["Read(./.env)"] | block access outside the workspace | sandbox_mode = "workspace-write" (blocks writes outside cwd) |
| Plan mode | look, do not touch | sandbox_mode = "read-only" |
| --dangerously-skip-permissions | full autonomy | approval_policy = "never", sandbox_mode = "danger-full-access" |
# ~/.codex/config.toml, a sane default
approval_policy = "on-request" sandbox_mode = "workspace-write"
Expected result: Codex runs freely inside the repo and asks before touching anything outside it or reaching the network. The granular per-command control you had in Claude Code does not survive; if you relied on a long, precise allowlist, accept that Codex's model is blunter by design.
Step 6: Hooks
Codex has hooks now, enabled by default, and they cover most of Claude Code's events. You declare them as array-of-tables blocks in config.toml; to turn the whole system off you would set [features] hooks = false.
# ~/.codex/config.toml [[hooks.PreToolUse]] matcher = "^Bash$" # same idea as Claude Code's PreToolUse matcher [[hooks.PreToolUse.hooks]] type = "command" command = "$(git rev-parse --show-toplevel)/.codex/hooks/pre_tool_use.sh"
Expected result: PreToolUse, PostToolUse, SessionStart, Stop, and even PreCompact/PostCompact fire as they did in Claude Code, once you translate the JSON handler into TOML. The one gap is ConfigChange, which has no Codex event — any automation you built to react to a config file changing mid-session is the one part of your hook setup that does not come along.
The Dead End
What Has No Equivalent: Claude Models (and the Fix)
The single migration step with no native answer is keeping your Claude models, because vanilla Codex authenticates against OpenAI and drives OpenAI models such as gpt-5.5 and gpt-5.4. There is no built-in switch that selects Claude Opus or Sonnet. If you migrated to Codex for its sandbox and workflow but still want Opus writing your code, you need a bridge.
The bridge is a custom model_provider. Codex will talk to any OpenAI-compatible gateway, so you register one and point a profile at a Claude model. Add the provider to ~/.codex/config.toml:
# ~/.codex/config.toml — register an OpenAI-compatible gateway
[model_providers.gateway] name = "your gateway" base_url = "https://your-gateway.example/v1" env_key = "GATEWAY_API_KEY" wire_api = "responses" requires_openai_auth = false
Two details trip people up. Both are about how Codex negotiates the wire protocol, not about the gateway itself.
Set wire_api = "responses".
Codex removed support for the older chat protocol in February 2026, so a provider left on wire_api = "chat" now errors on startup. A Responses-compatible endpoint under the same /v1 base URL is what actually connects.
Set requires_openai_auth = false.
This stops Codex from expecting an sk- key prefix, so your gateway's own key format is accepted without friction.
Then create a profile file at ~/.codex/claude.config.toml:
model = "anthropic/claude-opus-4.8" model_provider = "gateway"
Run it with codex --profile claude. Now Codex's task loop and sandbox drive Anthropic's anthropic/claude-opus-4.8, and swapping model = "openai/gpt-5.5" in a second profile lets you A/B the two without changing auth. This is the one migration surface where a gateway is not a convenience but the only way to keep what you came for.
Pricing for any model flows through your chosen gateway at that provider's published rates; FACTA is vendor-neutral and recommends no specific gateway.
Troubleshooting
Common Errors During Migration (and Fixes)
Six failures cover almost every stuck migration. The pattern is the same each time: a Claude Code assumption that Codex does not share.
| Symptom | Cause | Fix |
|---|---|---|
| Codex ignores your CLAUDE.md | Codex reads AGENTS.md | Rename it, or set project_doc_fallback_filenames |
| Custom provider returns 401 | Codex expects an sk- key | Add requires_openai_auth = false |
| Codex errors on startup: chat wire API deprecated | wire_api = "chat" was removed in Feb 2026 | Set wire_api = "responses" |
| Subagents do nothing | No agent file, or you never asked for one | Add a .codex/agents/NAME.toml file; Codex spawns subagents only on explicit request |
| Hooks never fire | Wrong event name or matcher regex | Fix the event name / matcher; hooks are on by default, so no flag is needed |
| A command your allowlist permitted now stops | Sandbox stricter than the old rule | Widen sandbox_mode or use approval_policy = "on-request" |
If a project's .codex/config.toml is being ignored entirely, check that the project is marked trusted. Codex only loads project-scoped config in trusted directories, and it will not let a project file override provider, auth, or profile selection.
Team Migration
Team / Multi-Developer Migration
For a team, the migration is cleaner than the solo case, because Codex collapses two Claude Code files into one committed config. In Claude Code you shipped a .claude/settings.json for the team and let each developer keep a gitignored .claude/settings.local.json. In Codex, you commit a single .codex/config.toml at the repo root and let each developer select a profile.
| Concern | Claude Code | Codex |
|---|---|---|
| Shared team config | .claude/settings.json (committed) | .codex/config.toml (committed, trusted repos) |
| Personal overrides | .claude/settings.local.json | a personal profile file in ~/.codex/ |
| Shared instructions | CLAUDE.md | AGENTS.md |
| Risk posture per run | permission allowlist | --profile strict vs --profile fast |
The team payoff is the same gateway trick from the dead-end section, applied once. Register one model_provider in the committed config, hand every developer the same gateway key scheme through your secret manager, and the whole team routes through one endpoint with one billing view — whether they run openai/gpt-5.5 or anthropic/claude-opus-4.8. That single-endpoint routing is the concrete reason a shared gateway beats per-developer provider keys.
Advanced
Profiles for CI, Local, and Review
Profiles are where Codex pays back the migration effort, because they replace the Claude Code habit of juggling settings.json against settings.local.json. A profile is a separate file under ~/.codex/, and you select it per run with --profile. Nothing changes globally until you decide it should.
Create three files for three risk postures. The base config.toml holds the shared pieces — providers, MCP servers, and hooks; each profile overrides only the two or three keys that differ. That single-file discipline is what makes the Codex setup easier to reason about than the Claude Code scope stack, once the migration is behind you.
# ~/.codex/ci.config.toml
model = "gpt-5.5" approval_policy = "never" sandbox_mode = "read-only"
Run automated review in CI with codex --profile ci, and it can read everything but change nothing. Keep a local.config.toml at workspace-write for day-to-day work, and the claude.config.toml from the dead-end section that swaps the driver to anthropic/claude-opus-4.8 when you want Anthropic's model on a hard problem.
Why This Matters
What This Actually Teaches
Most migration guides sell the rename. The real lesson is that your tooling config is not the tool — it is a contract, and Codex's contract is blunter and more composable than Claude Code's.
When a surface "breaks," it usually means the new tool chose a coarser abstraction on purpose. Codex's two-dial sandbox replaces a per-command allowlist because coarse dials survive a team of twenty developers touching the same repo; a hand-tuned allowlist does not. That is a trade-off, not a bug.
The dead end is the honest part. No vendor is going to make it trivial to run a competitor's model inside their CLI. The fact that the fix is a single model_provider block — and not a fork or a wrapper script — tells you Codex treats providers as pluggable. The migration that matters is the one that keeps your options open.
Migrating your tooling to Codex should not mean giving up the models you migrated for, and with one provider block it doesn't.
Port intent, not rules
When a config has no 1:1 equivalent, the rule was never the point — the intent behind it was. A sandbox tier that captures the intent is a better migration than a literal translation that misses it.
Keep the model pluggable
The single config surface worth getting right is the model_provider. Nail it once and you can swap the brain without rewriting the body — the difference between a migration and a lock-in.
Verify before you delete
Keep the old .claude/ directory until the new setup is proven on a real task. Config that 'transfers' and config that 'works under load' are not the same thing.
The migration that matters isn't the rename — it's the one that keeps your models pluggable, your sandbox honest, and your options open.
FAQ
Frequently Asked Questions
Can I use Claude models in Codex CLI?+
Not with vanilla Codex, which is OpenAI-only. Register an OpenAI-compatible gateway as a model_provider and point a profile at anthropic/claude-opus-4.8. That is the single surface with no native equivalent.
Does Codex CLI read CLAUDE.md?+
Not by default. It reads AGENTS.md. Add project_doc_fallback_filenames = ["AGENTS.md", "CLAUDE.md"] to keep the old file, or rename it.
How do I import my Claude Code settings into Codex?+
Run codex, then /import. Codex 0.140 added a selective importer for setup, project config, and recent chats. It does most of the work and reports the rest.
Does Codex CLI have hooks like Claude Code?+
Yes, and they are on by default. Declare [[hooks.Event]] blocks for events including PreToolUse, PostToolUse, SessionStart, Stop, PreCompact, and PostCompact. The only Claude Code hook with no equivalent is ConfigChange.
Can Claude Code and Codex share the same MCP servers?+
Yes. The MCP processes are identical. Only the declaration moves, from JSON in .mcp.json to TOML under [mcp_servers.NAME].
Do I have to rewrite my Claude Code subagents for Codex?+
You re-declare, not rewrite. The prompt body carries over; the wrapper moves from Markdown in .claude/agents/ to a standalone TOML file in .codex/agents/. Subagents are on by default, so there is no flag to enable.
Is the AGENTS.md file the same as CLAUDE.md?+
Same job, different name. AGENTS.md is a cross-tool convention; CLAUDE.md is Claude Code's own memory file. Content transfers directly.
References
References
- OpenAI Codex Configuration Reference
- OpenAI Codex Changelog
- OpenAI Codex Hooks Reference
- Claude Code Settings Reference
About FACTA
FACTA is an AI consulting firm. We design agent systems, build the workflows around them, and help teams adopt AI without betting the farm on a single vendor.
We write these guides because the hardest part of AI tooling is rarely the model — it is the config, the sandboxing, and the contracts you sign with your tools. A migration is a good time to look at those contracts instead of just renaming them.
If you are weighing a Claude Code → Codex migration, or want a vendor-neutral agent stack that keeps your options open, we can help.
Vendor-neutral by design. Pluggable by habit.
Need help migrating your agent tooling?
Migrating Claude Code to Codex is a config problem dressed up as a rename. FACTA builds vendor-neutral, pluggable AI automation stacks — keeping your models, sandboxes, and workflows portable. We can run the migration with you and leave your team with a config that survives the next tool switch.
Explore AI Automation