Skip to content

Migrating between Codex, Claude Code, and Cursor means moving three layers: instructions, MCP and skills, and permissions. The reliable pattern is one AGENTS.md as the only instruction source, each CLI’s built-in importer for MCP servers, commands and skills, and a parity run in which both agents execute the same closed ticket and are judged on the same tests.

Your team standardised on Codex last spring. Now half of them want Claude Code in the terminal, one squad lives in Cursor, and the first Claude Code session on the repo ignores the build commands that Codex always followed. Nobody knows which instruction file is authoritative, and the MCP token sits in three configs.

This guide is for developers who move a repository from one of these agents to another, or who add a second agent beside the first. It covers every direction. If you are a tech lead setting one standard for a whole team, read it, then continue with shared context and rules for a team. If you have not yet decided which agent should own which work, start with Codex compared with Claude Code and Cursor.

What you get from moving a repository between agents

Section titled “What you get from moving a repository between agents”
  • One AGENTS.md that Codex reads natively, Claude Code imports with one line, and Cursor receives as a project rule.
  • The exact import commands both CLIs ship for the other tools’ configuration, and what each one misses.
  • MCP servers written correctly in all three formats, with tokens read from the environment and never committed.
  • A parity run: the same closed ticket executed by the old and the new agent, compared on tests, lint, and boundaries instead of on a line-by-line read.
  • A failure-modes list for the migration traps that fail silently.

The model is the smallest difference. The configuration surface is the larger one, and it is where migrations fail quietly.

LayerClaude Code (v2.1.283)Codex CLI (0.157.1)Cursor (3.x line, checked 2026-08-28)
Project instructionsCLAUDE.md; reads AGENTS.md only when there is no CLAUDE.md (v2.1.277+)AGENTS.md (/init creates one)AGENTS.md and CLAUDE.md in the project root and subdirectories (Cursor docs, checked 2026-10-12); Rules under .cursor/rules/ for Cursor-only rules
Import from other agentsclaude import codex|cursor|gemini, or /import in a session/import in the TUI (described as importing from Claude Code in 0.162.1, checked 2026-10-12; Cursor too, per the 0.145.0 release notes)none verified
MCP config.mcp.json (project) via claude mcp add[mcp_servers.<name>] in ~/.codex/config.toml via codex mcp add.cursor/mcp.json or ~/.cursor/mcp.json
Skills.claude/skills/.agents/skills/.agents/skills/ (where npx skills add installs for Cursor, skills 1.7.0); Cursor also loads .cursor/skills/, .claude/skills/ and .codex/skills/ (Cursor docs, checked 2026-10-12)
PermissionsPermission modes; auto mode is the starting mode for interactive sessions from v2.1.283 (both channels)Approval policy (-a) plus sandbox or permission profileRun modes
Isolated parallel work--worktree, --bg, /batch--worktree, codex cloud (experimental), desktop appWorktrees, Cloud Agents
Default modelClaude Opus 5.5GPT-6.1 Solno single default model; Hobby uses Auto (Cursor, checked 2026-10-12)

Prices and the full model lineup live on the models hub. The rule for a migration is the same as for any model change: start on the new tool’s default model, tune effort before you switch model, and switch only when your own evals say so.

How to move a repository from one agent to another

Section titled “How to move a repository from one agent to another”
  1. Make AGENTS.md the one source of instructions. Every tool either reads it or can be pointed at it, and it is the only format of the three that is an open standard. Pick your direction below.

  2. Run the importer, in dry-run mode first. Both CLIs ship one. It moves MCP servers, commands, and skills faster than you can by hand, and the dry run shows what it would overwrite.

  3. Rewrite MCP servers in the target format and read every secret from the environment.

  4. Map permissions and parallel work to the new tool’s model, so the agent is neither blocked on every command nor running unsandboxed.

  5. Prove the migration with a parity run before you delete anything from the old setup.

Step 1: consolidate instructions into AGENTS.md

Section titled “Step 1: consolidate instructions into AGENTS.md”

Rename CLAUDE.md so that Codex reads it, then give Claude Code a one-line pointer back:

Terminal window
# terminal, repository root
git mv CLAUDE.md AGENTS.md
printf '@AGENTS.md\n\n## Claude Code only\n' > CLAUDE.md

The @AGENTS.md line is a native import. It works on every release channel and in repositories that keep both files. Claude Code’s own fallback does not: when a CLAUDE.md exists, Claude Code reads only that file. Put anything that is truly Claude-specific, such as a note about a hook or a subagent, under the Claude Code only heading.

In a monorepo, repeat the pattern in every directory that has its own instructions: a packages/api/AGENTS.md with the content, and a packages/api/CLAUDE.md that contains only @AGENTS.md.

Step 2: run the importer, and read the dry run

Section titled “Step 2: run the importer, and read the dry run”

Both CLIs import the other tools’ configuration. Neither import is a full migration, so run the dry run first and treat the output as a checklist.

