Every AI coding tool now expects a config file. Claude Code reads CLAUDE.md. Cursor used to read .cursorrules but switched to .cursor/rules/*.mdc. OpenAI Codex reads AGENTS.md. And there's SOUL.md, which Aaron Mars created as a tool-agnostic standard.
I've been maintaining configs for all four systems across different projects since late 2025. Some are 20 lines. Some are 200. The quality of my AI output varies wildly depending on which format I use and how well I've written it.
Why Config Files Are the Most Important File in Your Project
Bold claim. I'll back it up.
Last month I tested the same TypeScript project with Claude Code - one with no CLAUDE.md, one with my usual config. Without it, the model added an npm package for something I already had a utility for. Used any types in three places. Put business logic in a route handler. With the config? Clean code that followed every convention. Same model, same prompt, different output.
The config closes the gap between "AI that generates code" and "AI that generates code for your project." I covered my full setup in a separate post. This article is about the broader ecosystem. Four formats. Four philosophies. One goal.
Think of it this way. package.json tells Node what to install. tsconfig.json tells TypeScript how to compile. Your AI config tells the model how to think about your project. As I wrote in my AI tools guide, the tooling only works as well as the instructions you give it.
CLAUDE.md: Anthropic's Layered System
Three levels: global (~/.claude/CLAUDE.md), project root, and subdirectory. Global sets universal preferences. Project defines architecture. Subdirectory handles module rules.
The layering is the best part. My global file is 15 lines about reading files before editing, running tests, not adding deps without asking. The project file is where the real work happens.
# Project: Payment Service
Stack: Node.js, TypeScript, Fastify, Drizzle ORM, PostgreSQL
# Commands
- Build: npm run build
- Test: npm test
- Lint: npm run lint
# Architecture
src/routes/ - Fastify handlers (validation + response only)
src/services/ - All business logic
src/db/ - Drizzle schema, migrations, queries
src/lib/ - Shared utilities, no business logic
# Code Style
- Zod schemas for all request/response validation
- Result pattern for errors (no throw in services)
- Money values as integers (cents)
# Don't
- Don't add npm packages without asking
- Don't use any types
- Don't put logic in route handlers
- Don't modify migration files after they've run
- Don't use console.log (use the logger)
The "Don't" section is the most valuable part. Without explicit prohibitions, Claude takes shortcuts. Covered the iterative process in my Claude Code setup guide.
Best practice: under 300 lines. Run /init to generate a starter, then prune.
SOUL.md: The Tool-Agnostic Standard
Aaron Mars created SOUL.md as a universal format. Write your config once, use it everywhere. It became the standard for OpenClaw and works with Claude Code, Cursor, Windsurf.
Six sections across multiple files:
- SOUL.md - Identity. Who is the AI in this project?
- STYLE.md - Tone, formatting, code conventions
- SKILL.md - Domain knowledge and capabilities
- MEMORY.md - Session memory between conversations
- Role definitions - Different personas per task
- Tool permissions - What the AI can and can't do
# SOUL.md
You are a senior backend engineer on a fintech API.
You prioritize correctness over cleverness.
You write code a junior developer can read.
When in doubt, ask instead of guessing.
# STYLE.md
- TypeScript strict mode, no exceptions
- Functions under 30 lines
- Descriptive names (not x, temp, data)
- JSDoc on all exported functions
- Prefer named exports over default
# SKILL.md
- Expert in PostgreSQL performance
- Familiar with PCI-DSS compliance
- Knows Stripe API patterns
- Can write Drizzle ORM migrations
The separation is elegant. MEMORY.md persists context between sessions. The role system lets you define different behaviors for code review vs feature work vs debugging.
Downside: more files to maintain. And since it's tool-agnostic, it can't configure MCP servers or slash commands. Still, if you work across multiple AI tools, one format is appealing. Touched on multi-tool workflows in my agents post.
AGENTS.md: OpenAI's Emerging Standard
Started as Codex CLI's config. Now being adopted through the Linux Foundation. Over 60,000 projects have one.
The philosophy is procedural. SOUL.md describes who the AI is. AGENTS.md describes what it should do.
# AGENTS.md
## Setup
- Run npm install before changes
- Node 20+, TypeScript 5.4+
- PostgreSQL 16, connection in .env
## Testing
- Run npm test after every change
- Tests in __tests__/ mirroring src/
- Use vitest, not jest
- Mock external APIs, never hit real endpoints
## Task Definitions
### bug-fix
1. Read the error report
2. Reproduce with a failing test
3. Fix the code
4. Verify test passes
5. Check for similar patterns
### new-feature
1. Read spec in docs/specs/
2. Create migration if needed
3. Implement service layer first
4. Add route handler
5. Write integration tests
Task definitions set AGENTS.md apart. Step-by-step workflows reduce variance across developers and AI agents working the same codebase.
.cursorrules and .cursor/rules: Cursor's Evolution
The original .cursorrules was simple. One file, project root. People loved it. Then Cursor deprecated it.
Replacement: .cursor/rules/*.mdc files with frontmatter controlling activation:
---
description: Rules for API route handlers
glob: src/routes/**/*.ts
alwaysApply: false
---
# Route Handler Rules
- Zod schema for request validation
- Return typed response objects
- No business logic - delegate to services
- Log request ID on entry and exit
Glob-based activation is smart. Route rules only load when editing routes. Migration rules only load when editing migrations. Context stays tight. The alwaysApply flag marks global rules.
Migration pain was real. My polished 150-line .cursorrules took an afternoon to convert. Old community resources are all stale. Wrote about my Cursor experience in the IDE review.
Head-to-Head Comparison
| Feature | CLAUDE.md | SOUL.md | AGENTS.md | .cursor/rules |
|---|---|---|---|---|
| Creator | Anthropic | Aaron Mars | OpenAI / Linux Found. | Cursor |
| Format | Single .md per level | Multiple .md files | Single .md | Multiple .mdc files |
| Tool support | Claude Code | Any tool | Codex CLI, growing | Cursor only |
| Layering | Global + project + subdir | By concern | Directory hierarchy | Glob targeting |
| Context scoping | Always active | Always active | Always active | Glob-activated |
| Task workflows | Slash commands | Role definitions | Built-in tasks | Not supported |
| Memory | ~/.claude dir | MEMORY.md | Not built-in | Not supported |
| Ecosystem | Large | Growing | 60K+ projects | Large (fragmented) |
| Learning curve | Low | Medium | Low | Medium |
What Actually Works: Six Months of Config Files
"Don't" sections are worth more than "Do" sections. My CLAUDE.md has 8 positive rules and 12 prohibitions. The prohibitions prevent more bugs. "Don't use any types" saves more cleanup than "use TypeScript strict" creates correct code.
Shorter configs work better. A 50-line CLAUDE.md beat a 300-line version on the same project. The model deprioritizes rules after about 100 lines.
Include your actual commands. Don't assume the AI knows how to run your tests. Spell it out. Single easiest improvement. Covered this in Devin vs Claude Code.
Architecture descriptions save tokens. Five-line directory structure eliminates dozens of "which file do I put this in?" back-and-forths.
Update when you fix a recurring mistake. Every time I correct the AI twice for the same thing, I add a rule. Last Tuesday Claude Code put a DB call in a resolver for the third time. Added the rule. Haven't seen it since.
Using Multiple Formats in One Project
Nothing stops you from having CLAUDE.md AND AGENTS.md AND .cursor/rules in the same project. Each tool reads its own files.
My main project:
- CLAUDE.md - Primary development config. Commands, architecture, conventions.
- AGENTS.md - Task workflows for CI/CD agents.
- .cursor/rules/ - Lightweight rules for quick Cursor edits.
Duplication is about 20%. Architecture goes in all three. "Don't" rules in CLAUDE.md and AGENTS.md. Glob rules only in .cursor/rules.
Where This Is Heading
The fragmentation is temporary. I'm 80% confident we converge on one or two formats within a year.
AGENTS.md has the best shot. Linux Foundation backing, 60K projects, procedural enough to be unambiguous. The name is tool-neutral in a way "CLAUDE.md" isn't.
But CLAUDE.md won't disappear. Anthropic has too much invested. Same with Cursor's .mdc format - it solves context scoping that others don't.
SOUL.md is the most thoughtful design - identity, style, skill, memory is good thinking. But "thoughtful design" doesn't always win format wars. VHS beat Betamax. JSON beat XML. The winner is usually the one with the most adoption.
My bet: AGENTS.md becomes the standard, every tool reads it, tool-specific files remain as extension layers.
Start with CLAUDE.md if you use Claude Code. Add AGENTS.md if you have CI/CD or multiple contributors. Consider SOUL.md if you switch between three or more AI tools. Use .cursor/rules only if Cursor is your primary editor.
Getting Started: 5 Minutes
Don't overthink it. Create CLAUDE.md (or AGENTS.md) and write:
- Your stack. Language, framework, database.
- Your commands. Build, test, lint.
- Your directory structure.
- Three to five "Don't" rules based on AI mistakes you've already seen.
# Project: [Name]
Stack: [Language], [Framework], [Database]
# Commands
- Build: [command]
- Test: [command]
- Lint: [command]
# Structure
src/ - Application code
tests/ - Tests, mirrors src/
# Rules
- Read existing code before changes
- Follow existing patterns
- Run tests after modifications
# Don't
- Don't add dependencies without asking
- Don't use broad type assertions
- Don't skip error handling
Start here. Use it a week. Every time the AI does something wrong that a rule could prevent, add the rule. After a month you'll have a config tuned to your project. Worth more than any template from GitHub.