Claude Code AI rules CLAUDE.md

CLAUDE.md vs .cursorrules vs .windsurfrules vs AGENTS.md: Complete Rules Syntax Reference 2026

The Prompt Shelf ·

import ExternalLinkCard from ”../../components/ExternalLinkCard.astro”;

Every major AI coding tool ships with its own rules format. CLAUDE.md lives in Claude Code. .cursorrules and its modern replacement .mdc live in Cursor. .windsurfrules controls Windsurf’s Cascade agent. AGENTS.md is the emerging cross-tool standard adopted by OpenAI Codex, GitHub Copilot’s coding agent, Gemini CLI, and a growing list of others.

If you use more than one of these tools — or if you’re joining a repo that already has rules you need to adapt — you’ve probably noticed they don’t work the same way. A glob-scoped Cursor .mdc rule doesn’t translate directly into a CLAUDE.md section. An AGENTS.md nesting pattern has no equivalent in .windsurfrules. Shell hooks work in Claude Code but don’t exist at all in the other three.

This page is a reference dictionary, not a “which tool wins” guide. Use it to look up exact syntax, understand what each format supports, and translate rules between formats when you need portability.

Quick Comparison Table

The table below captures the fundamental properties of each format. Deeper breakdowns follow.

PropertyCLAUDE.md.cursorrules / .mdc.windsurfrulesAGENTS.md
File formatPlain MarkdownLegacy: plain .md / Modern: .mdc (YAML + Markdown)Plain text / MarkdownPlain Markdown
Primary locationProject root or .claude/CLAUDE.mdLegacy: .cursorrules (root) / Modern: .cursor/rules/*.mdcProject rootProject root (or any directory)
Global/user scope~/.claude/CLAUDE.mdCursor settings UICursor settings “Custom Instructions”~/.codex/AGENTS.md
Subdirectory scopingYes — nested CLAUDE.md files load per-directoryYes (.mdc only, via globs:)No — single file, project root onlyYes — AGENTS.md per subdirectory, concatenated root-to-current
YAML frontmatterNo (plain Markdown).mdc requires description, globs, alwaysApplyNoNo (v1.1 proposes optional description/tags)
Path-based loading.claude/rules/ with paths: frontmatterglobs: in .mdc frontmatterNot supportedDirectory walk (proximity-based)
Shell/hook executionYes — hooks fire on lifecycle eventsNoNoNo
File importsYes — @path/to/file syntaxNoNoNo
Override mechanismMore-specific file wins on conflictalwaysApply, globs, manual @mentionProject rules override globalAGENTS.override.md replaces at its level
Size limits200-line recommendation; survives /compact500-line recommendation per .mdc fileNo documented limit32 KiB combined default (project_doc_max_bytes)
Multi-tool supportClaude Code onlyCursor onlyWindsurf only20+ tools (Codex, Copilot, Gemini CLI, Windsurf, Aider, Zed, Devin…)

Format Deep Dives

CLAUDE.md (Claude Code)

File location hierarchy — Claude Code walks up the directory tree from your working directory, collecting every CLAUDE.md and CLAUDE.local.md it finds. All discovered files concatenate into context, ordered from filesystem root down to working directory (closest file is read last, giving it higher effective priority):

/Library/Application Support/ClaudeCode/CLAUDE.md   # Managed/org policy
~/.claude/CLAUDE.md                                  # User-wide preferences
./CLAUDE.md  or  ./.claude/CLAUDE.md                 # Project (committed)
./CLAUDE.local.md                                    # Personal/gitignored
./src/api/CLAUDE.md                                  # Subdirectory (lazy-loaded)

Subdirectory CLAUDE.md files are not loaded at launch. They load on demand when Claude reads files in those directories. This means large monorepos stay lean — the frontend rules don’t land in context when you’re working in the backend.

.claude/rules/ with path frontmatter — For path-scoped rules, put .md files in .claude/rules/. Files without frontmatter load every session. Files with paths: frontmatter only load when Claude reads a matching file:

---
paths:
  - "src/api/**/*.ts"
  - "lib/**/*.ts"
---

# API Rules