Terminal window
claude import codex --dry-run # or: claude import cursor --dry-run
claude import codex # opens a picker; choose what to bring over

Per Anthropic’s commands reference (checked 2026-09-26), /import brings in instruction files, MCP servers, commands, subagents, and skills. Because it can bring instruction files, run it after Step 1 and check that it did not recreate a second copy of your rules in CLAUDE.md.

Skills move with the Agent Skills standard: a SKILL.md folder works in all three tools, only the directory differs. npx skills add <owner/repo> (npm skills 1.7.0) installs into each agent it detects. Plugins do not move: Claude Code plugins, Codex plugins, and Cursor plugins come from different marketplaces, so reinstall the equivalent in the new tool.

Step 3: rewrite MCP servers in the target format

Section titled “Step 3: rewrite MCP servers in the target format”

The servers are the same; only the wrapper changes. The example below uses two official remote servers: the GitHub MCP server and Context7. The GitHub server reads its token from GITHUB_PAT in your shell, never from a committed file; Context7 needs none.

Terminal window
# writes .mcp.json, which is safe to commit because it holds only a variable reference
claude mcp add --scope project --transport http context7 https://mcp.context7.com/mcp
claude mcp add --scope project --transport http github https://api.githubcopilot.com/mcp/ \
-H 'Authorization: Bearer ${GITHUB_PAT}'
claude mcp list

The single quotes keep ${GITHUB_PAT} literal. Claude Code expands it from the environment each time the server starts.

One protocol difference survives the translation. Claude Code negotiates the 2026-07-28 MCP specification with direct HTTP servers by default. Codex 0.157.1–0.162.1 does not (its mcp_2026_07_28 feature is still under development and off, checked 2026-10-12), so a server can behave differently in the two tools even with an identical entry.

The habit that breaks most often is autonomy. An agent that was allowed to run your tests in the old tool stops and asks in the new one, or the reverse: a flag copied from a blog post turns the sandbox off.

You relied onClaude CodeCodexCursor
Edit files, gate risky commandsAuto mode (the starting mode for interactive sessions from v2.1.283); --permission-mode acceptEdits for edits-only autonomy-a on-request (the default) with --sandbox workspace-write; to let a reviewer model decide instead of you, --approve-for-meRun modes: Auto-review, Allowlist and Run Everything, under Settings > Agents > Approvals & Execution (Cursor docs, checked 2026-10-12)
Headless run in a scriptclaude -p (starts in Manual, or in auto mode on third-party providers or with telemetry off from v2.1.285; allow tools with --allowedTools)codex exec (put -a before exec: codex -a never exec …)Cursor CLI print mode (-p) (per Cursor’s headless docs, checked 2026-08-28)
Isolated parallel sessionsclaude --worktree or --bgcodex --worktree, or Codex cloudWorktrees or Cloud Agents

Two corrections to advice you may have followed. First, codex "prompt" starts an interactive local session in your current checkout, not a cloud sandbox. Five of them in five terminals edit the same files unless each runs with --worktree. Second, codex --full-auto does not exist in 0.157.1; use --approve-for-me or a permission profile. Keep --dangerously-skip-permissions and --dangerously-bypass-approvals-and-sandbox for disposable, network-restricted sandboxes only. The full model for each tool is on permissions and sandboxing for agents.

How do you prove the migration worked without reading every diff?

Section titled “How do you prove the migration worked without reading every diff?”

Run one closed ticket through both agents from the same commit, and let the repository’s own gates decide. Pick a ticket with a merged fix and a test that failed before it. That test is your oracle: it is the part neither agent is allowed to change.

Terminal window
# terminal: two isolated checkouts of the commit before the fix
git worktree add ../parity-old BASE_SHA
git worktree add ../parity-new BASE_SHA
# dependencies are installed before either agent starts
(cd ../parity-old && npm ci) && (cd ../parity-new && npm ci)
# copy the oracle test from the fix commit into both checkouts and commit it there
for d in ../parity-old ../parity-new; do
git -C "$d" checkout FIX_SHA -- path/to/oracle.test.ts
git -C "$d" commit -qm "oracle test"
# record the oracle commit; the gate diffs against it, so an agent's own commits are still checked
git -C "$d" tag "oracle-$(basename "$d")"
done
# the oracle must fail before either agent runs
(cd ../parity-old && npx vitest run path/to/oracle.test.ts) && echo "ORACLE PASSES AT BASE: pick another ticket"
# old tool (Codex here), headless, sandboxed to the workspace, transcript kept
(cd ../parity-old && codex exec --json --sandbox workspace-write "$(cat ../parity-task.md)" > ../run-old.jsonl)
# new tool (Claude Code here), headless, edits allowed, the same commands AGENTS.md lists
(cd ../parity-new && claude -p "$(cat ../parity-task.md)" --permission-mode acceptEdits \
--allowedTools "Bash(npm test *)" "Bash(npm run *)" \
--output-format stream-json --verbose > ../run-new.jsonl)
# the gate, identical for both
for d in ../parity-old ../parity-new; do
base="oracle-$(basename "$d")"
(cd "$d" && git add -A \
&& git diff --cached --quiet "$base" -- path/to/oracle.test.ts \
':(glob)**/*.test.*' ':(glob)**/*.spec.*' 'test/**' 'tests/**' \
&& npm test && npm run lint && git diff --cached --stat "$base") || echo "FAILED: $d"
done
# did each agent run the commands AGENTS.md lists?
for f in ../run-old.jsonl ../run-new.jsonl; do
grep -q 'npm test' "$f" && grep -q 'npm run lint' "$f" || echo "MISSING COMMANDS: $f"
done

