What is AGENTS.md
AGENTS.md is Codex CLI's "project memory" mechanism. It's an ordinary Markdown file where you write, in natural language, everything you want Codex to know about your project. At startup, Codex injects its contents into the system context of your conversation.
The core problem it solves: AI models are stateless — every session starts from a blank slate. AGENTS.md provides a lightweight, version-controlled way to persist project-specific knowledge for Codex to use.
AGENTS.md vs config.toml: .codex/config.toml is technical configuration (model selection, sandbox level, proxy URL). AGENTS.md is content configuration (what the project does, how to work in it, what's forbidden). They complement each other perfectly.
How Codex finds and reads AGENTS.md
Codex searches for and loads AGENTS.md in this order:
- Project root (most common):
<working-dir>/AGENTS.md - Subdirectory chain: when working on
packages/api/src/auth.ts, Codex also checkspackages/api/AGENTS.mdandpackages/AGENTS.md - User global:
~/.codex/AGENTS.md(applies across all projects — ideal for personal preferences)
Multiple AGENTS.md files are merged, with subdirectory files taking priority over parent directories, enabling fine-grained control in monorepos.
/init: Generate a Starter AGENTS.md
Not sure where to start? Type /init in the Codex interactive UI's composer input. Codex scans the current project directory, analyzes file structure and detects the tech stack, then writes a draft AGENTS.md to your project root.
# In the composer input box at the bottom:
/init
After generation, always review and manually augment it. The auto-generated draft typically identifies the tech stack and directory structure, but it won't know your team's coding conventions, forbidden paths, or business context. Adding those manually is what makes AGENTS.md genuinely valuable.
The generated AGENTS.md is written to your project root. If a file already exists, Codex will ask you to confirm before overwriting. Back up first if you have existing content.
Recommended AGENTS.md Structure
Here's a battle-tested structure template, ordered by highest value to Codex:
# Project Overview (1-3 sentences)
A SaaS subscription management platform. Backend: Node.js + Express + PostgreSQL.
Frontend: React + TypeScript. Stripe handles payments.
## Directory Structure
- `src/api/` — Express routes and controllers
- `src/services/` — Business logic (no routing here)
- `src/models/` — Sequelize ORM model definitions
- `src/frontend/` — React SPA
- `tests/` — Jest unit tests
- `generated/` — **Auto-generated. Never modify manually.**
## Tech Stack
- Runtime: Node.js 22 LTS
- Database: PostgreSQL 16 (local: Docker Compose)
- ORM: Sequelize v6
- Testing: Jest + Supertest
- CI: GitHub Actions
## Coding Conventions
- ESLint + Prettier (configured in .eslintrc, runs pre-commit)
- All functions must have JSDoc comments if they have parameters or a return value
- Database queries only in `src/services/` — never directly in route handlers
- No `any` types (TypeScript strict mode)
## Common Commands
```bash
npm run dev # Start dev server (port 3000)
npm test # Run all tests
npm run db:migrate # Run database migrations
docker-compose up -d # Start local PostgreSQL
```
## Off-Limits
- Never modify anything in `generated/`
- Never push directly to main — always use a PR
- No hardcoded API keys or secrets in code
- The Stripe webhook handler in `src/api/webhooks.ts` has signature verification logic — understand it before modifying
## Testing Notes
- Unit tests: `npm test` (covers services and models)
- Integration tests need Docker Compose running (`npm run test:integration`)
- New features must include unit tests in the corresponding `tests/` subdirectory
Real-World Examples
Node.js + TypeScript Project
# Project: User Authentication Service
JWT authentication microservice handling user registration, login, and token refresh.
Other microservices call `/auth/verify` to validate tokens.
## Stack
Node.js 22 / Express 5 / TypeScript 5.4 / PostgreSQL / Redis (refresh tokens)
## Key Conventions
- JWT signing key comes from env var `JWT_SECRET` — never hardcode it
- All passwords must be hashed with `bcryptjs`, cost factor 12
- Database connection pool config in `src/db/pool.ts` — don't create new connections
- Error response format: `{ error: string, code: string }`
## Commands
```bash
npm run dev # ts-node-dev with hot reload
npm test # Jest
npm run build # tsc compile to dist/
```
Python Project
# Project: Data Processing Pipeline
Processes user behavior logs (CSV/Parquet), generates user profile features,
outputs to ClickHouse. Triggered nightly at 2am by Airflow.
## Stack
Python 3.12 / Pandas / Polars / ClickHouse-driver / Poetry
## Conventions
- Format with Ruff (`poetry run ruff format .`)
- Type annotations required on all function parameters and return values
- Prefer Polars over Pandas (faster) — use Pandas only when sklearn compatibility is needed
- `pipelines/` contains only orchestration code, not business logic
## Directories
- `src/processors/` — Data transformation logic
- `src/loaders/` — I/O (ClickHouse, S3, local files)
- `pipelines/` — Airflow DAG definitions
- `tests/` — pytest tests
- `data/samples/` — Small sample files for local testing (gitignored)
## Commands
```bash
poetry run pytest # Run all tests
poetry run pytest -x -q # Fast-fail mode
```
Monorepo
The monorepo pattern: root AGENTS.md for global conventions, per-package AGENTS.md for package-specific details.
# Project: Full-Stack SaaS Monorepo
pnpm workspace monorepo with web frontend, API backend, and shared library.
## Packages
- `packages/web/` — Next.js 14 frontend
- `packages/api/` — Fastify API service
- `packages/shared/` — Shared types and utility functions
## Global Conventions
- Cross-package dependencies go through `@myapp/shared` — no direct source file imports across packages
- `pnpm run build` at root builds all packages in dependency order
- Commit message format: `feat(api): add avatar upload endpoint`
## Off-Limits
- No Node.js-only modules in packages/web
- packages/shared contains only pure functions and types — no I/O
# API Service (Fastify)
REST API for auth, user management, and order processing. PostgreSQL database.
## Conventions
- Routes defined in `src/routes/` — one file per resource
- Database queries only in `src/repositories/`
- All endpoints need Zod schema validation for both input and response
- Error handling via `src/plugins/error-handler.ts` — no ad-hoc try/catch for 500s
## Commands
```bash
pnpm dev # Start with hot reload
pnpm test # Vitest
pnpm db:migrate # drizzle-kit push
```
How Nested AGENTS.md Files Work
When Codex works on a file, it traverses from that file's directory up to the project root, collecting and merging all AGENTS.md files it finds.
| Scenario | Codex reads |
|---|---|
Working on packages/api/src/auth.ts |
AGENTS.md (root) + packages/AGENTS.md (if present) + packages/api/AGENTS.md (if present) |
Working on src/components/Button.tsx |
AGENTS.md (root) + src/AGENTS.md (if present) |
Global codex exec task |
~/.codex/AGENTS.md + AGENTS.md (root) |
All AGENTS.md content consumes context window space. If your monorepo stacks many large AGENTS.md files, you may end up with less room for actual conversation. Keep each file concise.
Global AGENTS.md: Personal Preferences
You can also write personal preferences in ~/.codex/AGENTS.md, which apply across all projects:
# My Preferences
- Use English for code comments and variable names
- When explaining a solution, state the conclusion first, then explain why
- Always include error handling in generated code — don't skip it
- If a task is ambiguous, ask clarifying questions before writing code
- Don't auto-install npm/pip packages — tell me what you need first
## Tech Preferences
- Frontend: React + TypeScript (not Vue)
- CSS: Tailwind CSS preferred
- Testing: Vitest preferred over Jest for new projects
- Package manager: pnpm preferred
Best Practices for Writing AGENTS.md
✅ Include This
- One-sentence project purpose: What does this project do, and who uses it?
- Key directory descriptions: Which directories are auto-generated (never edit), which hold core business logic?
- Forbidden operations: Hardcoded secrets, files that must not be deleted, logic that must not be bypassed
- Common commands: Exact commands to start the dev server, run tests, run migrations
- Coding conventions: Layering rules, naming patterns, things Codex can't infer from code alone
- Important context: Why you chose a particular approach ("we use Polars not Pandas for performance")
❌ Avoid This
- Long project history: Codex doesn't need to know when the project was started
- Restating what code already expresses: If the code has clear comments, no need to duplicate in AGENTS.md
- Very long files: AGENTS.md is fully injected into context. Keep it under 300-500 lines
- Vague instructions: "Write high-quality code" has no actionable meaning — replace with specific, measurable requirements
- Rapidly-changing info: Version numbers, API endpoints — these belong in config files, not AGENTS.md
Rule of thumb: Every time you find yourself explaining "this is a … project" or "don't touch …" in a Codex session, that's content that belongs in AGENTS.md — so you never have to repeat it.
Using AGENTS.md in CI/CD
Many users don't realize: codex exec (non-interactive mode) also reads the project's AGENTS.md. This means your automated Codex tasks in GitHub Actions or local scripts have full awareness of all project conventions.
# .github/workflows/codex-changelog.yml
name: Generate Changelog with Codex
on:
push:
branches: [main]
jobs:
changelog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '22' }
- run: npm install -g @openai/codex
- run: |
# codex exec reads AGENTS.md — knows the changelog format rule
codex exec "Update CHANGELOG.md based on the latest git diff"
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
Because AGENTS.md specifies "Use Keep a Changelog format", the output is automatically formatted correctly — no need to repeat the instruction in the exec prompt.
Want more CI/CD integration patterns? See the Codex CLI CI/CD Integration Guide — complete GitHub Actions and GitLab CI YAML examples.
Commit AGENTS.md to Version Control
Strongly recommended: commit AGENTS.md to your Git repository (don't add it to .gitignore). Why:
- Team consistency: Everyone using Codex gets the same project understanding
- Audit trail: See when conventions were added and why
- CI/CD effectiveness: GitHub Actions checkouts include AGENTS.md, so automated tasks have project context
- Documentation value: A well-written AGENTS.md is excellent onboarding documentation for new team members
FAQ
Where do I put AGENTS.md?
In your project root directory, alongside package.json or pyproject.toml. Codex finds and loads it automatically at startup. You can also place nested AGENTS.md files in subdirectories — Codex merges all relevant ones when working on files in that subtree.
What's the difference between AGENTS.md and .codex/config.toml?
config.toml is technical configuration — model, sandbox level, proxy. AGENTS.md is project context — what the project does, coding conventions, forbidden operations, useful commands. They're complementary: config.toml controls how Codex runs, AGENTS.md tells Codex what your project is.
Does codex exec also read AGENTS.md?
Yes. codex exec reads AGENTS.md from the project root (and relevant subdirectories) at startup, giving non-interactive runs the same project context as interactive sessions. This is key to making automated tasks more accurate.
How long should AGENTS.md be?
Keep it under 400 lines. AGENTS.md is fully injected into the context window, so longer files reduce the space available for conversation. Prioritize: project purpose, key directory descriptions, forbidden operations, build commands, and conventions Codex can't infer from code alone.
Can I disable AGENTS.md loading?
Yes — set disable_agents_md = true in .codex/config.toml. But this is rarely the right move. If a file's content is confusing Codex, fix the content rather than disabling the whole mechanism.
Can team members have different personal AGENTS.md alongside the shared one?
Yes — two layers. The project AGENTS.md (committed to Git) holds team-wide conventions. Each person puts their individual preferences in ~/.codex/AGENTS.md (global, not committed) — things like "explain in bullet points" or "prefer Vitest". Both are merged at runtime.