AGENTS.md: what to put in it, how to structure it, and when to use a skill instead

A working template for the instruction file OpenCode, Codex and other agents read first, the sections that earn their place, and the ones that rot.

Last reviewed 2026-08-27 · View as Markdown

What the file is for

agents.md describes AGENTS.md as "a dedicated, predictable place to provide the context and instructions to help AI coding agents work on your project" — "a README for agents". It carries "the extra, sometimes detailed context coding agents need: build steps, tests, and conventions that might clutter a README".

There is no schema: "AGENTS.md is just standard Markdown. Use any headings you like; the agent simply parses the text you provide." No front matter, no reserved section names.

The agent reads it at the start of every session, so every line is paid for every session, and every wrong line is wrong every session. One more rule from the same page: "explicit user chat prompts override everything". The file sets defaults; the person typing wins.

AGENT.md vs AGENTS.md: which tools read which name

The singular is the older name, kept as a fallback rather than a default. Amp's documentation says it looks for AGENTS.md, and that "If no AGENTS.md exists in a directory, but a file named AGENT.md (without an S) or CLAUDE.md does exist, that file will be included". Amp's original AGENT.md page now redirects to agents.md, so what circulates as AGENT.md best practices points at the same file under a new name; only the filename moved. Two headings below keep the singular spelling; the file to write is the plural.

What each tool reads today, from its own documentation:

ToolReadsNested filesNotes
CodexAGENTS.override.md, then AGENTS.md, in each directory from the git root downConcatenated root-down; closer files overrideAlso ~/.codex; combined size capped by project_doc_max_bytes, 32 KiB by default
OpenCodeAGENTS.md, falling back to CLAUDE.mdTraverses up from the current directoryGlobal ~/.config/opencode/AGENTS.md; more files via instructions in opencode.json
AmpAGENTS.md, falling back to AGENT.md or CLAUDE.mdSubtree files load when the agent works there@path mentions pull in other files
CursorAGENTS.md "in the project root and subdirectories""Combined with parent directories, with more specific instructions taking precedence""An alternative to .cursor/rules"; plain Markdown, no metadata
GitHub Copilot"One or more AGENTS.md files, stored anywhere within the repository"The nearest file takes precedenceA single root CLAUDE.md or GEMINI.md is accepted instead
Claude CodeCLAUDE.md onlyAncestors at launch, subdirectories on demandImport the shared file with @AGENTS.md; see below
Autoplans desktop app and CLIAGENTS.md at the root of the folder you openDocumented for the root fileApplies to every agent; see Configuration

Write AGENTS.md, plural, at the repository root: every tool in the table except Claude Code reads that name or falls back to it, and a one-line CLAUDE.md covers Claude Code (below). A CLAUDE.md on its own is read by OpenCode, Amp and Copilot, but not by Codex unless you add the name to project_doc_fallback_filenames.

How to structure AGENT.md (now AGENTS.md), section by section

The honest answer to what to put in AGENTS.md is: whatever a new contributor would need on day one that the code does not already say. Five sections cover almost every repository, commands first.

SectionBelongsDoes not belong
CommandsInstall, dev server, test, lint, typecheck, build, and the order to run them before a commitEvery script in package.json
LayoutWhere things live when it is not obvious; which directories are generated or vendoredA full directory tree
ConventionsChoices a linter cannot enforce: naming, error handling, how a migration is addedThe whole style guide; put it in the linter config
GotchasWhat bit the last three people: a flaky test, a script that only runs from one directoryAnything the agent finds within a minute
Where the plan livesWhere current work is tracked, and how the agent reaches itThe task list itself

Commands must be copy-pasteable and true. An agent that runs pnpm test and gets "command not found" starts guessing.

Conventions is the section people over-write. The test for each line is whether a reviewer would reject a pull request that broke it. If not, it is a preference, and preferences belong in your personal global file (~/.config/opencode/AGENTS.md, ~/.claude/CLAUDE.md).

Gotchas are the highest-value lines per token and the fastest to rot, because the bug gets fixed and the warning stays. Date them.

Where the plan lives is the section most files leave out, which is why agents end up with a root TODO.md or a task list that is stale by the second session. State where the backlog is and how to reach it. In a repository linked to Autoplans that is one line: the project id sits in .autoplans/project.json, and the agent reads it and calls the project's task tool with that id — autoplans_project_tasks in the desktop app, the CLI and the OpenCode plugin, list_tasks over the MCP server — rather than listing every project. Where work is tracked in GitHub issues, say so, and which label means "ready". Either way the file points at the plan without containing it; the reasoning is in why a coding agent needs a backlog, not a prompt.

AGENTS.md for a monorepo

agents.md is explicit: "Place another AGENTS.md inside each package. Agents automatically read the nearest file in the directory tree, so the closest one takes precedence." What precedence means differs by tool. Codex concatenates every file from the root down, so a package file comes after the root file rather than replacing it. Copilot uses the nearest file. Cursor combines the nested file with its parents, "with more specific instructions taking precedence". OpenCode traverses up from the directory it started in.

Write the nested file as a delta and it behaves the same under all of them:

repo/
├── AGENTS.md                 # commands, shared conventions, where the plan lives
└── packages/
    ├── web/AGENTS.md         # only the deltas: dev server port, a framework gotcha
    └── api/AGENTS.md         # only the deltas: migrations, the test database

A package file that repeats the root file is doubled under Codex. One that contradicts it resolves in favour of the closer file under Codex, Cursor and Copilot, so the resolution order is not the problem; adherence is. Claude Code's memory page says as much: "if two rules contradict each other, Claude may pick one arbitrarily". State a rule once. Watch the total, too: Codex "stops adding files once the combined size reaches" its limit, and Claude Code's guidance is "under 200 lines" per instruction file.

