AGENTS.md vs CLAUDE.md vs Cursor rules: a structure your team can maintain
Instruction files work when they have one source of truth, a clear scope, and an owner instead of copies of a 500-line handbook.

AGENTS.md should hold shared repository facts, CLAUDE.md (when you need one) should adapt them for Claude Code, and Cursor rules should carry tool- or path-specific guidance. That is the maintainable answer to AGENTS.md vs CLAUDE.md: one source of truth, explicit scope, and no copied handbook.
The worst repository instruction setup has three near-identical files that disagree about the test command. Every agent gets “context”; none gets a reliable instruction.
AGENTS.md, CLAUDE.md, and Cursor rules solve overlapping problems. Treat them as a configuration system with scope and precedence. Build a small set of statements that a developer can verify and an agent can apply at the right moment.
Tool behavior changes, so verify it before standardizing. As of October 24, 2026, Claude Code’s memory documentation says Claude Code v2.1.277 or later reads AGENTS.md when there is no CLAUDE.md or CLAUDE.local.md in the working directory or above it; when one exists, it reads only the CLAUDE.md files by default. It supports importing AGENTS.md from CLAUDE.md, and it loads ancestor files as concatenated context rather than enforcing rules. Cursor’s rule format and discovery are documented in Cursor’s rules documentation. “Instruction” is behavioral guidance, not a security boundary: use repository controls, CI, permissions, and hooks for things that must be enforced.
Which tool reads which file
Surface | Primary reader | Scope mechanism | Maintainable use |
|---|---|---|---|
| Agents and tools that adopt the shared convention, including Cursor, and Claude Code when no | Repository or nested directory | Durable commands, boundaries, and shared facts |
| Claude Code | Project and ancestor files; | Optional: import the shared core, then add narrow Claude-specific workflow |
| Cursor | Focused rules, including path-based rules | Tool- or subtree-specific conventions |
Imports avoid drift when the same fact belongs to multiple readers. A symlink can also make two filenames resolve to one file, but it hides tool-specific intent and can behave awkwardly across editors and platforms. Prefer an explicit import where the tool supports it; verify discovery in a clean checkout.
Start with a decision tree
Choose the instruction surface
Structure, not a sequence. Classify the rule by audience, scope, and size, then put it on the matching surface.
A root AGENTS.md contract branches to sibling Claude and Cursor adapters while a path descends into a nested payments instruction that retains root safety requirements; a runbook is linked and loaded only on trigger.
Classify the rule
Audience · scope · size
Classify. Decide who the rule is for, how widely it applies, and whether it is a fact, a procedure, or a one-off.
Shared repository facts
ROOT / AGENTS.md
Shared instruction file. Facts the whole repository shares live at the root. Root safety remains unless a nearer file explicitly replaces it.
Tool adapters
CLAUDE.md · .cursor/rules
Tool adapter. Tool-specific deltas sit beside the root contract. They adapt the same facts; they do not become a second source of truth.
Path-scoped rule
services/payments/AGENTS.md
Shared instruction file. A path rule lives inside the subtree it governs. The current example adds pnpm --filter payments test:integration and keeps root safety.
Long procedure
RUNBOOK / SKILL
Can't load at startup. A long procedure stays linked from a runbook or skill and loads only when its trigger fires.
Task-only direction
ISSUE / PROMPT
Task-only direction. Direction that applies to one task stays in the issue or prompt. Keep it transient.
Path example
- pnpm --filter payments test:integration
Precedence
- The nearest local command adds or narrows behavior.
- Root safety remains unless explicitly replaced.
| From | Relationship | To |
|---|---|---|
| Classify the rule | Shared repository facts | |
| Classify the rule | Path-scoped rule | |
| Classify the rule | Long procedure | |
| Classify the rule | Task-only direction | |
| Shared repository facts | tool-specific delta | Tool adapters |
A rule can be shared, tool-specific, path-specific, or too large to deserve startup context. That classification decides where it belongs.
Use a decision packet when the agent needs product authority, and a product spec when that authority must carry into implementation and learning. A shared context layer can hold the durable facts those artifacts point to.
Three setups that survive contact with a real repository
1. A small application: one shared file
Use this when one team, one deployable, and a few developers share the same build and conventions.
AGENTS.mdKeep it to durable facts: commands that actually work, layout, style decisions that cannot be inferred, and completion expectations.
# Working agreement
- Install and test: `pnpm test`; type-check: `pnpm typecheck`.
- API handlers live in `app/api`; validate input at the boundary.
- Do not change generated files under `src/generated`.
- Before a PR, add or update the behavior-level test for a changed API contract.As of October 24, 2026, Claude Code reads this file directly when no CLAUDE.md or CLAUDE.local.md exists in the working directory or above it. Add a tiny CLAUDE.md containing @AGENTS.md only when you need Claude-specific workflow or use sessions that can’t read AGENTS.md directly, as Anthropic’s docs describe.
2. A growing product: shared core plus tool adapters
Use this when the team uses more than one agent and each tool has a small, legitimate difference.
AGENTS.md # shared repository facts
CLAUDE.md # @AGENTS.md + Claude-only workflow
.cursor/rules/api.mdc # API-specific Cursor rule
.cursor/rules/frontend.mdcExample: AGENTS.md owns “run pnpm verify before declaring work done.” CLAUDE.md may add “use plan mode for billing changes.” Cursor’s API rule may describe the response-envelope convention only when editing API code. Do not repeat the test command in all three.
3. A monorepo: a root contract and local contracts
Use this when a broad instruction is truly broad, but packages have different commands, owners, and risks.
AGENTS.md
apps/web/AGENTS.md
services/billing/AGENTS.md
CLAUDE.md
.cursor/rules/The root document should say how to find the package rule and identify cross-cutting requirements. A package document should only add or narrow what applies there: its test target, local architecture, migrations, or boundary. Put an explicit conflict policy at the root: “nearest package instruction wins for local commands; root security and compatibility rules always apply.” Then make it true in every tool you support.
Decide precedence explicitly
Consider this conflict:
# root AGENTS.md
- Run `pnpm test` before requesting review.
# services/payments/AGENTS.md
- Run `pnpm --filter payments test:integration` before requesting review.The second is not necessarily a contradiction; it can be an addition. Write it that way: “In addition to the root verification, run…” If the package command replaces the root command, say “For this package, test:integration is the required verification; do not run the root suite unless the change crosses packages.”
Now consider CLAUDE.md importing AGENTS.md and then saying “do not run tests automatically.” That is a direct contradiction that a model may resolve unpredictably. Replace it with a scoped condition: “For documentation-only changes, report why tests were not run.” The difference is a rule a reviewer can audit.
For Claude Code specifically, nested CLAUDE.md files are context concatenated in directory order; proximity changes what appears later, and the files still do not enforce policy. Write non-conflicting additions instead of relying on a “last rule wins” intuition.
Migrate in a controlled pass
- Inventory every instruction surface, including old
.cursorrules, nested files, onboarding docs, and CI messages. - Classify every line: shared fact, tool-specific behavior, path-specific convention, workflow, or stale advice.
- Write the shared core first. Delete lines that merely say “write clean code” or duplicate a formatter.
- Create adapters. For Claude, import the shared file rather than copy it. For Cursor, move genuinely scoped conventions into focused rules.
- Add one conflict policy and one owner for the instruction system.
- Ask two people to run the same small task with different agents. Compare which instructions were discoverable and which were ambiguous; fix the files, not the people’s prompts.
Avoid a blind rename from AGENTS.md to CLAUDE.md. It loses portability and can silently alter how a tool loads content. Preserve the shared source, add a tested adapter, and remove old copies only after the adapter behaves as intended. A symlink can provide a temporary compatibility bridge, but an explicit import documents why the relationship exists and leaves room for a small tool adapter.
Audit the setup when it changes
Run this audit after a tool migration, a repeated agent mistake, or every quarter.
- Can each line name its owner and the behavior that proves it?
- Is the command current in a clean checkout?
- Is the same rule duplicated in another file? If yes, is one an import rather than a copy?
- Is a local rule actually scoped to the files where it matters?
- Does the file contain a procedure better kept in a runbook?
- Does any statement contradict CI, repository policy, or a nearer instruction?
- Has a recent review comment exposed a rule worth adding or an obsolete rule worth deleting?
Keep a small changelog in the pull request that changes the rules: what moved, why, and how it was checked. Treat instruction files like production configuration. A stale line can alter work long after its author has forgotten it.
Write rules that have a chance of being followed
An instruction works best when it is short, concrete, and located next to the decision it governs. “Use sensible error handling” asks the agent to supply the standard. “Return the repository’s ApiError envelope from handlers in apps/api, including a stable error code” identifies the surface and the observable outcome.
Prefer a reason when the rule would otherwise look arbitrary: “Do not edit generated clients under src/generated; regenerate them from the schema command.” The reason lets an implementer recognize the boundary when a task looks like an exception. Do not explain obvious formatting twice; your formatter and linter already carry that load.
Keep global startup context deliberately narrow. Claude’s documentation recommends concise instructions and path-scoped rules when material applies only to part of a large project. Unrelated context consumes attention and invites accidental conflicts. A database migration convention belongs with migrations; a release procedure belongs in a runbook reached by a short trigger such as “For production migrations, follow docs/release-migrations.md.”
Finally, test discovery rather than assuming it. Open the tool in a nested package, ask it to identify the applicable test command and local rule, and compare the answer to your intended precedence. This inexpensive test catches the failure that static review misses: a beautifully organized instruction system that the tool never loaded.
What not to put in a rule file
Do not put credentials, URLs that only work on one person’s machine, a project plan, a transcript of architecture debates, or an ever-growing list of one-off mistakes. Do not promise enforcement through natural-language instructions. If an action must not happen, enforce it outside the model’s discretion.
Start with the repository’s next repeated correction. Put the durable, testable version in the shared core; make the tool adapter import it; remove the duplicate. Then open a nested package and verify that the agent can name the applicable test command and local rule.

