Codex CLI on Large Repositories: AGENTS.md, Scoping, and MCP

How to keep Codex CLI fast and accurate on big monorepos: nested AGENTS.md files, scoped prompts, structural context over MCP, and reviewable runs.

By The OpenVisio Team · · 13 min read

Codex CLI works well on a fresh, small repository almost by default. Point it at a monorepo with a few thousand files, several languages, generated code, and a decade of history, and the experience changes. Sessions start slower, the agent reads more than it needs, and its first plan sometimes targets a module that has the right name but the wrong role. None of that is a flaw specific to Codex. It is what happens to any agent that has to rediscover a large codebase from a shell at the start of every task.

This guide is about working with that reality. It covers how to write an AGENTS.md that Codex can use, how to scope tasks so the agent searches a small area instead of the whole tree, how to add structural context through MCP, and how to run sessions and non-interactive jobs so the results are reviewable. The advice is practical and mostly tool-agnostic, but the examples are written for Codex CLI.

Key takeaways

  • Codex CLI reads AGENTS.md files. Use a short root file for repo-wide facts and nested files for area-specific rules close to the code they describe.
  • Scope every task to a directory or package. The smaller the search space, the better the first plan.
  • Add an MCP server that answers structural questions (definitions, callers, dependents) so the agent stops sampling files to infer relationships.
  • Keep approvals and sandboxing strict at first; loosen them per task type once you trust the workflow.
  • Use non-interactive runs for well-defined, verifiable jobs, and interactive sessions for anything that needs judgment.

What makes large repositories hard for agents

Three properties of large codebases cause most of the friction.

Ambiguous names. A big repo has five things called client, three called config, and a utils folder in every package. Text search returns all of them. The agent has to guess which one the task means, and a wrong guess shapes everything after it.

Hidden relationships. Dependency injection, event buses, dynamic imports, and code generation create links that do not show up as a simple import. The agent can see that a function exists but not who triggers it.

Noise. Vendored code, build output, snapshots, fixtures, and lockfiles inflate every search. If they are not excluded, they compete with real source for the agent's attention.

The rest of this guide is a set of countermeasures for each of these.

AGENTS.md: the instructions Codex reads first

AGENTS.md is a plain Markdown file of instructions for coding agents. Codex CLI picks up AGENTS.md files from the repository, and when there are several, the file closest to the code being worked on is the most specific. That nesting is the main tool for large repos: global facts at the root, local facts next to the code.

A root file

# AGENTS.md

## Repository map
- `services/`: Go services, one per folder. Entry points are `services/<name>/cmd/<name>/main.go`.
- `web/`: TypeScript frontend (pnpm workspace).
- `proto/`: shared protobuf contracts. Generated code lives in `gen/` and must not be edited by hand.
- Ignore `third_party/`, `gen/`, and any `testdata/` folder when searching for logic.

## Commands
- Go tests for one service: `cd services/<name> && go test ./...`
- Regenerate protobuf code: `make proto`
- Frontend typecheck: `pnpm -C web typecheck`

## Rules
- Do not change anything under `proto/` without being asked; it is a cross-team contract.
- New service-to-service calls go through the generated clients in `gen/`, never raw HTTP.
- Keep changes inside the directory named in the task unless told otherwise.

A nested file

# services/billing/AGENTS.md

- Money is `int64` cents. Never use `float64` for amounts.
- All database access goes through `internal/store`. Handlers must not import `database/sql`.
- Run `go test ./internal/...` after any change to pricing logic; the table tests there are the spec.

The nested file is short because it only needs to say what is different about this area. When Codex works in services/billing, it gets both. For a deeper look at what belongs in these files, see writing AGENTS.md and CLAUDE.md.

What to leave out

Do not paste framework documentation, a full directory listing, or style rules your linter enforces. Every line in AGENTS.md is read on every task, and long files dilute the few rules that matter. If the agent can learn something from one quick command, it does not need to be in the file.

Scope tasks to shrink the search space

The most effective habit on a large repo is also the simplest: say where the work is. Compare two prompts.

Fix the bug where refunds are sometimes applied twice.
Fix the bug where refunds are sometimes applied twice.
Scope: services/billing. The refund flow starts at internal/refunds/handler.go.
A failing test that reproduces it is in internal/refunds/handler_test.go (TestDoubleRefund).
Do not change the public API in proto/billing.

The second prompt does three things. It shrinks the search to one service, gives a starting point, and defines done as a passing test. Codex will still explore, but from the right place.

When you do not know the starting point yourself, make finding it the first task:

Investigate only, no edits. In services/billing, find where refunds are created
and every code path that can create one. List file:line for each and explain
how they are triggered.

Splitting investigation from implementation keeps the investigation cheap and gives you a chance to correct the agent's model before it writes code.

Launch from the right directory

