# Codex setup for a Next.js app

> How Codex reads AGENTS.md and its 32 KiB limit, runs skills as $name, blocks commands with .codex/hooks.json, and loads subagents and MCP. Real files.

*Updated 2026-10-08.*

Codex reads five things from a repo. AGENTS.md for instructions. `.agents/skills/` for skills. `.codex/hooks.json` for hooks. `.codex/agents/` for subagents. `.codex/config.toml` for MCP servers. The last three load only in a project you trust.

Below: each file, what Codex does with it, and the real version from a generated Next.js repo. Tested on Codex CLI 0.161.

## What Codex reads

| File | What it is | When it loads |
|---|---|---|
| `AGENTS.md`, root and nested | Instructions | At start, from the root down to the folder you launch in. 32 KiB per chain |
| `.agents/skills/<name>/SKILL.md` | Skills, run as `$name` | Name and description at start. The body when used |
| `.codex/hooks.json` | Hooks around tool calls | Trusted project, after you review each hook in `/hooks` |
| `.codex/agents/<id>.toml` | Custom subagents | Trusted project |
| `.codex/config.toml` | MCP servers | Trusted project |

## AGENTS.md: the chain and the 32 KiB limit

Codex builds its instructions once, when it starts:

1. `~/.codex/AGENTS.override.md` if it exists, else `~/.codex/AGENTS.md`.
2. From the project root down to your current folder, one file per folder: `AGENTS.override.md`, else `AGENTS.md`, else a fallback name you set in `project_doc_fallback_filenames`.
3. Joined root first. Closer files come later, so they win.

It stops adding files at `project_doc_max_bytes`, 32 KiB by default. Root files go in first, so a fat root file crowds out the nested ones. And files below your launch folder don't load at all.

A generated repo plans around both limits:

- **The root file stays lean.** It uses about half the budget.
- **Folder rules live in nested files.** This repo has 32 of them. Every chain, root down to the deepest folder, stays under 30 KiB. We checked that Codex CLI 0.161 loads a 28 KB chain whole.
- **A full folder links instead of copying.** When a chain runs out of room, that folder's AGENTS.md points at the rule's full text in `.agents/rules/<id>.md`.
- **The root covers the launch-folder gap.** It tells Codex to read every AGENTS.md on the path before it edits a file.

Here is the top of that root file. Note the `$setup` line: in Codex, skills start with `$`.

````markdown
# my-app

