AGENTS.md vs CLAUDE.md vs Cursor Rules: Writing One in 2026
Which tool reads which file, how to feed all of them from one source, and the size budget that decides whether the agent actually follows your rules.
If you have used Cursor, Claude Code, Copilot, and Codex CLI in the same month, you have probably written the same “here is how this repo works” file three times in three formats, then watched the agent ignore half of it.
The instruction file is the single biggest lever you have over a coding agent. Most of the ones I read are quietly making the agent worse: too long, too vague, or full of advice the model already has.
Checked against the vendor docs on 21 August 2026.
Three files, and who reads what
AGENTS.md is the closest thing to a standard. It was formalized as an open spec in 2025 with OpenAI leading, and in December 2025 it went to the Linux Foundation’s new Agentic AI Foundation alongside Anthropic’s MCP and Block’s goose. More than 60,000 open source projects use one, and it is read natively by Codex, Cursor, Copilot, Gemini CLI, Windsurf, Cline, Devin, Jules, Factory, and a long tail of others. The spec is roughly “put a Markdown file at the repo root and write useful things in it.”
CLAUDE.md is Claude Code’s file, and here is the catch that trips teams up: Claude Code reads CLAUDE.md and not AGENTS.md. The feature request is one of the most upvoted issues on the repo and it is still open. So if your team standardizes on AGENTS.md and someone opens Claude Code, that file is invisible.
Cursor rules live in .cursor/rules/*.mdc, where the MDC format scopes a rule to file globs so it fires only when you are editing, say, *.tsx. Cursor also reads AGENTS.md. It does not read CLAUDE.md.
The bridge is a two-line CLAUDE.md, and it is what Anthropic’s own docs recommend:
@AGENTS.md
## Claude Code
Use plan mode for changes under `src/billing/`.
The @path import pulls the shared file in at session start, and anything below it is yours to add. A symlink works too (ln -s AGENTS.md CLAUDE.md) but cannot carry the extra section, and on Windows it needs Administrator or Developer Mode, so the import is the safer default. If you are coming the other way, /import copies an existing AGENTS.md into CLAUDE.md along with MCP servers and commands, and /init reads Cursor and Copilot instruction files when it generates one.
It is context, not configuration
This is the part that reframed the whole thing for me, and it is stated plainly in the docs: instruction files are delivered to the model as a message, not as enforced settings. Claude reads them and tries to comply. There is no guarantee.
Which gives you a clean test for where a rule belongs. If the rule is “here is how we do things,” it is a sentence in the file. If the rule is “this must happen before every commit, no exceptions,” a sentence is the wrong mechanism and you want a hook, which runs as a shell command at a fixed lifecycle event regardless of what the model decides. Same for hard blocks on tools or paths: those are permission settings, not prose.
People write ALL CAPS NEVER rules because the sentence version keeps failing. The sentence was never going to be enough.
What loads, and when
Half the confusion about these files is really confusion about what is in the context window at any moment.
That last line is the one people get wrong. Breaking a 400-line file into four imported files feels like housekeeping, and it does help a human maintain it, but the agent still pays for all four at launch. Moving a section into a rule that only loads when someone opens a *.tsx file is what buys back the context. Cursor’s glob-scoped MDC rules and Claude Code’s paths: frontmatter are the same idea wearing different clothes.
The size budget is real
Anthropic’s guidance is to target under 200 lines. That is a number worth taking seriously, not because 201 breaks something, but because a 600-line file is a file where your carefully worded rule on line 400 is being averaged in with forty unimportant ones. Long context dilutes attention.
When the file gets too big, the fix is rarely trimming words. It is moving things to where they belong. Formatting goes to the linter, which is deterministic and costs no tokens. File-type rules go to a path-scoped rule. Deep architecture docs go in docs/ and get a one-line pointer, not a paste.
Treat every line like a global variable. It is a small permanent tax on every request, so add it reluctantly and only when something concrete broke without it.
A bad file is worse than no file
An empty repo gives the agent nothing and it works from the code. A bad instruction file gives it confident, wrong, bloated context, and it follows that faithfully every turn.
Two shapes show up constantly. The first is the file that reads like a résumé: “we value clean, maintainable code and follow industry best practices.” The model already knows what clean code is. You have spent tokens saying nothing, on every request, forever.
The second is the fully auto-generated file. /init is a fine starting point and it will find your build commands for you, but what it produces is a draft, and the parts it derives from the codebase are the parts the agent could have derived too. Claude Code’s own /doctor will now propose trimming exactly that: directory layouts, dependency lists, architecture overviews, keeping the pitfalls and the conventions that differ from the defaults. That tells you what the valuable half is.
The bar for a line is one question. Would the agent get this wrong without it? If not, cut it.
What actually belongs
Think of the onboarding note you would write for a strong contractor who is fast and has never seen the repo. Not a lecture on software engineering. The specifics that are not discoverable in five minutes.
Exact commands, first, because this is the highest-value section and the one most often missing. Not “run the tests,” the literal line including the flag that stops it hanging in CI:
## Commands
- Install: pnpm install
- Test (one file): pnpm test path/to/file.test.ts
- Test (all): pnpm test --run
- Typecheck: pnpm typecheck
Then style deltas, and only the surprises. Do not restate what the linter enforces; deleting quotes and semicolons and import order from your instructions is free accuracy. Keep the things a linter cannot catch: “use Result<T, E> for fallible functions and pattern-match every variant, do not throw.” That is a delta. “Use meaningful variable names” is not.
Then testing conventions, with the one that is easy to violate spelled out. “Colocate tests as *.test.ts. Avoid mocks, use the real database through the testcontainers helper in test/setup.ts” is the sentence that stops an agent mocking its way around your integration suite.
Then boundaries. The do-not-touch list: generated output, vendored code, the migration nobody edits by hand. Agents respect these when they are stated and walk straight through them when they are not.
Notice what is missing: architecture philosophy, company values, the history of the codebase. The model does not act on prose. It acts on commands, constraints, and named files.
One small trick while you are in there. Block-level HTML comments are stripped out of CLAUDE.md before it reaches the model, so you can leave notes for human maintainers without paying for them.
Specificity is the whole game
Cursor’s own guidance uses a comparison worth stealing. “Add tests for auth.ts” against “write a test covering the logout edge case in auth.ts, using the patterns in __tests__/, avoiding mocks.” Same intent, wildly different output. The second names the case, points at the pattern, and rules out the shortcut.
Bake that into the file wherever a rule has a concrete anchor. Instead of “handle errors properly,” write “wrap external calls in the withRetry helper in lib/retry.ts, surface failures as typed errors, never a bare throw.” Now the agent has a function to call and a file to open.
A rule that can be read three ways gets read the wrong way about a third of the time.
The setup that holds up
One tool only? Use that tool’s native file and stop reading. If you are all-in on Claude Code, write a good CLAUDE.md and skip the standard you are not using.
Two or more tools? AGENTS.md is the real file, and CLAUDE.md is the two-line import above. One thing to maintain, every tool fed.
Hit an actual limit? Add tool-specific files only where a tool does something the others cannot. A rule that loads only for *.tsx is a real capability, not a second copy.
The failure mode to avoid is three near-identical files maintained by hand. They drift inside a week, one still says npm test from before the migration, and now every agent gets slightly different instructions depending on which one you opened.
Broad rules high, specific rules low. Root file for the universal stuff, packages/api/AGENTS.md for what only makes sense in that service. Nearest-file-wins does the rest, and each file stays short because it only owns its own scope.
Start with almost nothing
The good files were not written up front. They grew from an empty file, one rule at a time, each line added the moment an agent made the same mistake twice. Anthropic’s docs suggest the same trigger, which is reassuring: add to the file when you catch yourself typing the same correction you typed last session.
The repo behind this site has eleven rules in its CLAUDE.md and every one of them is a scar. Rule one exists because pnpm deploy and pnpm run deploy are different commands, the short one collides with a built-in, and the failure message tells you nothing useful the first time you see it. That line was not speculation about good practice. It cost an afternoon.
If you have a bloated 400-line file right now, try the opposite exercise. Delete it, keep the commands, add rules back as things break. The file you rebuild will be a third the size, and the agent will behave better, because it is reading three sharp rules instead of skimming forty soft ones.