Skip to content

Configuration reference

Cursor, Claude Code and Codex read project instructions from different files: Cursor from .cursor/rules/*.mdc, Claude Code from CLAUDE.md (and AGENTS.md when no CLAUDE.md exists, from v2.1.277 on the latest channel), Codex from an AGENTS.md chain plus config.toml. Loading order, scoping and size limits differ, and none of the tools warns when a rule fails to load (checked on Claude Code 2.1.283, Codex CLI 0.157.1 and @cursor/sdk 1.0.32).

This reference is for the developer or tech lead who owns a repository’s agent configuration. The typical failure is quiet: a rule scoped to API routes fires on every file, a personal CLAUDE.local.md stops Claude Code from reading the team’s AGENTS.md, or Codex drops the package instructions you wrote last week because the chain crossed its byte budget. Nothing errors. The agent just stops following the rule.

What this configuration reference gives you

Section titled “What this configuration reference gives you”
  • One table of which file each tool loads, from where, and when.
  • Minimal, correct templates for .cursor/rules/*.mdc, CLAUDE.md, .claude/settings.json, AGENTS.md and config.toml.
  • A one-source-of-truth layout for teams that use more than one tool.
  • Commands that prove which instructions actually loaded, plus a CI budget check you can paste into a workflow.
  • The silent failures, each with its recovery step.

For what to put in these files and what to cut, see Pruning CLAUDE.md and AGENTS.md. This page covers where the files go and how each tool loads them.

Cursor†Claude CodeCodex
Instruction file.cursor/rules/**/*.mdcCLAUDE.md or .claude/CLAUDE.md; AGENTS.md when no CLAUDE.md existsAGENTS.md in each directory from the project root to the working directory
Scoped rulesglobs in .mdc frontmatter.claude/rules/*.md with paths frontmatterBy directory only: a nested AGENTS.md
Personal, uncommittedNot a repository fileCLAUDE.local.md (add it to .gitignore)AGENTS.override.md (add it to .gitignore)
User-levelCursor settings~/.claude/CLAUDE.md, ~/.claude/rules/~/.codex/AGENTS.md
Settings and permissionsCursor settings.claude/settings.json, .claude/settings.local.json~/.codex/config.toml, .codex/config.toml in a trusted project
MCP servers.cursor/mcp.json, ~/.cursor/mcp.json.mcp.json (project scope)[mcp_servers.<name>] in config.toml
Older formats still read.cursorrules (applied as an always-on rule).claude/commands/*.md (still works; now part of skills)[profiles.<name>] tables (still parsed)
Check what loadedAsk the agent (see the prompt below)/context, /doctor prompt-auditcodex debug prompt-input

† The Cursor column follows the rule loader in Cursor’s agent SDK, @cursor/sdk 1.0.32; see the note below.

Each rule is one .mdc file: YAML frontmatter, then Markdown. Three frontmatter fields decide when the rule enters the context.

---
description: "API route conventions for the Next.js App Router"
globs: src/app/api/**/*.ts
alwaysApply: false
---
- Validate every request body with the zod schema in `src/lib/schemas/`.
- Call the service layer; never query the database from a route.
- Return `{ ok: true, data }` or `{ ok: false, error }` with a matching status code.
- Run `npm run test -- src/app/api` before reporting the task complete.

The fields are checked in a fixed order, and the first matching row wins:

FrontmatterRule typeWhen it loads
alwaysApply: trueAlwaysEvery request, whatever globs says
globs setFile-scopedWhen the agent works with a matching file
Only descriptionAgent-selectedWhen the agent judges the description relevant
None of the threeManualOnly when you attach the rule yourself

globs takes a comma-separated string (src/**/*.ts, src/**/*.tsx); a YAML list also works. Keep one topic per file and name files after the topic (api-routes.mdc, testing.mdc), so a reviewer can see from the file list what is always on. For setup inside the editor, see Cursor project rules.

Claude Code: CLAUDE.md, rules and settings