Replace FIX_SHA with the merged fix and BASE_SHA with its parent. The oracle test comes from the fix commit, so it does not exist at BASE_SHA: copy it in before the agents start and confirm that it fails there, or npm test can pass without the ticket being solved. Swap npx vitest run for your own single-test command, list every test location your repository uses in the gate’s pathspec (co-located tests, snapshot folders, fixtures), adjust the command list to what your AGENTS.md names, and put the ticket text, its acceptance criteria, and “do not edit the test files” in parity-task.md. Before you run anything, confirm that Codex sees your MCP entries with codex mcp list, and that it recognises every key with codex --strict-config exec "Reply OK" (it names any unknown key; --strict-config does not work with codex mcp, checked on 0.157.1).

Both checkouts must be trusted projects for Codex, or it ignores AGENTS.md there, and codex exec cannot show the trust prompt. Trust them first: run codex interactively once in each worktree and accept the prompt, or add both absolute paths to ~/.codex/config.toml (key format checked on 0.157.1):

[projects."/abs/path/to/parity-old"]
trust_level = "trusted"
[projects."/abs/path/to/parity-new"]
trust_level = "trusted"

Then add Before you start, list the instruction files you loaded. to parity-task.md and reject a run that reports none.

The migration passes when the gate prints neither FAILED nor MISSING COMMANDS: both runs are green on the same tests, neither agent modified a test file, and both transcripts show the commands AGENTS.md lists. The grep also matches a command the agent only read, so open the transcript when a run looks suspiciously quick. Then check the staged diff stat against your Boundaries section. Claude Code gets Bash(npm test *) and Bash(npm run *) so it can run every command AGENTS.md lists; add any other command your AGENTS.md names, or the comparison favours Codex, which may run anything inside its workspace sandbox. You sign off on that evidence, not on the diff. If you want a second opinion on the two diffs, use the prompt below.

Run the parity task in both directions whenever you change AGENTS.md substantially. The cheapest guard against drift afterwards is a CI step that fails when CLAUDE.md stops importing the shared file:

Terminal window
# CI step
grep -qx '@AGENTS.md' CLAUDE.md || { echo "CLAUDE.md must import AGENTS.md"; exit 1; }

What breaks when you move a repository between Codex, Claude Code, and Cursor?

Section titled “What breaks when you move a repository between Codex, Claude Code, and Cursor?”

Claude Code ignores AGENTS.md. The repository has a CLAUDE.md (so the fallback never fires), the teammate’s build is older than v2.1.277, or the toggle under Project instructions in /config is off. Recovery: make @AGENTS.md the first line of CLAUDE.md. That works in all three cases.

Codex runs as if there were no instructions. The project is untrusted, and since 0.150.0 an untrusted project supplies no project-level AGENTS.md. Recovery: trust the project when Codex prompts, then ask it which instruction files it loaded.

An MCP server loses its token in Codex only. A JSON headers object was pasted into config.toml, and Codex dropped it without an error. Recovery: re-add the server with --bearer-token-env-var, and run codex --strict-config exec "Reply OK" to catch other unknown keys.

A server works in Claude Code but misbehaves in Codex. The two negotiate different MCP protocol versions. Recovery: test the server in Codex specifically, and check its README for a pre-2026-07-28 compatibility note.

The importer doubled your rules. claude import or Codex /import wrote a second copy of instructions you had already merged. Recovery: run the dry run first, delete the duplicate, and keep AGENTS.md as the only file with content.

A token ended up in git. Someone replaced ${GITHUB_PAT} with the literal value while debugging. Recovery: revoke and rotate the token first, then remove it from history. Rewriting history alone does not protect a token that has already been pushed.

Results got worse after the switch. The prompts and AGENTS.md were tuned for the old model. Recovery: do not change the model first. Raise effort on the default model, rerun the parity task, and change the instruction that the comparison prompt points to.

Parallel sessions overwrote each other. Several sessions ran in one checkout. Recovery: give each session its own worktree (--worktree in both CLIs, Worktrees in Cursor) and merge through pull requests.