- All endpoints must validate inputs with Zod
- Return errors as `{ code, message, details }` objects
- Document with OpenAPI JSDoc comments

Supported glob patterns:

PatternMatches
**/*.tsAll TypeScript files recursively
src/**/*Everything under src/
*.mdMarkdown files in project root
src/**/*.{ts,tsx}Brace expansion for multiple extensions

Hooks — The most powerful CLAUDE.md-only feature. Hooks fire on lifecycle events and run real shell commands, independent of what Claude decides to do. This is the only format where you can enforce a rule mechanically rather than just instruct Claude:

// .claude/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint -- --fix $CLAUDE_TOOL_INPUT_PATH"
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "/usr/local/bin/check-dangerous-command.sh"
          }
        ]
      }
    ]
  }
}

Hook types in 2026: command (shell script), prompt (LLM evaluation), mcp_tool (calls a connected MCP server directly, added April 2026).

@path imports — CLAUDE.md can pull in other files inline. Imported files load in full at session start:

See @README.md for project overview.

# Dev Setup
@docs/setup.md

# Git Conventions
@docs/git-guide.md

Key gotchas:

  • The 200-line recommendation is a guideline, not a hard limit. Past ~200 lines, adherence degrades.
  • CLAUDE.md survives /compact. Nested subdirectory CLAUDE.md files do not re-inject automatically after compaction.
  • Path-scoped rules in ~/.claude/rules/ (user-level) have a known bug where paths: frontmatter is silently ignored. Use project-level rules for path scoping.
  • CLAUDE.md is Markdown only. No YAML frontmatter in the root file itself — frontmatter is only used inside .claude/rules/*.md files.

.cursorrules and .mdc (Cursor)

Cursor has two generations of rules format. Understanding which one you’re dealing with matters because they behave very differently.

Generation 1: .cursorrules — A single plain Markdown file at the project root. Cursor reads it automatically for every Chat and Composer session.

# .cursorrules

You are an expert TypeScript developer working on a Next.js 14 app.

## Code Style
- Use functional components only
- Prefer named exports over default exports
- Always type props explicitly; avoid `any`

## Testing
- Write Vitest unit tests for all utility functions
- Use React Testing Library for component tests

Limitations of the legacy format:

  • Not loaded in Agent mode. If a user switches to Cursor’s Agent, .cursorrules is invisible.
  • No scope control. Every rule loads for every conversation regardless of relevance.
  • No file-type targeting. Frontend rules and backend rules share the same context.

Generation 2: .cursor/rules/*.mdc — Modern format using .mdc files with YAML frontmatter. The .mdc extension is required; plain .md files in .cursor/rules/ are ignored.

---
description: "TypeScript API route conventions"
globs: ["src/app/api/**/*.ts"]
alwaysApply: false
---

# API Route Rules

- Use Next.js 14 Route Handlers (`route.ts`), not Pages Router API routes
- Validate request body with Zod before processing
- Return consistent `{ data, error }` response shape
- Handle errors with try/catch and return appropriate HTTP status codes

The four rule application types determined by frontmatter:

TypealwaysApplyglobsdescriptionBehavior
AlwaystrueLoads in every chat session
Auto AttachedfalsesetLoads when a matching file is in context
Agent RequestedfalsesetLLM reads description and decides relevance
ManualfalseOnly loads when you @mention it

Key gotchas:

  • .mdc extension is mandatory. A file named react.md in .cursor/rules/ does nothing.
  • .cursorrules at the root still works and Cursor still reads it — but not in Agent mode.
  • The 500-line recommendation per .mdc file. Split large rule sets into multiple files.
  • alwaysApply: true and globs: set simultaneously: the rule loads always and auto-attaches for matching files. Redundant but not harmful.
  • There is no cross-file import mechanism. Each .mdc stands alone.

.windsurfrules (Windsurf)

Windsurf uses a single plain-text file called .windsurfrules placed at the project root. Cascade (Windsurf’s AI agent) reads it at the start of every session.

.windsurfrules  (project root)

Format — Freeform plain text or Markdown. No required schema, no YAML frontmatter, no special syntax:

