Claude Code agents.md support is not file discovery. On 2.1.273 we put a unique codeword inside AGENTS.md, denied every tool that can open a file, and asked a session to repeat it — it answered UNKNOWN, three runs in a row. The identical test with CLAUDE.md returned the codeword immediately. AGENTS.md reaches Claude Code through exactly one route, an @AGENTS.md import line, and without it the file is invisible no matter where you put it. The complete Claude Code guide covers how instruction files load; this is the measurement of which ones do.
Key takeaways
- A project containing only
AGENTS.mdansweredUNKNOWNwhen its own codeword was requested, with reading tools denied. CLAUDE.mdloaded on its own in the same harness, same prompt, same restrictions.- With both files present, the
CLAUDE.mdcodeword won and theAGENTS.mdcodeword never appeared at all. - A one-line
@AGENTS.mdinsideCLAUDE.mdcarried the AGENTS.md codeword through intact. - With tools enabled the same session answers correctly by grepping for the file — which is why this question is so widely answered wrong.
The claude code agents.md answer in one table
Four projects, one codeword each, one prompt, one build. The only difference between arms is which instruction files sit in the working directory.
| Files in the project | Answer returned | Reached context |
|---|---|---|
AGENTS.md only | UNKNOWN | No |
CLAUDE.md only | m8qd-3zpl | Yes |
| Both, different codewords | w7ju-1cke (the CLAUDE.md one) | CLAUDE.md only |
AGENTS.md + CLAUDE.md holding @AGENTS.md | x5ta-8dmr (the AGENTS.md one) | Yes, via the import |
Row three is the one that matters in practice. Dropping an AGENTS.md into a repository that already has a CLAUDE.md feels like adding a second instruction source. It adds nothing. The file sits there, committed, reviewed in pull requests, and never once reaches the model.
How we measured it
The hard part of this question is not running a session — it is stopping the session from cheating. A Claude Code agent with Read, Grep, Glob and Bash available will find an instruction file whether or not the harness loaded it, and then it looks like discovery.
So every file-reading tool was denied. The prompt has one legal route to the codeword: auto-loaded instructions.
claude -p "Reply with the project codeword and nothing else. If no codeword is in your instructions, reply UNKNOWN." \ --output-format json \ --disallowedTools Bash Read Grep Glob Task Agent Edit Write WebSearch WebFetch NotebookEdit Skill
Each arm is a fresh empty directory holding one or two files. The codewords are unguessable strings — k4rn-9twx, m8qd-3zpl, v2hs-6fbn, w7ju-1cke, x5ta-8dmr — so no arm can borrow another's answer and a plausible guess cannot pass.
npm run check:agents-md
The committed check re-validates all thirteen guards against the recorded arms: that the reading tools were denied, that the five codewords are distinct, that the negative arm reproduced, and that the import arm returned the AGENTS.md value rather than the CLAUDE.md one.
Arm by arm, what reached the model
AGENTS.md alone returned UNKNOWN. One turn, no tool calls, no hedging. The file was at the repository root with a plain Project codeword: k4rn-9twx line in it — the canonical placement the AGENTS.md standard describes — and the model had never seen it.
CLAUDE.md alone returned m8qd-3zpl. Same directory shape, same prompt, same denied tools, one turn. This is the control that proves the method works: when a file is auto-loaded, a tool-less session can quote it.
Both files together returned w7ju-1cke. That is the CLAUDE.md codeword. The AGENTS.md codeword in that arm was v2hs-6fbn and it never appeared. There is no merge, no precedence contest, no second-place file. Anthropic's memory documentation describes CLAUDE.md as the file the CLI looks for, and the absence of any AGENTS.md fallback is visible here rather than inferred.
The import arm returned x5ta-8dmr. A CLAUDE.md whose entire contents were the string @AGENTS.md pulled the AGENTS.md codeword straight through.
Why a casual test says the opposite
Before the controlled arms, we ran the obvious version: AGENTS.md with a codeword, a plain claude -p asking for it, tools left on. It answered tp84-vmq2 and cited AGENTS.md:1. That looks exactly like proof of automatic discovery, and it is the test most people run.
The streamed transcript shows what actually happened.
TEXT "I'll look for the codeword in the working directory." TOOL_USE Bash ls -la <project> TOOL_USE Grep pattern: codeword, path: <project> TOOL_RESULT AGENTS.md:1:When asked for the project codeword, reply with exactly: tp84-vmq2 TEXT "tp84-vmq2"
Three turns and two tool calls. The session did not know the codeword; it went and found it. That distinction decides whether your instructions are in force on every request or only when the agent happens to look — and the second one is not a configuration, it is a coincidence.
The one line that fixes it
Keep the rules in AGENTS.md where every other agent finds them, and spend one line of CLAUDE.md on the bridge.
@AGENTS.md
That is the whole fix, and it is the arrangement our AGENTS.md versus CLAUDE.md comparison recommends. Both of those articles asserted the transclusion route from documentation; this is the run that confirms it and the negative control they were missing. Anything Claude-specific — subagents, skills, permission notes — goes underneath the import line in CLAUDE.md, and the shared contract stays vendor-neutral.
The alternative route, symlinking CLAUDE.md to AGENTS.md, still carries the Windows caveat documented in the open agent standard explainer: without Developer Mode, git checks the link out as a text file containing a path, and Claude Code loads the path string. We did not re-measure that here, and it is named as untested rather than repeated as fact.
Claude Code is also not alone in stepping over the file. Running the same probe shape against an installed Antigravity CLI on 2026-09-18 found it loaded no instruction file from four candidate paths, AGENTS.md at the workspace root included — so the file both vendors point at is one neither loads unprompted.
What /import is actually for
import is a real command — it is one of 86 slash commands the session init event lists, and it also exists as a shell subcommand.
claude import --help # → Import config from another AI coding agent into Claude Code # → source Which agent to import from (codex, gemini, cursor)
It migrates another agent's configuration into yours. It is not an instruction-file loader. Against a Cursor project fixture, adding an AGENTS.md changed the importer's reported item count by exactly zero. Treat /import as a one-time migration step when you arrive from Codex, Gemini CLI or Cursor, and treat @AGENTS.md as the thing that keeps working every session afterwards.
Common mistakes
- Committing
AGENTS.mdnext to an existingCLAUDE.mdand assuming both apply. It is tempting because both files are obviously instruction files. The symptom is silent: rules get ignored with no warning anywhere. The fix is the import line. - Testing discovery with tools enabled. The agent finds the file and you conclude it was loaded. Deny the reading tools, or ask something the file alone can answer and watch for a tool call.
- Duplicating the rules into both files. Two copies drift within a sprint, and the one the model reads is the one you forgot to update. Import instead.
- Expecting
/importto wire up AGENTS.md. It migrates config from another agent; the source list iscodex,gemini,cursor, and AGENTS.md is not in it. - Assuming a large AGENTS.md is free once imported. The import inlines the file, so it lands in context on every request exactly as
CLAUDE.mdcontent does. Our memory files census covers what that costs per turn.
What did not work
Our own first reading of the data was wrong. The tools-enabled probe answered the codeword and cited AGENTS.md:1, and the draft note said Claude Code auto-discovers AGENTS.md. The transcript overturned it within one command. That result is published above rather than quietly deleted, because it is the failure mode of every version of this test on the internet.
The memory_paths field looked like the structural answer and is not. The session init event carries a memory_paths object, which reads like a list of loaded instruction files. It reports only the auto-memory directory — nothing about CLAUDE.md or AGENTS.md — so the behavioural arms had to carry the whole argument.
The first arm's token accounting nearly became a finding. AGENTS.md-only reported 15,857 cache-creation tokens against roughly 3,600 for the other arms, which reads like a large file being loaded. It was prompt-cache warming on the first run of the batch. Two reruns in the same directory returned UNKNOWN at 825 and then 0 cache-creation tokens, so the spike is recorded as an ordering artifact rather than evidence.
One measurement was thrown away entirely. Running claude -p "/import cursor --dry-run" from Git Bash does not run the command: the shell rewrites the leading slash into C:/Program Files/Git/import, the session sees a file path, improvises by reading files by hand, and then reports that /import does not exist. It does exist. That trace was discarded and the shell subcommand used instead.
Best practices
- Write the rules once, in
AGENTS.md. Every other major agent discovers it, and one line brings Claude Code along. - Add
@AGENTS.mdas the first line ofCLAUDE.md. Put Claude-specific instructions under it, not instead of it. - Verify with tools denied. A codeword and
--disallowedToolsturns a belief into a result in one command. - Do not mirror content between the two files. The import costs nothing and cannot drift.
- Re-check after a CLI upgrade. This behaviour is version-pinned to 2.1.273;
npm run check:agents-mdis the thirty-second version of this article's evidence.
Conclusion
If you run Claude Code alongside any other agent, keep AGENTS.md as the shared contract and add @AGENTS.md to the top of CLAUDE.md today — measured on 2.1.273, that single line is the difference between instructions that apply on every request and a committed file the model has never seen. Do not trust a test that leaves the reading tools on. Next, read the AGENTS.md versus CLAUDE.md comparison for how to split the two files once the bridge is in place.
Frequently asked questions
Does Claude Code read AGENTS.md automatically?
How do I make Claude Code use AGENTS.md?
If both CLAUDE.md and AGENTS.md exist, which one wins?
Why did Claude Code quote my AGENTS.md if it does not read it?
Does the /import command import AGENTS.md?
Muhammad Kashif
Founder and editor of Devventa, covering AI coding assistants, Next.js and the modern AI development stack.




