# 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. Source: https://autoplans.dev/guides/agents-md ## What the file is for [agents.md](https://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: | Tool | Reads | Nested files | Notes | |---|---|---|---| | Codex | `AGENTS.override.md`, then `AGENTS.md`, in each directory from the git root down | Concatenated root-down; closer files override | Also `~/.codex`; combined size capped by `project_doc_max_bytes`, 32 KiB by default | | OpenCode | `AGENTS.md`, falling back to `CLAUDE.md` | Traverses up from the current directory | Global `~/.config/opencode/AGENTS.md`; more files via `instructions` in `opencode.json` | | Amp | `AGENTS.md`, falling back to `AGENT.md` or `CLAUDE.md` | Subtree files load when the agent works there | `@path` mentions pull in other files | | Cursor | `AGENTS.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 precedence | A single root `CLAUDE.md` or `GEMINI.md` is accepted instead | | Claude Code | `CLAUDE.md` only | Ancestors at launch, subdirectories on demand | Import the shared file with `@AGENTS.md`; see below | | Autoplans desktop app and CLI | `AGENTS.md` at the root of the folder you open | Documented for the root file | Applies to every [agent](/docs/agents); see [Configuration](/docs/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. | Section | Belongs | Does not belong | |---|---|---| | Commands | Install, dev server, test, lint, typecheck, build, and the order to run them before a commit | Every script in `package.json` | | Layout | Where things live when it is not obvious; which directories are generated or vendored | A full directory tree | | Conventions | Choices a linter cannot enforce: naming, error handling, how a migration is added | The whole style guide; put it in the linter config | | Gotchas | What bit the last three people: a flaky test, a script that only runs from one directory | Anything the agent finds within a minute | | Where the plan lives | Where current work is tracked, and how the agent reaches it | The 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](/docs/tools) — 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](/guides/ai-coding-agent-backlog). ## 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: ```text 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: ```markdown @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: ```markdown @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](/guides/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//` (project) or `~/.claude/skills//` (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 in | When | |---|---| | AGENTS.md | A fact or standing rule for most sessions: the test command, the naming convention, where the plan lives | | A skill | A multi-step procedure for some sessions: cutting a release, a security review, filing a bug | | An agent | A 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](/docs/claude-code) 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. ```markdown # 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](/guides/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](/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.