CLAUDE.md and AGENTS.md compatibility: what Claude Code and Codex actually read
Claude Code reads CLAUDE.md. Codex reads AGENTS.md. Neither falls back to the other by default. Here's what the docs say in both directions, how to make one file work for both tools, and why the file is only half the problem.

If you have both Claude Code and Codex in your team's toolbox, you have probably typed the same question into a search bar: does Claude Code read AGENTS.md? Does it fall back to it if CLAUDE.md is missing? Do you need to maintain both files, or is there a way to keep them in sync?
The official answer, straight from the Claude Code memory documentation, is short:
Claude Code reads
CLAUDE.md, notAGENTS.md.
There is no automatic fallback. If your repo only has AGENTS.md, Claude Code will not load it on its own. But the documentation also describes three first-class patterns for making one source of truth work for both agents. None of them require you to duplicate instructions.
Why this question keeps coming up
AGENTS.md started as a Codex convention and has spread across the ecosystem. Most non-Anthropic coding agents now look for it by default. CLAUDE.md is the equivalent file Claude Code has always used, and it predates AGENTS.md by enough that Anthropic chose to keep the name rather than rename around a younger convention.
The result is a real interoperability problem for any team that runs more than one agent:
- A
CLAUDE.md-only repo confuses Codex, Cursor, and anything else that expectsAGENTS.md. - An
AGENTS.md-only repo gets ignored by Claude Code. - Maintaining both by hand means every project rule has to be written, edited, and reviewed twice.
The good news is you do not have to pick.
Option 1: import AGENTS.md from CLAUDE.md (recommended)
Claude Code supports @path/to/file imports inside CLAUDE.md. Imported files are expanded into the session context at launch, exactly as if their contents were inline. So the minimum-viable shared setup is a CLAUDE.md that pulls in AGENTS.md:
@AGENTS.md
## Claude Code
Use plan mode for changes under `src/billing/`.
AGENTS.md stays the source of truth for every tool in your stack. CLAUDE.md exists only to wire the import and hold the small handful of Claude-specific overrides you actually need. Codex reads AGENTS.md directly. Claude Code reads CLAUDE.md, expands the @AGENTS.md line, and ends up with the same instructions plus your overrides.
This is the pattern Anthropic itself recommends in the docs. It is the cleanest answer for almost every team.
Option 2: symlink CLAUDE.md to AGENTS.md
If you have nothing Claude-specific to say and want exactly one file on disk, a symlink works:
ln -s AGENTS.md CLAUDE.md
Claude Code follows the symlink and reads AGENTS.md byte-for-byte. There is no second file to keep updated and no merge logic to debug.
The caveat: on Windows, creating a symlink requires Administrator privileges or Developer Mode. Cross-platform teams should default to the @AGENTS.md import instead. The import works identically on every OS and survives git clone without anyone needing elevated permissions.
Option 3: let /init merge them for you
If you are bootstrapping Claude Code in a repo that already has an AGENTS.md (or a .cursorrules or .windsurfrules), running /init reads those files and incorporates the relevant parts into the generated CLAUDE.md automatically. This is the right starting point if your AGENTS.md has grown beyond a clean shared spec and you want Claude Code to extract the parts that apply to it specifically.
After /init, you still own the resulting CLAUDE.md. If you want it to stay in sync with AGENTS.md going forward, convert it to the import pattern from Option 1 and delete the duplicated content.
What about the other direction: can Codex read CLAUDE.md?
The symmetric question: if your repo only has CLAUDE.md, will Codex pick it up?
By default, no. Codex CLI reads AGENTS.md and AGENTS.override.md. CLAUDE.md is not part of the default discovery list. But unlike Claude Code, Codex exposes a configuration setting for adding fallback filenames. In ~/.codex/config.toml:
project_doc_fallback_filenames = ["CLAUDE.md", "COPILOT.md"]
With that set, Codex's per-directory lookup becomes AGENTS.override.md → AGENTS.md → fallback names, in order, walked from the Git root down to the current working directory. At most one file is picked up per directory, so CLAUDE.md is read only where no AGENTS.md exists alongside it. The full lookup rules are in the Codex AGENTS.md guide.
The two ecosystems end up symmetric in shape but asymmetric in mechanism:
| Default behavior | How to read the other file | |
|---|---|---|
| Claude Code | Reads CLAUDE.md only | @AGENTS.md import inside CLAUDE.md, or ln -s AGENTS.md CLAUDE.md |
| Codex CLI | Reads AGENTS.md / AGENTS.override.md only | project_doc_fallback_filenames = ["CLAUDE.md"] in ~/.codex/config.toml |
One practical caveat about the Codex fallback: it lives in ~/.codex/config.toml, which is a user-level file. It does not travel with the repo. New teammates who clone the project will not pick up CLAUDE.md until they set the same fallback list themselves. The Claude Code import pattern, by contrast, lives inside the repo and works for everyone on first clone with no per-machine setup.
That asymmetry is the main reason we still recommend AGENTS.md as the canonical source of truth and CLAUDE.md as a thin import wrapper, even though both directions are technically achievable. One file travels with the repo; the other depends on every developer remembering to configure their CLI.
What about CLAUDE.local.md, rules, and managed policy?
The compatibility question usually surfaces because someone is trying to make a project-level file work across tools. But Claude Code has a full hierarchy of instruction files that also matters when you are running more than one agent:
CLAUDE.mdand./.claude/CLAUDE.md— team-shared, committed to the repo.CLAUDE.local.md— personal, gitignored..claude/rules/— modular, withpaths:frontmatter for path-scoped rules.- Managed policy
CLAUDE.md— organization-wide, deployed by IT, cannot be excluded.
AGENTS.md is a single flat file. There is no AGENTS.local.md, no rules directory, no managed-policy layer. Other agents that read AGENTS.md mostly do not have those concepts either. So the @AGENTS.md import covers the team-shared layer cleanly, but the rest of the Claude Code hierarchy stays Claude-specific by design.
In practice this means:
- Put cross-tool rules in
AGENTS.md, imported fromCLAUDE.md. - Put Claude-specific behavior in
CLAUDE.mdbelow the import. - Put personal preferences in
CLAUDE.local.md, gitignored. - Use
.claude/rules/withpaths:frontmatter for instructions that only apply to part of the codebase.
That gives you one shared file across tools without giving up the features that make Claude Code's instruction layer useful.
The bigger problem the file does not solve
CLAUDE.md and AGENTS.md are about instructions to the model. They are not the rest of the harness.
In a production setup, swapping Claude Code for Codex (or running both side by side) is not just a question of whether they read the same markdown file. It is a question of:
- Which execution sandboxes the agent is wired up to connect to.
- Which MCP servers the agent has access to.
- How secrets are injected so the model never sees them in context.
- Which internal services the agent can reach over the network.
- How idle timeouts, scaling, and audit logs are configured.
- Which model and API keys back the agent.
Two coding agents that happen to read the same AGENTS.md can still have wildly different deployment posture, security boundaries, and observability. Making the instruction file portable is a one-line change. Making the rest of the runtime portable is the actual work.
How Agyn handles this
Agyn is the open-source Kubernetes runtime we build for deploying coding agents inside enterprise infrastructure. The harness around the model — containers, MCP servers, secrets, network policy, observability — lives in Terraform. The agent itself is one line of that Terraform.
To switch an agent from Claude Code to Codex, you change two lines — the init_image and the model it talks to:
resource "agyn_agent" "support" {
organization_id = agyn_organization.acme.id
name = "Support"
nickname = "support"
# Swap these two lines to change the agent runtime.
# init_image determines which agent CLI runs; model must match its vendor.
model = agyn_llm_model.claude_opus_4_8.name
init_image = "ghcr.io/agynio/agent-init-claude:v1.0.0"
# model = agyn_llm_model.gpt_5_3_codex.name
# init_image = "ghcr.io/agynio/agent-init-codex:v1.0.0"
instructions = file("./agents/support/instructions.md")
image = "ghcr.io/agynio/agent-runtime:v1.0.0"
idle_timeout = "5m"
availability = "internal"
}
instructions is the field that resolves to CLAUDE.md or AGENTS.md depending on init_image. You write the content once, in plain markdown, and Agyn renders it into the container at ~/.claude/CLAUDE.md when the Claude init image is active or ~/.codex/AGENTS.md when the Codex one is. The Terraform stays identical across the swap — the same string lands at the path the active agent expects.
The agent runtime container, MCP servers, secrets, OpenZiti zero-trust networking, per-agent observability, and access policy all stay in place. Everything Agyn manages — the harness — keeps working unchanged. Only the agent loop itself swaps.
The agent's instruction file is part of the agent definition, not part of every repo it operates on. You write the instructions once in Terraform, and Agyn renders them into the runtime container at the user-level path the active agent expects — ~/.claude/CLAUDE.md when the init image is Claude Code, ~/.codex/AGENTS.md when it is Codex. Because they sit at the user-instruction layer, those instructions apply across every repository the agent works in.
For repo-level instructions — project-specific build commands, conventions, architectural notes that only matter inside one codebase — the patterns from the start of this post still apply. Use AGENTS.md as the canonical file with @AGENTS.md imported from CLAUDE.md, or one of the symlink / /init variants. Agyn does not replace the repo-level layer; it adds the global agent-level layer on top of whatever the repo already has, and the two compose at runtime exactly as Claude Code and Codex normally compose user-level and project-level instructions.
The model layer is becoming a commodity. The harness — the runtime around the agent — is where compatibility actually lives. CLAUDE.md vs AGENTS.md at the repo level is the easy half of that problem. The global instruction layer, the secrets boundary, the MCP wiring, the network policy, and the observability are the other half. We built Agyn for that half.
- Claude Code docs on
CLAUDE.mdandAGENTS.md: code.claude.com/docs/en/memory - Agyn platform: github.com/agynio/platform
- Previously: Introducing Agyn