Section titled “Claude Code: CLAUDE.md, rules and settings”
LocationScopeWhen it loads
Managed policy file (/etc/claude-code/CLAUDE.md on Linux, /Library/Application Support/ClaudeCode/CLAUDE.md on macOS)Every user on the machine; cannot be excludedAt launch
~/.claude/CLAUDE.md, ~/.claude/rules/You, in every projectAt launch
./CLAUDE.md or ./.claude/CLAUDE.md, and each one in a parent directoryThe team, through version controlAt launch, root first
./CLAUDE.local.mdYou, in this projectAt launch
src/billing/CLAUDE.md (below the working directory)That part of the treeWhen Claude reads a file there
.claude/rules/*.md without pathsThe projectAt launch
.claude/rules/*.md with pathsMatching filesWhen Claude reads a matching file

Files are concatenated, not overridden, so a contradiction between two of them is resolved arbitrarily. Anthropic’s memory documentation recommends keeping each CLAUDE.md under 200 lines. A path-scoped rule looks like this:

---
paths:
- "src/api/**/*.ts"
---
- Validate input with the zod schemas in `src/api/schemas/`.
- Errors use the `ApiError` class; never return a raw stack trace.

A lean project CLAUDE.md holds what the agent cannot read from the code: commands, boundaries and pitfalls.

CLAUDE.md
@AGENTS.md
## Claude Code only
- Use plan mode for any change under `src/billing/`.
- Before reporting done: `npm run typecheck && npm run lint && npm test`.

@path imports keep a long file organised, but they do not save context: imported files load at launch with the file that imports them. Block-level HTML comments (<!-- note -->) are stripped before injection, so maintainer notes cost no tokens.

From v2.1.277, Claude Code reads AGENTS.md when there is no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md in the working directory or above it. v2.1.281 extended this to Amazon Bedrock, Google Cloud, Foundry, LLM gateways and telemetry-off sessions. On 2026-09-26 both versions were on the latest release channel only; the stable channel (2.1.274) still reads CLAUDE.md only. The Project instructions setting in /config changes the default:

ValueWhat Claude reads
claude-md-or-agents-md (default)CLAUDE.md files, or AGENTS.md when there is no CLAUDE.md
claude-md-and-agents-mdBoth, each directory’s CLAUDE.md first; a file already imported is not read twice
claude-mdCLAUDE.md files only
managed-onlyOnly the managed CLAUDE.md and auto memory at launch

The @AGENTS.md import in the template above works on every channel and never loads the file twice, which makes it the safe choice for a team on mixed versions.

.claude/settings.json: permissions, not context

Section titled “.claude/settings.json: permissions, not context”

Settings control what Claude may do; they add no instructions. Precedence, highest first: managed settings, command-line arguments, .claude/settings.local.json, .claude/settings.json, ~/.claude/settings.json. List keys such as permissions.allow merge across files instead of replacing each other.

{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": ["Bash(npm run lint)", "Bash(npm run test *)", "Bash(npx tsc --noEmit)"],
"deny": ["Bash(git push *)", "Read(./.env)", "Read(./.env.*)"]
}
}