Generated by [Agentic Boilerplate](https://github.com/agentic-studio/agentic-boilerplate) from [Agentic Studio](https://theagentic.studio). Same `agentic.config.json`, same repo: regenerate and diff any time.

- **Stack:** Next.js on Vercel (`nextjs-vercel`)
- **Services:** Drizzle ORM (`drizzle`), Neon (`neon`), Better Auth (`better-auth`), Stripe (`stripe`), Resend (`resend`), Sentry (`sentry`), PostHog (`posthog`), Admin panel (`admin-panel`), MDX blog (`blog-mdx`)
- **Design:** Daylight (`daylight`). Every UI change follows [DESIGN.md](DESIGN.md).
- **Package manager:** bun
- **Mode:** solo

## Start here

On a fresh clone, run the `setup` skill: `/setup` in most agents, `$setup` in Codex.
It reads [SETUP.md](SETUP.md), which lists every environment variable, where to get
it, and the order to set the services up.

```sh
bun install
bun run setup:env -- --check   # what .env.local still needs
bun run verify
bun run dev
```
````

*First 22 of 335 lines of `AGENTS.md`.*

The full walkthrough of root and nested files: [AGENTS.md examples](/guides/agents-md-examples).

## Skills: .agents/skills and $name

Codex reads Agent Skills from `.agents/skills/<name>/SKILL.md`. At start it sees each skill's name and description. It loads the body only when it uses the skill. Run one by name with a `$` in front, or let Codex pick it from its description.

The generated repo ships 29 skills. On a fresh clone, start with `$setup`. It reads `SETUP.md`, shows a plan, and fills `.env.local` after you say yes. Then `$verify` proves every service answers.

These are the same files Cursor, Copilot, Antigravity and most other agents read. Claude Code gets a copy in `.claude/skills/`. More: [Agent Skills in every agent](/guides/agent-skills-every-agent).

## Hooks: .codex/hooks.json

Codex runs project hooks from `.codex/hooks.json`, in the same shape Claude Code uses: an event, a matcher, a command. Hooks are on by default in Codex CLI 0.161. This is the generated file:

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "apply_patch",
        "hooks": [
          {
            "type": "command",
            "command": "bun \"$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents/hooks/run.mjs\" auto-lint --from codex",
            "timeout": 60
          },
          {
            "type": "command",
            "command": "bun \"$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents/hooks/run.mjs\" enforce-doc-meta --from codex",
            "timeout": 60
          },
          {
            "type": "command",
            "command": "bun \"$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents/hooks/run.mjs\" env-leak-detector-write --from codex",
            "timeout": 60
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bun \"$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents/hooks/run.mjs\" block-destructive --from codex",
            "timeout": 60
          },
          {
            "type": "command",
            "command": "bun \"$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents/hooks/run.mjs\" enforce-typecheck --from codex",
            "timeout": 60
          },
          {
            "type": "command",
            "command": "bun \"$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents/hooks/run.mjs\" env-leak-detector --from codex",
            "timeout": 60
          },
          {
            "type": "command",
            "command": "bun \"$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.agents/hooks/run.mjs\" guard-neon-sql --from codex",
            "timeout": 60
          }
        ]
      }
    ]
  }
}
```

*`.codex/hooks.json`, as generated.*

How it works:

- **One launcher.** Every command runs `.agents/hooks/run.mjs <guard> --from codex`. The guard scripts live once in `.agents/hooks/`, shared with every agent that runs them.
- **The repo root, found by git.** `git rev-parse --show-toplevel` keeps the path right after Codex changes folder.
- **Edits arrive as one patch.** Codex sends file changes as one `apply_patch` call. The launcher splits it into one write or edit per file, then runs the guards on each.
- **Exit 2 blocks.** The reason goes back to Codex on stderr. In a live run, Codex 0.161 refused `rm -rf ./x` with "blocked by the block-destructive hook".

Two limits. A Claude Code rewrite (a bare `tsc` swapped for `bun run typecheck`) becomes a block in Codex that names the command to run instead. And hiding a secret in command output works in Claude Code only, so in Codex the check before the command is what stops a leak. `env-leak-detector` runs on shell commands only here.

Before any of it runs, trust the project, then review each hook once in `/hooks`. Codex won't run a project hook you haven't reviewed. Prove the guards still block with `bun run verify:hooks`. More: [guard hooks in every agent](/guides/ai-coding-agent-hooks).

## Subagents: .codex/agents/*.toml

Codex reads custom subagents from `.codex/agents/`, one TOML file each. `name`, `description` and `developer_instructions` are required. The top of the generated PR reviewer:

````toml
name = "pr-reviewer"
description = "Reviews a diff against this repo's rules before it becomes a PR. Convention-aware, blocking on correctness and security, advisory on taste."
sandbox_mode = "read-only"
developer_instructions = '''
You are the PR reviewer for this repository. You review a change *against the
rules this repo has already written down*, not against your own preferences.
A reviewer who invents new standards mid-review is worse than no reviewer.

## Before you read a single line of the diff

1. Read the root `AGENTS.md` and every nested `AGENTS.md` between it and each
   file the diff touches. The full text of each rule is in `.agents/rules/`.
````

*First 12 of 85 lines of `.codex/agents/pr-reviewer.toml`.*

- **`developer_instructions` holds the prompt.** The same text Claude Code's version uses.
- **`sandbox_mode = "read-only"` keeps reviewers from writing.** It's set on `pr-reviewer`, `security-auditor`, `db-inspector` and `product-analyst`.
- **Optional fields inherit.** Leave out `model` or `mcp_servers`, and the subagent uses your session's.

The generated repo ships 7 subagents. Each prompt also lives in `.agents/agents/` for agents that read that folder.

## MCP: .codex/config.toml

Codex reads MCP servers from `[mcp_servers.<name>]` tables: `~/.codex/config.toml` for you, `.codex/config.toml` for a trusted project. This is the generated one:

```toml
# Codex reads this file in a trusted project. MCP servers for this repo.
# Keys come from the shell you start Codex in. Codex never reads .env.local.

[mcp_servers.better-auth]
url = "https://mcp.better-auth.com/mcp"