You are an expert Python backend developer. This project uses FastAPI + SQLAlchemy + PostgreSQL.

Follow these conventions:

1. Use async/await for all database operations
2. Define Pydantic v2 models for all request/response schemas
3. Write docstrings for all public functions using Google style
4. Use Alembic for all database migrations — never modify tables directly
5. Tests live in tests/ and use pytest with pytest-asyncio
6. Environment variables are loaded via python-dotenv; never hardcode credentials

Two-tier system:

  • Global rules: Set in Windsurf settings under Cascade → Custom Instructions. Applied to every project on your machine.
  • Project rules (.windsurfrules): Applied to the current project only. Committed to version control for team consistency. Project rules override global rules on conflict.

Key gotchas:

  • Single-root limitation — One .windsurfrules per project. No subdirectory scoping, no per-directory files. Monorepos must consolidate all rules into one file, which can grow unwieldy.
  • No frontmatter, no glob patterns, no conditional loading. Every line is always in context.
  • No import mechanism. Everything must be inline in the one file.
  • Windsurf also reads AGENTS.md — so a team that commits AGENTS.md gets Windsurf support without maintaining .windsurfrules separately.

AGENTS.md (OpenAI Codex + 20+ tools)

AGENTS.md is the most portable format. As of mid-2026 it’s natively supported in OpenAI Codex, GitHub Copilot’s coding agent, Gemini CLI, Windsurf, Aider, Zed, Factory, Jules, Devin, Amp, Kilo, RooCode, Augment, Warp, JetBrains Junie, and others.

Format — Pure Markdown. No required frontmatter, no required sections. Use whatever heading structure fits your project:

# Project Rules

## Code Style
- TypeScript strict mode required for all files
- No `any` types; use `unknown` and narrow explicitly
- Imports ordered: external → internal → relative

## Testing
- Run `pnpm test` before committing
- Unit tests must cover all exported utility functions
- Integration tests live in `tests/integration/`

## Git
- Commit messages follow Conventional Commits (feat/fix/chore/docs)
- Branch names: `feat/`, `fix/`, `chore/` prefixes required
- Never force-push to `main`

Nesting and hierarchy — AGENTS.md’s most powerful feature. Place AGENTS.md in any directory. Codex walks up the tree from the file being edited and concatenates every AGENTS.md it finds, root to current directory. The closest file wins on conflicts.

project/
├── AGENTS.md                    # Global project rules (always loaded)
├── src/
│   ├── AGENTS.md                # Frontend-specific rules
│   └── api/
│       └── AGENTS.md            # API-specific rules (highest priority here)
└── packages/
    └── auth/
        └── AGENTS.md            # Auth package rules

OpenAI’s own Codex monorepo ships 88 nested AGENTS.md files — one per service or package.

AGENTS.override.md — While AGENTS.md concatenates with parent files, AGENTS.override.md replaces the file at its level entirely. Use it when a subdirectory needs completely different rules, not an extension of the parent:

project/
├── AGENTS.md                    # Company standards (concatenated)
├── legacy-service/
│   └── AGENTS.override.md      # Replaces parent completely; legacy has its own rules

Global scope~/.codex/AGENTS.md applies across all projects for a user. Codex merges it with project-level files.

Key gotchas:

  • Size cap: 32 KiB combined across all concatenated files (project_doc_max_bytes). Empty files are skipped.
  • No frontmatter means no path-scoped loading. Rules in AGENTS.md are always in scope for the directory and below — granularity comes from file placement, not patterns.
  • AGENTS.override.md replaces, doesn’t extend. Choosing the wrong one can cause parent rules to disappear.
  • Tool support varies. Most tools read AGENTS.md but don’t implement the full spec identically. Codex implements nesting most faithfully.

Rule Portability Guide

Translating rules between formats isn’t always 1:1. Here are concrete before/after examples for the four most common rule categories.

Code Style Rules

Cursor .mdc → CLAUDE.md

Before (.cursor/rules/typescript.mdc):

---
description: "TypeScript coding conventions"
globs: ["**/*.ts", "**/*.tsx"]
alwaysApply: false
---

