OpenAI
- Codex
- AGENTS.md
Codex CLI and AGENTS.md: persistent instructions for the agent, from global to project
I work with Codex CLI across very different repositories, and what wasted most of my time was repeating the same things to the agent every session: which package manager I use, how I run the tests, which folders are off-limits. The AGENTS.md file is the purpose-built answer: a README for agents that Codex reads on its own and turns into persistent instructions. It isn't a proprietary OpenAI format: it's an open standard adopted by tens of thousands of projects and by many other tools. In this article I look at how Codex discovers and merges these files, from global to a single subproject, and how I write them so the agent starts each time with a clear picture.
🧭 What AGENTS.md is and why Codex reads it before working
AGENTS.md is a plain Markdown file that tells the agent how to work on the project: setup commands, how the tests run, style conventions, pull request rules, security notes. The idea is to keep it separate from README.md: the latter speaks to humans, AGENTS.md speaks to agents and collects the operational context that in a README would just be noise.
The practical difference is that Codex reads it before doing anything: at startup it builds an instruction chain — once per run, and in the TUI once per session — and puts it in front of every task. I don't need to remember to attach or cite it: if the file is there, it enters the context on its own.
One detail I appreciate is that it isn't a closed format: AGENTS.md is an open standard, now stewarded by the Agentic AI Foundation, and the same file works with many agents beyond Codex. I write the rules once and reuse them, without locking myself to a single tool.
# AGENTS.md
## Setup
- Install deps: pnpm install
- Run tests: pnpm test
## Code style
- TypeScript strict, single quotes, no semicolons
## Pull requests
- Run pnpm lint and pnpm test before committing🪜 The discovery chain: from global to project
The heart of AGENTS.md is how Codex discovers it. It starts at the global scope: in the Codex home directory (by default ~/.codex, or the one set by CODEX_HOME) it reads AGENTS.override.md if it exists, otherwise AGENTS.md. At this level it uses only the first non-empty file.
Then it moves to the project scope: from the repo root (usually the Git root) it walks down to the directory I'm in. In each directory along the path it checks, in order, AGENTS.override.md, then AGENTS.md, then any fallback names — but it includes at most one file per directory.
Finally it merges them: it concatenates from the root downward, joining the files with blank lines. Position matters, because the ones closer to my directory land later in the prompt and therefore override the more general guidance. That's how a subproject rule beats the global one without me having to delete anything.
- 01Global scope (~/.codex)Reads AGENTS.override.md if present, otherwise AGENTS.md: only the first non-empty file.
- 02From the Git root downWalks from the repo root to the current directory, a single file per level.
- 03Override and fallbacksIn each directory it checks AGENTS.override.md, then AGENTS.md, then the configured fallback names.
- 04Concatenate root → downJoins files with blank lines: the ones closest to the directory win over the more general ones.
Source: official OpenAI Codex documentation — Custom instructions with AGENTS.md.
🛡️ AGENTS.override.md, fallbacks and the limits to know
AGENTS.override.md is the escape hatch: when it exists in a directory, it takes absolute precedence over the AGENTS.md at the same level. I use it when I don't want to add rules but replace them entirely — for example in services/payments/, where the team has different test commands and its own security constraints.
If a repo already uses a different name (say TEAM_GUIDE.md) I don't have to rename everything: in config.toml I add project_doc_fallback_filenames and Codex treats them as instruction files. With the same file I set project_doc_max_bytes, the cap on the combined size: the default is 32 KiB, beyond which Codex stops adding content.
Two things I keep in mind to avoid wasting time. Empty files are ignored, so a half-written AGENTS.md simply does nothing. And there's no cache: Codex rebuilds the chain on every run, so if I've just edited the instructions I only need to relaunch it in the right directory for it to re-read them.
⚙️ config.toml: Codex's configuration, not its instructions
There's a file often confused with AGENTS.md that does a different job: config.toml, in the Codex home (~/.codex). It's written in TOML and holds no instructions for the agent, but its configuration: which model to use, the approval policy, sandboxing and — handy here — the discovery knobs seen above, project_doc_fallback_filenames and project_doc_max_bytes. In one line: config.toml says how Codex runs, AGENTS.md says what it should know about the project.
The parallel with Claude Code helps pin down the difference. There too the pair is the same, in different formats: configuration lives in settings.json (versioned and shared with the team) and settings.local.json (personal, out of version control), while the prose instructions live in CLAUDE.md — the equivalent of AGENTS.md. The syntax changes, TOML versus JSON, not the concept: one file for the machine, one for the agent.
# ~/.codex/config.toml — excerpt
# how Codex treats instruction files
project_doc_fallback_filenames = ['TEAM_GUIDE.md']
project_doc_max_bytes = 32768🔗 One rules file for Codex, Claude Code and the rest
If I work with several agents — Codex with AGENTS.md, Claude Code with CLAUDE.md, Gemini CLI with GEMINI.md, Copilot with .github/copilot-instructions.md — I don't copy the same rules into every file: I keep them in one and have the others import it. That way I have a single source of truth and the versions don't drift when I update a convention.
In practice Claude Code and Gemini CLI support an import with the @ syntax: I leave the rules in AGENTS.md and in CLAUDE.md I write just the line that includes it. The direction is my choice — what matters is having one source file and the others pointing at it, instead of four copies to keep in sync by hand.
# CLAUDE.md
@AGENTS.md
# GEMINI.md
@./AGENTS.md⚖️ AGENTS.md or instructions in the prompt: how I decide
The practical question is one: does this rule always apply, or only to the task at hand? If it always applies — conventions, commands, security guardrails — I write it in AGENTS.md, at the right level. If it's specific to that moment I say it in the chat: an explicit prompt takes precedence over any AGENTS.md, and that's how it should be.
On where to put it, I think in terms of reach. Preferences that apply everywhere (the package manager, the tone of responses) live in the global file in ~/.codex; the repo rules live in the root AGENTS.md; a module's exceptions live in an override next to the code. The more specific the rule, the closer I keep it to the files it refers to.
Global — ~/.codex/AGENTS.md
- Preferences valid across all repos
- Package manager, style, tone
- Inherited by every project I open
- Temporary override via AGENTS.override.md
Project — AGENTS.md and override
- Repo rules in the Git root
- Real build, test and lint commands
- Override next to the module that changes them
- Wins over global because it's closer
✅ The flow I follow to write a useful AGENTS.md
I don't aim for the perfect file on the first try: I start with the essentials and treat it as living documentation I update when something changes. The goal is that an agent — exactly like a new teammate — understands how to work without having to ask me.
The mini-playbook I apply, in order:
- Start at the root with an AGENTS.md covering setup, test and lint commands, style and PR rules.
- List the commands I want run: if I write them, the agent executes them and tries to fix the errors before closing the task.
- Use nested files in monorepos: one AGENTS.md per package, so each subproject has its own rules and the nearest one wins.
- Replace with an override only when I need to fully swap a level's rules, not for small additions.
- Verify what it loaded by launching Codex with a prompt like "summarize the active instructions": it confirms which files it read and in what order.
Frequently asked questions about AGENTS.md file Codex
Where do I put the AGENTS.md file so Codex reads it?
At the repository root for project rules, and in ~/.codex/AGENTS.md for global preferences that apply across all repos. Codex starts from the global file and then walks from the Git root down to the current directory, merging what it finds. The file closest to the working directory takes precedence over the more general ones.
What's the difference between AGENTS.md and AGENTS.override.md?
AGENTS.md adds to the instructions from the other levels; AGENTS.override.md instead replaces the AGENTS.md in the same directory entirely. I use the override when a module needs its own rules — different test commands, security constraints — and I don't want it to inherit the more general ones.
Does Codex actually run the commands I write in AGENTS.md?
Yes, if I list them. When I specify test or lint commands, the agent tries to run them and fix the errors before considering the task done. That's why I keep the commands up to date: an AGENTS.md with wrong instructions sends the agent in the wrong direction.
Do I have to rename my files if I already use a different name for conventions?
No. If the repo already uses, say, TEAM_GUIDE.md, I add it to project_doc_fallback_filenames in config.toml and Codex treats it as an instruction file. In the same file I can raise project_doc_max_bytes if the combined guide exceeds the default 32 KiB limit.
Are Codex's config.toml and Claude Code's settings.json the same thing?
They're the functional equivalent: both say how the agent runs, not the instructions about the project. Codex uses config.toml (TOML format) in ~/.codex; Claude Code uses shared settings.json and personal settings.local.json (JSON format). The prose instructions stay in AGENTS.md for Codex and CLAUDE.md for Claude Code.
Can I use the same rules file for Codex, Claude Code and Copilot?
Yes: I keep the rules in a single file — for example AGENTS.md — and have the others import it. Claude Code and Gemini CLI support the @ import syntax: in CLAUDE.md the line @AGENTS.md is enough. That way I avoid duplicating the conventions and the versions don't drift when I update one.
Let's talk
If this topic is relevant to you, write to me: comparing notes on code and AI is always time well spent.