AGENTS.md vs CLAUDE.md

Claude Code's documentation puts it plainly: "Claude Code reads CLAUDE.md, not AGENTS.md." The recommended fix is not two files but one importing the other. This repository does that; packages/web/CLAUDE.md is a single line:

@AGENTS.md

@path is a Claude Code import: the file is expanded into context at launch, relative paths resolve relative to the file containing the import, and imports nest to a maximum depth of four hops. Anything Claude-specific goes below the import, which is the one good reason to have content in CLAUDE.md at all:

@AGENTS.md

## Claude Code

Use plan mode for changes under `src/billing/`.

A symlink (ln -s AGENTS.md CLAUDE.md) works when there is nothing to add, but on Windows it needs Administrator privileges or Developer Mode, so the import is the portable choice.

The asymmetry matters. OpenCode, Amp and Copilot fall back to CLAUDE.md; Claude Code does not fall back to AGENTS.md, so a repository carrying only the plural file gives Claude Code nothing. The one-line import closes the gap. What belongs in the Claude-specific tail is covered in the guide to CLAUDE.md.

AGENT.md vs skills: standing instructions against reusable procedures

AGENTS.md loads whether or not the session needs it: right for facts and standing rules, wrong for procedures. Claude Code's skills documentation draws the line: create a skill "when a section of CLAUDE.md has grown into a procedure rather than a fact", because "a skill's body loads only when it's used, so long reference material costs almost nothing until you need it".

  • Claude Code skills are a SKILL.md under .claude/skills/<name>/ (project) or ~/.claude/skills/<name>/ (personal). The front matter's description tells Claude when to use it; the directory name becomes the /name command. Setting disable-model-invocation: true keeps it manual.
  • OpenCode agents are Markdown files in .opencode/agents/ (project) or ~/.config/opencode/agents/ (global). Front matter sets description, mode (primary, subagent or all), model, temperature and permission. A subagent is invoked by @-mentioning it or automatically from its description.
Put it inWhen
AGENTS.mdA fact or standing rule for most sessions: the test command, the naming convention, where the plan lives
A skillA multi-step procedure for some sessions: cutting a release, a security review, filing a bug
An agentA different persona, model or permissions: a read-only reviewer, a planner that cannot edit files

If you would resent reading a section aloud at the start of every session, it is a skill. The Autoplans desktop app and CLI are built on that split: an always-on instructions/dev-method.md, an on-demand skills/ directory holding the security review, five agents in agents.json, and your own AGENTS.md for what is specific to the repository. The Claude Code plugin does the same, with /plan, /start, /tasks and /finish as commands rather than paragraphs, and a single skill covering the task model and which tool to call.

A complete AGENTS.md example

Use the file below as an AGENTS.md template for a TypeScript monorepo. Every line is something an agent cannot derive from the code.

# AGENTS.md

## Commands

pnpm install                     # Node 22, pnpm 9 via corepack
pnpm dev                         # web on :3000, api on :4000
pnpm test                        # vitest, all packages; add --filter web for one package
pnpm lint && pnpm typecheck      # both must pass before a commit; CI runs the same

Database tests need `docker compose up -d db` and `pnpm --filter api migrate` once.
There is no seed step; tests create what they need.

## Layout

- `packages/web` — Next.js app. Route handlers live in `src/app/api/`, not `pages/`.
- `packages/api` — Fastify service. Handlers in `src/handlers/`, one per route.
- `packages/shared` — Prisma schema and client. Run `pnpm --filter shared generate` after
  editing `prisma/schema.prisma`.

## Conventions

- A new column is a migration plus a schema change in one commit. Never edit an applied one.
- Errors sent to a client go through `HttpError` in `packages/api/src/errors.ts`.

## Gotchas

- `pnpm test` from inside a package directory silently runs zero tests. Run it from the
  root with `--filter`. (2026-06)
- `packages/web` pins `sharp`; a newer version breaks the Linux build. (2026-08)

## Where the plan lives

Work is tracked in Autoplans. `.autoplans/project.json` holds the project id; read it and
call `list_tasks` with that id — `autoplans_project_tasks` in the desktop app, the CLI and
the OpenCode plugin — rather than listing projects. A finished task
goes to `waiting_for_review`, not `completed`, unless you have run the tests. Never keep
the task list here.

If the Gotchas section keeps growing, fix the gotchas rather than document more of them.

How to keep AGENTS.md up to date

Stale instructions are worse than none: the agent follows them with the same confidence as the fresh ones. The failure mode is context rot; the maintenance is mundane.

  • Every command in the file must run. When CI changes, the Commands section changes in the same pull request.
  • Let the tool draft it, then cut. OpenCode's /init "will improve it in place instead of blindly replacing it"; Claude Code's /init reads Cursor and Copilot rules, and AGENTS.md too when CLAUDE_CODE_NEW_INIT=1 is set. Both generate more than you need; delete anything the agent could find by reading the repository.
  • Date the gotchas. A warning with a date is easy to retire; one without lives forever.
  • Keep the plan out of it. The largest source of rot is a task list that was accurate the day it was written. Point at the tracker instead. With Autoplans the backlog lives in your account and the file only names the project, so nothing goes stale when the work moves. The same holds for any tracker the agent reaches through a tool, which is what the MCP server is for.
  • Add a line when the agent gets the same thing wrong twice. Not the first time; once is noise.

None of this depends on Autoplans; the template above works with nothing but a terminal. What Autoplans changes is the last section: the plan gets somewhere to live that every agent can read.

Give the agent a plan it can read.

Describe a project, get a backlog, connect it over MCP. Free, no card.

Start free