- Use strict TypeScript; no `any` types
- Prefer `const` over `let`
- Named exports only; avoid default exports

After (./CLAUDE.md or .claude/rules/typescript.md):

---
paths:
  - "**/*.ts"
  - "**/*.tsx"
---

# TypeScript Conventions

- Use strict TypeScript; no `any` types
- Prefer `const` over `let`
- Named exports only; avoid default exports

The translation is nearly 1:1. The frontmatter key changes from globs: to paths:, and the file goes in .claude/rules/ with a .md extension instead of .cursor/rules/ with .mdc.

Git and Commit Rules

AGENTS.md → .windsurfrules

Before (AGENTS.md section):

## Git Workflow
- Use Conventional Commits: `feat:`, `fix:`, `chore:`, `docs:`
- Branch names must start with `feat/`, `fix/`, or `chore/`
- PRs require passing CI before merge
- Never commit `.env` files

After (.windsurfrules section):

Git Workflow:
- Use Conventional Commits: feat:, fix:, chore:, docs:
- Branch names must start with feat/, fix/, or chore/
- PRs require passing CI before merge
- Never commit .env files

.windsurfrules is freeform, so the translation is mostly cosmetic. The main change: Markdown heading syntax works fine but isn’t required.

Testing Rules

CLAUDE.md .claude/rules/ → AGENTS.md

Before (.claude/rules/testing.md):

---
paths:
  - "**/*.test.ts"
  - "**/*.spec.ts"
  - "tests/**/*"
---

# Testing Rules

- Run `npm test` before committing
- Mock external HTTP calls; never hit real APIs in tests
- Test filenames must match the module they test: `users.ts``users.test.ts`

After (AGENTS.md or tests/AGENTS.md):

## Testing

- Run `npm test` before committing
- Mock external HTTP calls; never hit real APIs in tests
- Test filenames must match the module they test: `users.ts``users.test.ts`

The path-scope is lost. AGENTS.md doesn’t have frontmatter-based path filtering. Compensate by placing the AGENTS.md file inside the tests/ directory — it will only be loaded when the agent is working on files in that directory.

Architecture Rules

.cursorrules (legacy) → CLAUDE.md

Before (.cursorrules):

This is a Next.js 14 monorepo. Follow these architecture rules:

- API routes live in src/app/api/
- Shared types live in packages/types/
- Never import from apps/ into packages/
- Database access is only allowed in src/server/ — never in React components
- Use server actions for mutations; never call the API directly from client components

After (CLAUDE.md):

# Architecture Rules

This is a Next.js 14 monorepo.

- API routes live in `src/app/api/`
- Shared types live in `packages/types/`
- Never import from `apps/` into `packages/`
- Database access is only allowed in `src/server/` — never in React components
- Use server actions for mutations; never call the API directly from client components

For architecture rules that need enforcement (not just guidance), consider adding a Claude Code hook that checks import patterns on file save:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [{ "type": "command", "command": "npx madge --circular src/" }]
      }
    ]
  }
}

Which Format Wins for Which Use Case

Solo developer on Claude Code

Winner: CLAUDE.md

You get subdirectory scoping, shell hooks, @path imports, and the richest tooling. The 200-line discipline keeps context lean. Use .claude/rules/ to split rules by file type as the project grows.

Don’t bother maintaining .cursorrules or .windsurfrules unless you occasionally switch tools.

Team with mixed tools (some use Cursor, some use Claude Code)

Winner: AGENTS.md as core, tool-specific adapters for extensions

Commit a shared AGENTS.md at the root that covers coding standards, git conventions, and architecture. Then add tool-specific files for features only that tool supports:

project/
├── AGENTS.md           # Shared core — all tools read this
├── CLAUDE.md           # Import AGENTS.md + Claude-specific hook config
├── .cursor/rules/
│   └── react.mdc       # Auto-attached to *.tsx — Cursor only
└── .windsurfrules      # Windsurf reads AGENTS.md natively; may omit this

CLAUDE.md for a mixed-tool repo looks like:

@AGENTS.md

## Claude Code Extensions