Starting the CLI in a subdirectory makes that subdirectory the natural working area, and nested AGENTS.md files there apply directly. For a monorepo, launching from services/billing rather than the root is often a better default for billing work. You can still reference files outside it when needed.

Exclude noise

Keep generated and vendored code out of the agent's way. Make sure .gitignore covers build output, and say in AGENTS.md which committed folders are generated or vendored. If your repo has large fixture or snapshot directories, name them as well. These small notes stop the agent from "fixing" a generated file or learning patterns from third-party code.

Add structural context through MCP

AGENTS.md handles stable facts. It cannot tell the agent, for the commit you are on, who calls ApplyRefund or which packages import internal/store. A code graph exposed over MCP can. Codex CLI supports MCP servers, configured in its configuration file in your Codex home directory, where each server is defined with the command that starts it and its arguments. Check the current Codex documentation for the exact keys, since configuration formats evolve.

Once a server is connected, the agent can make calls like these instead of grepping:

NeedStructural queryTypical result
Find the real definitionfind symbol ApplyRefundone definition with path:line
Who triggers ittrace inbound callshandler, retry worker, admin tool
What a change affectslist dependents of internal/refundsthree packages and their tests
Where to start on a vague taskresolve the task text to ranked filestop files and symbols for "double refund"

Add one line to AGENTS.md so the agent actually uses these tools: "For definitions, callers, and dependents, use the code graph MCP tools before shell search; use shell search for config keys, docs, and string literals." Without that nudge, agents tend to default to grep.

The reasoning behind graph-based context over pure text search is covered in how AI coding agents understand a codebase.

Approvals and sandboxing

Codex CLI lets you choose how much it can do without asking: from suggesting changes that you approve, to editing files automatically, to running commands with broader autonomy, with sandboxing that limits file and network access. The exact mode names and flags change between releases, so check the CLI's help output for your version.

A sensible progression for a large, shared repository:

  1. Start conservative. Require approval for commands and edits while you learn how the agent behaves on your codebase.
  2. Allow automatic edits for scoped, test-backed tasks. If the task names a directory and a failing test, letting the agent edit and run tests in a sandbox is low risk.
  3. Keep network and destructive operations gated. Package installs, migrations, and anything that touches shared infrastructure should require a human.

Work on a branch or a separate git worktree for each task so an unexpected change never lands in your main checkout.

Interactive versus non-interactive runs

Codex CLI can run a prompt non-interactively with its exec subcommand, which is useful for scripted or CI-driven jobs. The rule of thumb is to use non-interactive runs only when the task is fully specified and machine-verifiable.

Good candidates:

codex exec "In services/billing, add table-driven tests for internal/refunds/calc.go
covering zero, negative, and partial refunds. Run go test ./internal/refunds/... and
stop when it passes. Do not modify non-test files."

Poor candidates are anything with "figure out", "improve", or "clean up" in the prompt. Those need a human looking at the plan.

For non-interactive runs, always end with a check the agent must pass and a constraint on which files it may touch. Then review the diff like any other pull request; our playbook for reviewing AI agent pull requests has a checklist.

A session template for big repos

Task: <one sentence>
Scope: <directory or package>; do not edit outside it.
Start: <entry file or symbol, if known>
Done when: <test or command that must pass>
Constraints: <APIs, contracts, files that must not change>
Process: investigate first and list file:line anchors, then propose a numbered
plan, wait for approval, then implement with tests after each step.

It looks bureaucratic for a one-line fix, and you can drop fields for small tasks. On large repos, filling it in takes a minute and saves the far longer cycle of reviewing and discarding a plausible change in the wrong place.

Failure modes to watch for

  • Confident edits in the wrong module. Usually an ambiguous name. Fix by naming the scope and asking for the definition's path before edits.
  • Edits to generated code. AGENTS.md did not mark the folder as generated, or the note was too far from the code. Add a nested AGENTS.md in the generated folder that says "generated, do not edit, run make proto".
  • Missed callers. The relationship goes through an interface, event, or registry. Ask for an explicit list of callers and dependents before finishing, ideally from a code graph rather than grep.
  • Runaway sessions. The agent keeps exploring without converging. Stop, ask for a summary of what it found, and restart with a narrower scope.
  • Instruction drift. AGENTS.md describes a layout that changed. Update it in the same PR as the structural change.

Where OpenVisio fits

OpenVisio builds a code graph of a repository and exposes it to agents including Codex over MCP, with tools such as resolve_context, find_symbol, trace_calls, and get_dependents. Indexing happens locally, so source does not need to leave your machine. For humans, the same model is browsable: you can use Ask to get an explanation of a flow before you write the scope line for the agent.

Large repositories do not need a different agent. They need the agent to start each task in the right place, with the rules of that place in front of it, and with a way to check relationships instead of guessing them.

Codex CLIAGENTS.mdmonorepoMCPAI agents

See it on your own repo

Paste a GitHub URL and get the day-one walkthrough — free, in your browser.

Index a repo

Keep reading