[mcp_servers.neon]
url = "https://mcp.neon.tech/mcp?readonly=true"

[mcp_servers.posthog]
url = "https://mcp.posthog.com/mcp?readonly=true"

[mcp_servers.sentry]
url = "https://mcp.sentry.dev/mcp"

[mcp_servers.stripe]
url = "https://mcp.stripe.com"
```

*`.codex/config.toml`, as generated.*

- **Remote servers sign in with OAuth.** Run `codex mcp login <server>` for each one.
- **Neon and PostHog connect read-only,** through `?readonly=true`.
- **Keys come from your shell.** Codex never reads `.env.local`. A server that needs a key reads it from the environment you start Codex in.

## The Compound Engineering plugin

The generated repo works in a loop: brainstorm, plan, work, review, write down what you learned. The Compound Engineering plugin adds those commands. In Codex they start with `$`: `$ce-plan`, `$ce-work`, `$ce-code-review`. Install it once:

```bash
codex plugin marketplace add EveryInc/compound-engineering-plugin
codex plugin add compound-engineering@compound-engineering-plugin
```

Why not declare it in `.codex/config.toml`? We measured it: a marketplace declared in a project's config makes `codex plugin list` fail. `SETUP.md` prints the commands instead.

## Codex setup checklist

1. Open Codex at the repo root and trust the project.
2. Open `/hooks` and review each hook once.
3. Run `$setup`. It fills `.env.local` and connects the services, after you say yes.
4. Sign in to each MCP server with `codex mcp login <server>`.
5. Install the plugin with the two commands above.
6. Run `bun run verify:hooks` and watch every guard block in Codex's format.

## Get a Codex-ready Next.js repo

Pick your stack at [/build](/build). Codex is one of 10 agents, all on by default. You get AGENTS.md and its nested files, `.agents/` with every skill and guard, and `.codex/` with hooks, subagents and MCP for your services. The same repo works in Claude Code, Cursor, Copilot and the rest. $99 once, with lifetime updates. What each agent gets: [the agentic layer](/docs/the-agentic-layer).


Other agents: [Claude Code setup](/guides/claude-code-setup-nextjs), [GitHub Copilot setup](/guides/github-copilot-setup-nextjs), [Cursor rules](/guides/cursor-rules-nextjs).

## FAQ

### Does Codex read AGENTS.md?

Yes. Codex reads `~/.codex/AGENTS.md`, then one AGENTS.md per folder from the project root down to the folder you launch in. It joins them root first and stops adding files at 32 KiB by default.

### Does Codex read CLAUDE.md?

Not by default. List it in `project_doc_fallback_filenames` and Codex reads it in folders that have no AGENTS.md.

### Where does Codex look for skills?

In `.agents/skills/<name>/SKILL.md`. Run one as `$name`, or let Codex pick it from its description.

### Does Codex support hooks?

Yes. Project hooks go in `.codex/hooks.json` or a `[hooks]` table in `.codex/config.toml`. They run in a trusted project, after you review each one in `/hooks`. A `PreToolUse` hook that exits 2 blocks the call.

### How do I add an MCP server to Codex?

Add a `[mcp_servers.<name>]` table to `.codex/config.toml`, with a `url` for a remote server or a `command` for a local one. Or run `codex mcp add`. Sign in to a remote server with `codex mcp login <server>`.

### Why aren't my Codex hooks running?

Usually one of three things: the project isn't trusted, you haven't reviewed the hook in `/hooks`, or the command can't find its script after Codex changed folder. Build the path from the repo root, like `git rev-parse --show-toplevel`.


## Sources

- [Codex docs: Custom instructions with AGENTS.md](https://developers.openai.com/codex/guides/agents-md)
- [Codex docs: Agent Skills](https://developers.openai.com/codex/skills)
- [Codex docs: Hooks](https://developers.openai.com/codex/hooks)
- [Codex docs: Subagents](https://developers.openai.com/codex/subagents)
- [Codex docs: Model Context Protocol](https://developers.openai.com/codex/mcp)

## Generate it

[Build your repo](https://agenticboilerplate.com/build)

---

Agentic Boilerplate: A Next.js repo your agent already knows. $99 once. Lifetime access and updates.

- Site map for agents: https://agenticboilerplate.com/llms.txt
- Public API: https://agenticboilerplate.com/openapi.json
- Contact: agenticstudio@gmail.com
