AGENTS.md is a plain-text file at your project root that gives AI coding agents — Claude Code, OpenAI Codex, GitHub Copilot Workspace, and others — the project-specific context they need to generate useful code. The format is intentionally simple: Markdown headings, bullet points, and code blocks. The challenge is knowing what to put in it and how different tools actually use it.
This guide covers three things you need to write an effective AGENTS.md in 2026: the difference between AGENTS.md and CLAUDE.md, what each major tool actually reads and ignores, and copy-paste templates for the most common project setups.
AGENTS.md vs CLAUDE.md: What Actually Differs
Both files serve the same purpose — project-specific instructions for AI agents — but with different origins and different scope.
AGENTS.md originated as an OpenAI Codex convention and has been adopted as the cross-tool standard. It lives at the project root (or in subdirectories for monorepos). Any agent that claims AGENTS.md support reads it by default.
CLAUDE.md is Claude Code’s native format. It supports Claude-specific extensions that AGENTS.md does not: the @path/to/file import syntax for splitting instructions across files, the @user scope for personal settings that don’t commit to the repo, and section markers that Claude Code uses to prioritize which rules to load within its context budget.
The practical difference:
| Feature | AGENTS.md | CLAUDE.md |
|---|---|---|
| Tool support | Claude Code, Codex, Copilot Workspace, Cursor, Aider | Claude Code only |
| File import syntax | No | Yes (@path/to/file) |
| User-scoped settings | No | Yes (~/CLAUDE.md) |
| Subdirectory support | Yes | Yes |
| Context budget hints | No | Yes (section markers) |
| Format | Standard Markdown | Standard Markdown + extensions |
If your team uses only Claude Code, CLAUDE.md gives you more capabilities. If your team uses Claude Code alongside Cursor, Copilot Workspace, or Codex, AGENTS.md at the root ensures all tools read the same baseline. Many projects use both: AGENTS.md for shared conventions, CLAUDE.md for Claude-specific configuration.
What Each Tool Actually Reads
Understanding what each tool does with AGENTS.md prevents you from writing instructions that work in one tool and silently fail in another.
Claude Code
Claude Code reads AGENTS.md natively as of 2025. It processes the full file and treats it with the same weight as CLAUDE.md. When both files exist, Claude Code reads both — CLAUDE.md takes precedence for conflicting instructions.
Claude Code respects subdirectory AGENTS.md files. If your repo has backend/AGENTS.md and frontend/AGENTS.md, Claude Code loads the relevant subdirectory file when working in that directory. This is critical for monorepos.
OpenAI Codex
OpenAI Codex (both CLI and the Codex API) reads AGENTS.md as its primary instruction source. It processes the file before any task and uses it to constrain generated code. The implementation is close to “read everything, apply literally” — Codex does not have context budget management equivalent to Claude Code’s, so large AGENTS.md files do get read but may dilute focus on critical rules.
Codex specifically processes the commands section and uses those commands for test execution and validation. If your AGENTS.md lists pytest tests/ as the test command, Codex will run it to verify generated code.
GitHub Copilot Workspace
GitHub Copilot Workspace reads AGENTS.md as part of its project context, but the implementation differs from Claude Code and Codex in one important way: Copilot Workspace is session-oriented rather than file-oriented. It reads AGENTS.md at session start, but mid-session it relies heavily on in-context chat rather than returning to the file.
The practical implication: the commands section and critical rules at the top of AGENTS.md have strong influence; rules buried in later sections are less reliably applied. Front-load what matters.
Copilot Workspace does not read subdirectory AGENTS.md files automatically. It reads the root file only.
Cursor
Cursor reads AGENTS.md alongside its native .cursorrules format. When both exist, Cursor applies both. The AGENTS.md content is treated as project-wide rules equivalent to Cursor’s “Project” rule scope.
Cursor does read subdirectory AGENTS.md files when configured with the include glob pattern.
Aider
Aider reads AGENTS.md and its own CONVENTIONS.md format. Both files are read on startup and treated as persistent context across the session. Aider’s AGENTS.md support is close to Claude Code’s — the full file is read, subdirectory files are respected, and commands are extracted for test execution.
The Structure That Works Across All Tools
Given the differences above, write AGENTS.md with the most critical information first. This structure works reliably across Claude Code, Codex, Copilot Workspace, and Cursor:
# AGENTS.md
## Commands
<build, test, lint commands — always first>
## Critical Rules
<numbered list of non-negotiable constraints>
## Code Style
<formatting, naming, patterns>
## Testing
<test framework and conventions>
## What NOT To Do
<explicit prohibitions>
This order matters because Copilot Workspace and Codex weight earlier sections more heavily. If your only priority is Claude Code, order matters less — Claude Code reads the full file regardless of structure.
Python Template
# AGENTS.md — Python Project
## Commands
- install: `uv sync`
- test: `uv run pytest`
- lint: `uv run ruff check .`
- format: `uv run ruff format .`
- typecheck: `uv run mypy src/`
- all checks: `uv run ruff check . && uv run ruff format --check . && uv run mypy src/ && uv run pytest`
## Critical Rules
1. Use `uv run <cmd>` for all commands — never activate venv manually
2. Add dependencies with `uv add <pkg>`, not pip install
3. All functions and methods must have type annotations
4. Use pytest for tests — not unittest
5. No print() in library code — use `logging.getLogger(__name__)`
6. Handle errors explicitly — no bare `except: pass`
## Code Style
- Formatter: ruff (not black or autopep8)
- Linter: ruff (not flake8)
- Line length: 100 characters (pyproject.toml)
- Import sorting: ruff handles this (not isort)
- Use f-strings, not .format() or %
## Type Checking
- Strict mode: `mypy --strict`
- No `Any` without a comment explaining why
- No `type: ignore` without a specific error code and reason
- `from __future__ import annotations` in all source files
## Testing
- Framework: pytest
- Location: tests/ mirroring src/ structure
- Naming: test_<module>.py / test_<function>_<scenario>()
- Fixtures: conftest.py (not inside test files)
- Use pytest.mark.parametrize for multiple input cases
- Avoid TestCase classes — use plain functions
## What NOT To Do
- pip install anything directly
- Write bare except: clauses
- Add type: ignore without reason
- Use unittest.TestCase when plain pytest functions work
- Return dict[str, Any] when TypedDict would be clearer
TypeScript / Node.js Template
# AGENTS.md — TypeScript Project
## Commands
- install: `npm install`
- build: `npm run build`
- test: `npm test`
- type check: `npx tsc --noEmit`
- lint: `npm run lint`
- format check: `npx prettier --check .`
- format write: `npx prettier --write .`
## Critical Rules
1. TypeScript strict mode is enabled — no implicit any
2. All exported functions must have explicit return types
3. Use `unknown` instead of `any` when type is genuinely unknown
4. Async functions must either catch errors or propagate them — no fire-and-forget
5. Use ESM imports — no CommonJS require() in .ts files
## Code Style
- Formatter: Prettier (config in .prettierrc)
- Linter: ESLint (config in eslint.config.js)
- No semicolons (Prettier handles this per .prettierrc)
- Single quotes for strings (Prettier handles this)
- Prefer const over let; avoid var
## Types
- No `as any` casts — use type guards or proper generics
- Use `z.infer<typeof Schema>` for Zod-validated types
- Prefer interfaces over types for object shapes (mergeable)
- Use types for unions, intersections, and utility types
## Testing
- Framework: Vitest (not Jest unless existing)
- Test files: *.test.ts co-located with source, or tests/
- Mock with vi.mock() — not manual mocks unless necessary
- Use describe/it blocks for grouping; test() for single assertions
## What NOT To Do
- Use require() in TypeScript source files
- Cast with `as any` — use type guards
- Leave unhandled promise rejections
- Write .js files inside src/ — TypeScript only
- Modify package-lock.json manually
Go Template
# AGENTS.md — Go Project
## Commands
- build: `go build ./...`
- test: `go test -race ./...`
- lint: `golangci-lint run`
- format: `goimports -w .`
- vet: `go vet ./...`
- tidy: `go mod tidy`
## Critical Rules
1. Always return errors — never discard with `_` in production paths
2. Wrap errors: `fmt.Errorf("operation: %w", err)`
3. `context.Context` as first param in all I/O functions
4. Never store context.Context in a struct field
5. `defer cancel()` immediately after context.WithCancel or WithTimeout
6. Document goroutine lifecycle in comments
## Error Handling
- Return all errors from I/O operations
- Wrap with context: `fmt.Errorf("thing: %w", err)`
- Sentinel errors: `var ErrNotFound = errors.New("not found")`
- Do not log AND return an error — choose one
## Code Style
- Exported names: CamelCase
- Single-method interfaces: -er suffix (Storer, Fetcher, Parser)
- Package names: lowercase, single word, no underscores
- Table-driven tests for functions with multiple input cases
## Testing
- Race detector: `go test -race ./...` always
- Assertions: testify/assert and testify/require
- Integration tests: `//go:build integration` tag
- Mock via interfaces defined in the consuming package
## What NOT To Do
- Discard errors with `_` in production code
- Store context in structs
- Start goroutines without documenting their termination condition
- Use init() for global state initialization — prefer explicit constructors
- fmt.Sprintf in hot paths — allocates on every call
Common Pitfalls When Writing AGENTS.md
Rules that are too general. “Write clean code” and “follow best practices” give agents nothing actionable. Every agent already tries to do those things. Effective rules are specific: “Use uv run for all commands, not python directly” or “No bare except: pass — reraise with raise SomeError(...) from original.”
Commands that don’t match the actual setup. If your AGENTS.md says pytest tests/ but your project structure puts tests at test/ or uses uv run pytest, the agent runs the wrong command and reports incorrect results. Test your AGENTS.md commands in a fresh shell before committing.
Stale rules that were true six months ago. “Use npm run test:watch for development” becomes wrong when the team switches to vitest --watch. Stale rules are worse than no rules — they actively mislead. Add a date or version note to sections that change frequently:
## Commands (verified 2026-07)
- test: `uv run pytest`
Missing “What NOT to Do” section. Agents trained on large code corpora have strong priors toward common patterns — pip install, var in JavaScript, except Exception: pass in Python. Explicit prohibitions (“Do NOT use pip install — use uv add”) override those priors more reliably than positive rules that don’t mention the alternative.
Not front-loading the critical path. For Copilot Workspace and Codex specifically, rules in the first 200 lines have stronger influence than rules at line 400. Put your most important constraints — the commands section and top critical rules — at the top of the file.
Monorepo AGENTS.md Structure
For monorepos, use a root AGENTS.md for global rules and subdirectory files for package-specific rules. Claude Code and Aider merge them; Cursor reads both with directory scoping; Codex reads the root unless configured otherwise.
/AGENTS.md # global: repo-wide commands, commit conventions, CI rules
/backend/AGENTS.md # Python API: uv, pytest, mypy rules
/frontend/AGENTS.md # TypeScript SPA: Vite, Vitest, strict TS rules
/infra/AGENTS.md # Terraform: plan/apply workflow, naming conventions
Root AGENTS.md for a monorepo:
# AGENTS.md — Monorepo Root
## Repository Layout
- backend/ — Python FastAPI service (see backend/AGENTS.md)
- frontend/ — TypeScript React app (see frontend/AGENTS.md)
- infra/ — Terraform infrastructure (see infra/AGENTS.md)
## Global Commands
- Install all: `make install`
- Test all: `make test`
- CI check: `make ci`
## Commit Conventions
- Format: `<type>(<scope>): <description>`
- Types: feat, fix, docs, refactor, test, chore
- Scope: backend, frontend, infra (matches directory name)
- Example: `fix(backend): return 404 on missing user instead of 500`
## What NOT To Do
- Commit directly to main — open a PR
- Change .github/workflows/ without team discussion
- Add global dependencies without updating all sub-package configs
Keeping AGENTS.md Current
An AGENTS.md that drifts from reality is worse than no file. Two practices prevent staleness:
Treat AGENTS.md like a test. When a CI check changes, update AGENTS.md in the same PR. When a dependency is replaced, update the install command. Make AGENTS.md changes required alongside any toolchain change.
Include a verification step. Add a line at the top:
# AGENTS.md — Last verified: 2026-07-07
# Run `make agents-check` to verify all commands are current.
The agents-check target is a Makefile rule that runs every command listed in the file and reports failures. It takes 5 minutes to write and catches stale commands before they mislead agents.
Browse real AGENTS.md files from open-source projects — including Python, TypeScript, and Go examples — in our gallery.
FAQ
Should I use AGENTS.md or CLAUDE.md for a single-tool team?
If your team uses only Claude Code, use CLAUDE.md. It supports features AGENTS.md does not: the @file import syntax, user-scoped settings, and context budget hints. If there is any chance of other tools being added, use AGENTS.md for baseline rules and CLAUDE.md for Claude-specific extensions.
Does AGENTS.md support file imports like CLAUDE.md?
No. AGENTS.md does not have an equivalent to CLAUDE.md’s @path/to/file import syntax. If you need to split instructions across files for AGENTS.md, reference them manually: “See backend/AGENTS.md for Python-specific rules.” Tools that support subdirectory files will read them; others will not.
How large should AGENTS.md be? Keep it under 300 lines for single-package projects. For monorepos, the root file should be under 150 lines (global rules only). Longer files are not ignored, but critical rules buried late in a long file get less weight from some tools. If you need more than 300 lines, use subdirectory AGENTS.md files to distribute the content.
Does GitHub Copilot in the IDE read AGENTS.md?
Copilot in the IDE (the VS Code extension) does not read AGENTS.md by default. Only Copilot Workspace (the task-oriented interface) reads it. For Copilot in the IDE, use the .github/copilot-instructions.md file, which the IDE extension reads natively.
Can I put secret values or API keys in AGENTS.md? No. AGENTS.md is committed to version control and will be indexed by GitHub and read by any AI tool that accesses the repo. Never put credentials, API keys, or any value you would not put in a public README. Use environment variables for secrets and reference them by name in AGENTS.md: “Requires DATABASE_URL environment variable.”
What happens if AGENTS.md and CLAUDE.md contradict each other? In Claude Code, CLAUDE.md takes precedence. If both files say different things about the test command, Claude Code uses the CLAUDE.md version. To avoid confusion, do not duplicate instructions across both files — use AGENTS.md for cross-tool baseline rules and CLAUDE.md for Claude-specific additions or overrides.
Related Articles
- AGENTS.md Best Practices 2026: What 60,000+ Repos Teach Us
- AGENTS.md vs CLAUDE.md: The Complete Decision Guide
- AGENTS.md for OpenAI Codex: What Works and What Doesn’t
- AGENTS.md and GitHub Copilot: How Copilot Reads It
- copilot-instructions.md: The Complete Guide
- CLAUDE.md Best Practices 2026: 12 Patterns from 100+ Real Repos
- Claude Code for Python Projects: Templates and AGENTS.md Patterns
- Browse AGENTS.md examples in our gallery