Every coding agent needs the same handful of facts before it can be useful in your repository: which package manager, which test command, which directories are off limits. Without them it guesses, and a wrong guess costs a review cycle.
AGENTS.md is the file those instructions go in. It is a plain Markdown file at the root of a repository, described by its own site as "a simple, open format for guiding coding agents, used by over 60k open-source projects," and it is now stewarded by the Agentic AI Foundation under the Linux Foundation. The interesting question is not what the spec permits. It is what teams actually write, so we went and measured.
What AGENTS.md Actually Is
AGENTS.md is a Markdown file that coding agents read before working on your repository, containing the build, test and convention details a human contributor would learn from a README plus a few weeks on the team. There is no schema, no required fields and no frontmatter. Any heading you like, any prose you like.

The site's framing is "a README for agents": README.md stays aimed at humans, and the build steps, test invocations and conventions that would clutter it move next door. That split is the whole design. It is also why the format spread quickly, because adopting it costs one file and breaks nothing.
Support is broad rather than deep. The agents.md site lists OpenAI Codex, Google Jules, Gemini CLI, GitHub Copilot's coding agent, Cursor, Factory, Aider, goose, opencode, Zed, Warp, VS Code, Devin, JetBrains Junie, Windsurf, Amp, RooCode and others as reading it. Each decides for itself what to do with the contents.
What 24 Real Repositories Actually Put in Theirs
Guidance about AGENTS.md is plentiful and evidence is not, so we checked 24 well-known public repositories for a root AGENTS.md on September 14, 2026, and measured what was in each one. This script needs Node 18 or newer and no dependencies.
js// agents-md-survey.mjs - Node 18+, no dependencies. Run: node agents-md-survey.mjs const REPOS = [ "openai/codex", "sourcegraph/amp-examples", "google-gemini/gemini-cli", "block/goose", "sst/opencode", "zed-industries/zed", "Aider-AI/aider", "microsoft/vscode", "apache/airflow", "temporalio/temporal", "vercel/next.js", "shadcn-ui/ui", "denoland/deno", "oven-sh/bun", "pydantic/pydantic", "astral-sh/uv", "langchain-ai/langchain", "run-llama/llama_index", "supabase/supabase", "tailwindlabs/tailwindcss", "cloudflare/workers-sdk", "grafana/grafana", "prisma/orm", "ariga/atlas", ] const out = [] for (const repo of REPOS) { let found = null for (const b of ["main", "master"]) { const r = await fetch(`https://raw.githubusercontent.com/${repo}/${b}/AGENTS.md`) if (r.ok) { found = await r.text(); break } } if (!found) { out.push({ repo, has: false }); continue } const headings = [...found.matchAll(/^#{1,3}\s+(.+)$/gm)].map((m) => m[1].trim()) out.push({ repo, has: true, words: found.split(/\s+/).filter(Boolean).length, headings }) } const withFile = out.filter((r) => r.has) const words = withFile.map((r) => r.words).sort((a, b) => a - b) console.log(`sampled ${out.length}, have AGENTS.md: ${withFile.length}`) console.log(`words: min ${words[0]}, median ${words[Math.floor(words.length / 2)]}, max ${words.at(-1)}`) for (const r of withFile.sort((a, b) => b.words - a.words)) console.log(`${r.repo.padEnd(28)} ${String(r.words).padStart(5)} ${r.headings.slice(0, 4).join(" | ").slice(0, 60)}`)
The result:
textsampled 24, have AGENTS.md: 14 words: min 1, median 1217, max 5067 apache/airflow 5067 AGENTS instructions | Naming | Environment Setup | Commands openai/codex 3128 Rust/codex-rs | The `codex-core` crate | Code Review Rules langchain-ai/langchain 2632 Global development guidelines for the LangChain monorepo prisma/orm 1343 Agents - Prisma 8 | Start Here | Modular Onboarding sst/opencode 1234 Branch Names | Commits and PR Titles | Style Guide grafana/grafana 1220 AGENTS.md | Project Overview | Principles | Comments temporalio/temporal 1217 Core Mandates | Tone and Style | Development Guide cloudflare/workers-sdk 1107 AGENTS.md | Start Here | Common Commands | Repository Map block/goose 865 AGENTS Instructions | Contribution Workflow | MCP Server supabase/supabase 695 Supabase Monorepo | Structure | Common Commands | CI astral-sh/uv 350 microsoft/vscode 33 VS Code Agents Instructions zed-industries/zed 1 oven-sh/bun 1
Fourteen of 24 had one, with a median of 1,217 words. The most repeated headings across those files were variations on commands (three files), testing (two), project overview (two) and structure (two). Nothing exotic: the format is being used for exactly the build-and-test facts its site suggests.
The Pattern Nobody Documents
Look at the bottom of that table. Two files are one word long, and one is 33.
Fetch them and the reason is obvious. zed-industries/zed has an AGENTS.md whose entire content is .rules, and oven-sh/bun has one whose entire content is CLAUDE.md. Both are symlinks, not documents. microsoft/vscode does the same thing in prose, with 33 words pointing at its Copilot instructions file. astral-sh/uv has 350 words and no headings at all, just a bullet list of rules in capital letters.
So the dominant real-world pattern among teams that already had an agent instructions file is not to write a new one. It is to make AGENTS.md an alias for what they already maintain. If you have a working CLAUDE.md, ln -s CLAUDE.md AGENTS.md gets you compatibility with every tool in the list above and nothing to keep in sync.
How Many Nested Files You Actually Need
Nested AGENTS.md files, where a subdirectory overrides the root, are the format's most discussed feature. Several guides claim OpenAI's own Codex repository ships dozens of them.
It does not. Querying the GitHub trees API for openai/codex on September 14, 2026 returns exactly two files ending in AGENTS.md: the root one, and codex-rs/tui/src/bottom_pane/AGENTS.md. The response was not truncated.
Bashcurl -s "https://api.github.com/repos/openai/codex/git/trees/main?recursive=1" \ | python3 -c "import sys,json; t=json.load(sys.stdin)['tree']; \ print(len([x for x in t if x['path'].endswith('AGENTS.md')]))"
2
The team that created the format, working in a large Rust and TypeScript monorepo, needed one override. Treat nesting as something you add when a directory genuinely contradicts the root, not as an architecture to plan up front.
AGENTS.md, CLAUDE.md and .cursorrules
These are the same idea with different readers. CLAUDE.md is Claude Code's file, .cursorrules was Cursor's original format, and AGENTS.md is the vendor-neutral one now under Linux Foundation stewardship. A repository can carry all three, which is how most teams got here: a file per tool, drifting apart.
The practical resolution is to pick one file as the source of truth and make the rest point at it. Which one you pick matters less than having a single place, because every version you maintain separately is one more chance for an agent to read a stale test command.
How to Write One That Earns Its Place
- Start with the commands. The three that matter are install, test and lint, written exactly as they should be run. This is the single highest-value content in the file and the most common heading in the survey above.
- Say what is off limits. Generated directories, vendored code, migration files that must never be edited after merge. Agents will happily rewrite all three.
- Write rules, not philosophy. The
astral-sh/uvfile is 350 words of capitalized imperatives with no headings and it works, because every line is checkable. - Keep it short enough to always be read. The file is prepended to the agent's context on every request, so its length is a per-request cost. Measure it before it grows past a couple of thousand words.
- Symlink rather than duplicate. If a CLAUDE.md or
.cursorrulesalready exists and is maintained, make AGENTS.md an alias instead of a second copy. - Nest only on contradiction. One override in a monorepo the size of Codex is the realistic number.
Conclusion
AGENTS.md is a one-file, zero-dependency convention that most large projects have either adopted or aliased to something they already had. The measurable pattern across 24 repositories is unglamorous and useful: a thousand words or so, heavy on commands and testing, light on nesting, and increasingly a pointer to a file that already existed. Before you write a long one, check whether your repository needs a new document at all, or just a symlink.
Related DevToolLab Tools
- AI IDE Config Generator - draft the AGENTS.md, CLAUDE.md or
.cursorrulesskeleton from your stack instead of starting at an empty file. - AI Token Counter - measure what your instructions file costs in context on every single agent request, which is the budget nobody tracks.
- Markdown Table Generator - build the commands table that turns out to be the most reused section in real files.
- Word Counter - check your file against the 1,217-word median from the survey above before it quietly doubles.
Related Guides
- Claude Code Skills Setup Guide - the layer above an instructions file, for packaging repeatable workflows.
- Spec-Driven Development With AI Agents - where steering documents and specs fit alongside AGENTS.md.
- OpenCode Guide - one agent's
/initflow for generating the file from an existing codebase. - Best Background Coding Agents - the tools that read this file, and how much each one actually respects it.