- Use plan mode before editing anything under `src/billing/`
- Run `/review` before submitting PRs

Windsurf reads AGENTS.md natively, so .windsurfrules may be optional.

Monorepo with multiple packages

Winner: AGENTS.md nesting + CLAUDE.md subdirectory files

AGENTS.md nesting maps naturally to monorepo package structure. Each package carries its own AGENTS.md with package-specific rules. Codex, Copilot, and Gemini CLI respect the hierarchy.

For Claude Code, add package-level CLAUDE.md files. They load lazily when Claude works in that directory:

packages/
├── auth/
│   ├── AGENTS.md       # Auth rules (multi-tool)
│   └── CLAUDE.md       # Claude-specific auth rules
├── payments/
│   ├── AGENTS.md
│   └── CLAUDE.md

Avoid .windsurfrules in monorepos — a single root file can’t express package-level differences without becoming a bloated, hard-to-maintain document.

Open-source project wanting universal compatibility

Winner: AGENTS.md only

If you want contributors using any AI tool to get consistent behavior, AGENTS.md is the obvious choice. It works across 20+ tools with no per-tool maintenance. Keep it concise and focused on the rules that prevent common mistakes.

Reserve tool-specific files for features that genuinely need them (hooks, path-scoped rules) and document that they exist so contributors know where to look.

2026 Multi-Tool Strategy: Staying in Sync Without Duplication

Maintaining four separate rules files is a maintenance nightmare. The approach that works is a shared core + thin adapter layer.

The architecture

project/
├── AGENTS.md                    # Single source of truth for shared rules
├── CLAUDE.md                    # Imports AGENTS.md + Claude-specific additions
├── .cursor/rules/
│   ├── auto-attached.mdc        # Path-scoped rules Cursor can apply per filetype
│   └── always.mdc               # Rules that need alwaysApply: true for Agent mode
└── .windsurfrules               # Optional; Windsurf reads AGENTS.md natively anyway

What goes where

AGENTS.md (shared core):

  • Coding style conventions
  • Naming conventions
  • Git and PR workflow
  • Architecture constraints (“don’t import X from Y”)
  • Testing requirements

CLAUDE.md additions:

  • Hook configurations (shell commands on file save, pre-commit checks)
  • @path imports to pull in large reference docs on demand
  • Claude-specific behavioral guidance (“use plan mode for billing changes”)
  • Any instruction that benefits from subdirectory scoping