Two rules catch teams out. allow rules from a committed file apply only after each teammate trusts the folder. And auto or bypassPermissions as permissions.defaultMode is ignored in project and local settings; it takes effect only from user settings, a --settings file or managed settings. Skills go in .claude/skills/<name>/SKILL.md; existing .claude/commands/*.md files keep working. For the full walkthrough, see Claude Code configuration and the Claude Code memory system.

Codex walks up from the working directory to the project root (the nearest directory containing .git, unless project_root_markers says otherwise). It then reads one file per directory, root first, and concatenates them. In each directory it takes the first file that exists from this list:

  1. AGENTS.override.md: a personal replacement for that directory’s AGENTS.md. Parent directories still load.
  2. AGENTS.md.
  3. Each name in project_doc_fallback_filenames, in order.

Files below the working directory are not read, so start Codex in the package you are changing (codex --cd packages/api). The global ~/.codex/AGENTS.md arrives as user instructions and does not count against the project budget. A project marked untrusted supplies no AGENTS.md at all (since Codex CLI 0.150.0).

Codex merges config.toml layers in this order, later winning: /etc/codex/config.toml, ~/.codex/config.toml, a profile selected with --profile <name> (~/.codex/<name>.config.toml), .codex/config.toml files from the project tree, then -c key=value flags. Project layers apply only in a trusted project, so a committed .codex/config.toml is a real team setting once each developer trusts the repository. Administrators enforce limits in requirements.toml, which users cannot override.

# .codex/config.toml (committed) or ~/.codex/config.toml (personal)
# Leave `model` unset to follow Codex's bundled default; pin a model only when your evals say so.
approval_policy = "on-request" # untrusted | on-request (default) | granular | never
# Permission profiles are beta (Codex CLI 0.138.0 and later).
# Built-ins: ":read-only", ":workspace", ":danger-full-access". Do not combine with sandbox_mode.
default_permissions = ":workspace"
project_doc_max_bytes = 32768 # default: 32 KiB across all project AGENTS.md files
project_doc_fallback_filenames = ["CLAUDE.md"] # read CLAUDE.md where a directory has no AGENTS.md
[mcp_servers.playwright]
command = "npx"
args = ["@playwright/mcp@latest"]

On the command line, -a accepts only on-request and never in Codex CLI 0.157.1; untrusted and granular are config.toml values. Put the flag before a subcommand: codex -a never exec "…". Current model names and defaults live on the models hub. For the full option set, see Codex configuration and writing AGENTS.md for Codex.

How do you share one instruction set across all three tools?

Section titled “How do you share one instruction set across all three tools?”

Make AGENTS.md the source of truth: Codex reads it natively and Claude Code reads or imports it. Cursor gets its own copy in .cursor/rules/. Then add only what each tool needs on top.

AGENTS.md # shared: stack, commands, boundaries, done criteria
packages/api/AGENTS.md # package rules; Codex reads it directly
CLAUDE.md # "@AGENTS.md" plus Claude-only notes
.claude/rules/api.md # paths: packages/api/** (Claude's copy of scoped rules)
.cursor/rules/project.mdc # alwaysApply: true (Cursor's copy of the shared layer)
.cursor/rules/api-routes.mdc # globs: packages/api/**/*.ts (Cursor's scoped rules)
.codex/config.toml # project_doc_max_bytes, approval policy, MCP servers

Restate the shared layer in one alwaysApply: true rule, .cursor/rules/project.mdc, and mirror package rules with globs, such as packages/api/**/*.ts. File-type scoping that a directory cannot express, such as **/*.test.ts, also belongs in a .mdc rule.

When the duplicated scoped rules start to drift, a sync tool can generate them from one source; see rules sync tools.

How do you prove which instructions loaded?

Section titled “How do you prove which instructions loaded?”

Reading every instruction file after each change does not scale. Check what the agent actually received, gate the size in CI, and give the files an owner.

  1. Add a canary line. Put a short, unique sentence in each file, such as Instruction set: api-rules-2026-09. It costs a few tokens and makes loading visible.

  2. Inspect the loaded context.

    Open a file the rule should cover, then run the prompt at the end of these steps. Every file-scoped rule you expect must appear by its canary.

  3. Gate the Codex budget in CI. The script fails when any root-to-leaf chain exceeds 32 KiB. Run it from the repository root. It counts AGENTS.override.md and AGENTS.md only; if you set project_doc_fallback_filenames, add those names to names, or a repository that relies on CLAUDE.md passes with nothing measured.

    #!/usr/bin/env bash
    # Fails when any root-to-leaf instruction chain exceeds Codex's default 32 KiB budget.
    set -euo pipefail
    limit=32768
    # Names Codex looks for in each directory, in order. If you set
    # project_doc_fallback_filenames, append those names too, e.g. CLAUDE.md.
    names=(AGENTS.override.md AGENTS.md)
    match=(-false)
    for name in "${names[@]}"; do match+=(-o -name "$name"); done
    status=0
    while IFS= read -r leaf; do
    dir=$leaf
    total=0
    while :; do
    for name in "${names[@]}"; do
    if [ -f "$dir/$name" ]; then
    total=$((total + $(wc -c < "$dir/$name")))
    break
    fi
    done
    [ "$dir" = "." ] && break
    dir=$(dirname "$dir")
    done
    if [ "$total" -gt "$limit" ]; then
    echo "over budget: $total bytes in the chain ending at $leaf/"
    status=1
    fi
    done < <(find . \( "${match[@]}" \) -not -path '*/node_modules/*' -exec dirname {} \; | sort -u)
    exit "$status"
  4. Assign an owner. Instruction files change agent behaviour on every run, so review them like code. The tech lead, or whoever owns the build, approves changes through CODEOWNERS:

    AGENTS.md @your-org/eng-leads
    **/AGENTS.md @your-org/eng-leads
    CLAUDE.md @your-org/eng-leads
    .claude/ @your-org/eng-leads
    .cursor/rules/ @your-org/eng-leads
    .codex/ @your-org/eng-leads

Replace @your-org/eng-leads with your own team handle. Organisation-wide policy that individuals must not override belongs in managed settings rather than in the repository; see managed agent policy.

SymptomCauseRecovery
A Cursor rule scoped to API routes applies to every filealwaysApply: true overrides globsSet alwaysApply: false; keep globs
A Cursor rule never loadsThe file ends in .md, not .mdc, or sits outside .cursor/rules/Rename to .mdc under .cursor/rules/
Claude Code stopped following the team’s AGENTS.mdSomeone added CLAUDE.local.md or a CLAUDE.md, which switches the fallback offPut @AGENTS.md at the top of CLAUDE.md, or set Project instructions to claude-md-and-agents-md
Claude Code ignores AGENTS.md on one laptopThat install is on the stable channel (below v2.1.277) or disabled the built-in agents-md pluginUse the @AGENTS.md import; it works on every version
Claude Code forgets an instruction after /compactThe instruction was given only in chat, or it lives in a nested file or path-scoped rule that has not reloadedMove it into the root CLAUDE.md; nested files reload when Claude reads a file there
Codex ignores the newest package rulesThe chain exceeded project_doc_max_bytes; the crossing file was cut and later files skippedRun the budget script, trim the root file, or raise project_doc_max_bytes
Codex ignores packages/api/AGENTS.mdCodex was started at the root; files below the working directory are not readStart Codex with --cd packages/api
Codex ignores the committed .codex/config.toml or all project AGENTS.md filesThe project is not trusted, or is marked untrustedTrust the project when Codex asks, then re-run codex debug prompt-input
codex -a untrusted fails with “invalid value”In 0.157.1, -a accepts only on-request and neverSet approval_policy = "untrusted" in config.toml
defaultMode: "auto" in .claude/settings.json has no effectProject and local settings cannot set auto or bypassPermissionsSet auto in user or managed settings; never set bypassPermissions outside a disposable, network-restricted sandbox

Frequently asked questions

Which configuration file does each AI coding tool read?

Claude Code reads CLAUDE.md, and reads AGENTS.md when a project has no CLAUDE.md (from v2.1.277, the latest channel). Cursor loads project rules from .cursor/rules/*.mdc. Codex reads AGENTS.md files from the project root down to its working directory, plus config.toml for settings.

Does Claude Code read AGENTS.md?

Yes, from v2.1.277 (the latest channel): in a project with no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md, Claude Code reads AGENTS.md instead. When both exist it reads only CLAUDE.md unless you set Project instructions to claude-md-and-agents-md in /config, or put @AGENTS.md at the top of CLAUDE.md.

Do CLAUDE.md imports reduce context usage?

No. Files pulled in with @path imports load at launch together with the CLAUDE.md that imports them. Only path-scoped rules in .claude/rules/, skills, and CLAUDE.md files in subdirectories defer loading.

What happens when Codex instruction files exceed the size budget?

project_doc_max_bytes (default 32 KiB) caps the combined size of the project AGENTS.md files. The file that crosses the limit keeps only its first bytes, and every file after it is skipped. Files load root first, so the most specific instructions are the ones cut.

Why does a scoped Cursor rule apply everywhere?

In the rule loader of Cursor's @cursor/sdk 1.0.32, alwaysApply: true wins over globs, so a rule with both is always on. Set alwaysApply: false and keep the rule in a .mdc file: that loader does not load a .md file in .cursor/rules/ as a project rule.