.cursor/rules/*.mdc additions:

  • Path-scoped rules for Cursor’s globs: auto-attachment
  • Agent-requested rules with rich description: for Cursor’s LLM relevance check
  • Anything that needs Cursor’s alwaysApply: true to work in Agent mode

.windsurfrules (optional): If your team uses Windsurf and it doesn’t read AGENTS.md for your setup, maintain a minimal .windsurfrules that covers only the rules most relevant to Cascade’s agentic workflows. Keep it short — there’s no scoping mechanism to keep irrelevant rules out of context.

Practical sync workflow

When you update a shared rule:

  1. Edit AGENTS.md (the source of truth).
  2. If it’s already imported in CLAUDE.md via @AGENTS.md, you’re done for Claude Code.
  3. Check whether the rule needs a Cursor .mdc equivalent (path scoping, alwaysApply for Agent mode).
  4. Update .windsurfrules only if the rule needs Windsurf-specific phrasing or your team actively uses Windsurf without AGENTS.md support.

For teams using Git hooks or CI, a simple linter that checks whether critical rules exist in all four files can catch sync drift before it causes problems.

Format Capability Matrix

CapabilityCLAUDE.md.cursorrules.mdc (Cursor).windsurfrulesAGENTS.md
Shell hook execution
File imports (@path)
Subdirectory hierarchy
Path-glob scoping❌ (proximity only)
User-global scope✅ (UI)
Override mechanismClosest winsN/AManual / alwaysApplyProject > globalAGENTS.override.md
Agent mode support
YAML frontmatterRules only✅ (required)
Works across 20+ tools
Auto-loads without config

Summary

Each format was designed for a specific tool’s mental model:

  • CLAUDE.md optimizes for power and precision: hierarchical loading, shell hooks, and file imports give you machine-level enforcement alongside Claude-read guidance.
  • .cursorrules is a quick-start legacy format. It works but loses its effect in Cursor’s Agent mode — migrate to .mdc if you use agents.
  • .mdc is Cursor’s mature format. The four rule types (always/auto/agent/manual) give fine-grained control over when rules enter context.
  • .windsurfrules is deliberately simple: one file, no schema, works. The single-root limitation becomes painful in large repos, but Windsurf’s native AGENTS.md support often means you can skip maintaining it separately.
  • AGENTS.md trades tool-specific power for universal reach. Directory-based nesting is its killer feature for monorepos. As the de facto open standard, it’s the obvious anchor for any multi-tool team.

The cleanest 2026 setup: AGENTS.md as your source of truth, CLAUDE.md importing it and adding Claude-specific hooks, and .cursor/rules/*.mdc files only for rules that genuinely benefit from Cursor’s path-scoping or agent-requested activation.

FAQ

What is the difference between CLAUDE.md and AGENTS.md?

CLAUDE.md is Claude Code’s native format. It supports shell hooks, @path file imports, and per-directory subdirectory loading — features no other format has. AGENTS.md is the cross-tool standard supported by 20+ tools including OpenAI Codex, GitHub Copilot, Gemini CLI, and Windsurf. Use CLAUDE.md for Claude-specific workflows; use AGENTS.md as the shared core when your team uses multiple AI coding tools.

Where should I place CLAUDE.md in my project?

Claude Code loads CLAUDE.md from multiple locations: ~/.claude/CLAUDE.md for user-wide preferences, the project root or .claude/CLAUDE.md for project rules, and CLAUDE.local.md for personal overrides. Subdirectory CLAUDE.md files also load on demand when Claude reads files in those directories. All files concatenate, with the closest file given higher priority on conflicts.

What is the difference between .cursorrules and .mdc files in Cursor?

.cursorrules is Cursor’s legacy format — a single plain Markdown file at the project root that is not loaded in Cursor’s Agent mode. .mdc is the modern format stored in .cursor/rules/ with YAML frontmatter defining four rule types: Always, Auto Attached, Agent Requested, and Manual. If you use Cursor’s Agent mode, migrate from .cursorrules to .mdc files.

How do I scope rules to specific file types in Claude Code?

Place .md files in .claude/rules/ and add a paths: key in the YAML frontmatter listing glob patterns — for example, paths: ["src/api/**/*.ts"]. The rule loads only when Claude reads a matching file. Files without frontmatter load every session. Note: paths: frontmatter is silently ignored in ~/.claude/rules/ (user-level); use project-level .claude/rules/ for reliable path scoping.

Which rules format should I use for a team with multiple AI coding tools?

Use AGENTS.md as the shared core — it is natively supported by 20+ tools and requires no per-tool maintenance for shared conventions. Add thin adapters for tool-specific features: CLAUDE.md for shell hooks and @path imports, and .cursor/rules/*.mdc for Cursor’s path-scoped or agent-requested rules. This avoids duplicating coding standards, git conventions, and architecture rules across four separate files.

What does AGENTS.override.md do?

AGENTS.override.md replaces the AGENTS.md at its directory level entirely, so parent AGENTS.md files do not apply. Normal AGENTS.md files concatenate from the root to the current directory, with the closest file winning on conflicts. Use AGENTS.override.md when a subdirectory — such as a legacy service — needs completely different rules rather than an extension of the parent’s rules.


Keep Secrets Out of Your Rules Files

Every example in this reference — from .windsurfrules to AGENTS.md — makes the same point: never hardcode credentials, never commit .env files, always load secrets from outside the repository. Rules files define that boundary, but they don’t enforce it at runtime. 1Password CLI’s op run injects secrets as environment variables only during execution, so your API keys and database passwords never touch disk inside the project directory — exactly the separation your rules files are trying to enforce.

Related Articles

Explore the collection

Browse all AI coding rules — CLAUDE.md, .cursorrules, AGENTS.md, and more.

Browse Rules