.cursorrules AGENTS.md Cursor migration AI coding rules cursor rules 2026

Migrating from .cursorrules to AGENTS.md: A Step-by-Step Guide for 2026

The Prompt Shelf ·

.cursorrules still works in Cursor in 2026. But it has two problems: Cursor’s own Agent mode ignores it, and every other AI tool you add to your workflow — Codex, Claude Code, Copilot, Windsurf — needs its own separate instruction file anyway. AGENTS.md solves both. This guide walks through the migration in concrete steps, with a conversion script and the specific gotchas that bite people who do it wrong.

What You Are Actually Migrating

Before touching files, it helps to understand what the migration does and does not change.

.cursorrules is a flat Markdown file. One file, one scope, global to the project. Cursor reads it in Chat and Composer modes and uses it as persistent context. It is not read in Agent mode.

AGENTS.md is the same concept but with two key differences:

  1. It supports a directory hierarchy — multiple AGENTS.md files at different depths, each scoped to its subtree
  2. It is a multi-tool standard — Codex, Copilot, Gemini CLI, Windsurf, and others read it natively

The content format is essentially identical — both are plain Markdown. The migration is mostly about structure and placement, not about rewriting your rules from scratch. Most of a well-maintained .cursorrules file drops into AGENTS.md with minimal changes.

What the migration does not do:

  • It does not affect .cursor/rules/*.mdc (Cursor’s current MDC format). If you are also migrating away from MDC, that is a separate process.
  • It does not automatically make Cursor use AGENTS.md in preference over .cursorrules. You still need .cursorrules or .cursor/rules/ for Cursor Chat/Composer.
  • It does not replicate Cursor-specific behavior in other tools.

Step 1: Audit Your .cursorrules

Open your .cursorrules file and categorize every instruction:

Category A: Universal — Rules that apply to any AI tool working on this project. Architecture descriptions, tech stack, commands, naming conventions, test requirements.

Category B: Cursor-specific — Instructions that reference Cursor’s features, behavior, or UI (“when reviewing code, use Cursor’s diff view,” “suggest multiple alternatives using Cursor’s multi-suggestion mode”). These stay in Cursor’s config.

Category C: Rationale/explanation — Background context that explains why a rule exists. This is useful for humans reading CONTRIBUTING.md but dilutes AI instruction files. Move it out.

Category D: Outdated — Rules that were added for a specific situation that no longer applies. Drop these.

Most files are 80%+ Category A. The migration is mostly copying A into AGENTS.md, keeping B in .cursorrules, and trimming C and D.

Step 2: Run the Conversion Script

This script handles the mechanical parts: creating the file, copying content, stripping Cursor-specific language, and generating a diff for review.

#!/bin/bash
# migrate-cursorrules.sh

set -e

CURSORRULES=".cursorrules"
AGENTS_MD="AGENTS.md"

# Sanity checks
if [ ! -f "$CURSORRULES" ]; then
  echo "Error: .cursorrules not found in current directory"
  exit 1
fi

if [ -f "$AGENTS_MD" ]; then
  echo "Warning: AGENTS.md already exists. Creating AGENTS.md.new instead."
  AGENTS_MD="AGENTS.md.new"
fi

# Read original
CONTENT=$(cat "$CURSORRULES")

# Strip Cursor-specific UI references (adjust patterns for your content)
CONTENT=$(echo "$CONTENT" | sed \
  's/Cursor'\''s diff view/code review/g' \
  's/in Cursor/in any AI editor/g' \
  's/Cursor-specific/tool-specific/g' \
  's/@cursor //g')

# Write output
cat > "$AGENTS_MD" << EOF
# AGENTS.md

<!-- Migrated from .cursorrules on $(date +%Y-%m-%d) -->
<!-- Review and reorganize under appropriate headers before committing -->

$CONTENT
EOF

echo "Created $AGENTS_MD"
echo ""
echo "Next steps:"
echo "1. Review $AGENTS_MD and organize content under standard headers"
echo "2. Move Cursor-specific rules back to .cursorrules"
echo "3. Test with: cursor chat 'What are this project\''s coding conventions?'"
echo "4. Keep .cursorrules for Cursor Chat/Composer compatibility"

The output is a starting point, not a finished file. The next step is reorganizing the content.

Step 3: Reorganize Under Standard Headers

AGENTS.md works best with consistent section headers that tools know to look for. Here is the structure that covers 95% of what belongs in the file:

# AGENTS.md

## Project Overview
[1-2 sentences describing what the project is and does]

## Architecture
[Directory structure, key modules, system design decisions]

## Tech Stack
[Languages, frameworks, databases, versions]

## Commands
[How to build, test, lint, and run the project]

## Code Style
[Naming conventions, formatting rules, patterns to follow]

## Testing
[Testing approach, coverage requirements, how to write tests]

## Boundaries
[What not to touch without explicit approval]

The ## Commands section deserves special attention. Tools use this to generate correct commands automatically. Keep it accurate:

## Commands
- Install: pnpm install (not npm install — lockfile is pnpm-lock.yaml)
- Dev: pnpm dev (starts Next.js on port 3000 and API on port 3001)
- Test: pnpm test (Vitest, watch mode) / pnpm test:run (single pass)
- Test E2E: pnpm test:e2e (requires running dev server first)
- Lint: pnpm lint (ESLint + Prettier check)
- Build: pnpm build (tsc + Next.js build)
- Type check: pnpm tsc --noEmit

Step 4: Handle the Cursor Compatibility Problem

Here is the thing nobody mentions: after migration, you still need .cursorrules (or .cursor/rules/) for Cursor Chat and Composer. Cursor’s Agent mode reads AGENTS.md, but Chat and Composer do not. Until Cursor unifies its configuration reading, you are maintaining two files.

There are two strategies:

Strategy 1: Keep both, accept duplication Simple but you will drift over time. Fine for small teams where .cursorrules is actively maintained.

project-root/
├── .cursorrules              # For Cursor Chat/Composer — keep synchronized
└── AGENTS.md                 # For everything else

Strategy 2: Symlink or generate from source More robust. Use AGENTS.md as the source of truth and generate .cursorrules from it.

# Option A: symlink (simple, but works)
ln -sf AGENTS.md .cursorrules

# Option B: generate (if you need to strip Cursor-incompatible content)
# In your build or pre-commit script:
python3 scripts/generate-cursorrules.py

A simple generator:

# scripts/generate-cursorrules.py
"""Generate .cursorrules from AGENTS.md, stripping Cursor-incompatible sections."""
from __future__ import annotations

import re

def generate_cursorrules(source: str = "AGENTS.md", output: str = ".cursorrules") -> None:
    with open(source) as f:
        content = f.read()
    
    # Remove AGENTS.md-specific metadata comments
    content = re.sub(r'^<!-- .*?-->\n', '', content, flags=re.MULTILINE)
    
    # Remove sections not relevant to Cursor Chat/Composer
    # (customize these patterns for your content)
    sections_to_remove = [
        r'## Copilot Workspace.*?(?=^##|\Z)',
        r'## OpenAI Codex.*?(?=^##|\Z)',
    ]
    for pattern in sections_to_remove:
        content = re.sub(pattern, '', content, flags=re.MULTILINE | re.DOTALL)
    
    with open(output, 'w') as f:
        f.write(content.strip() + '\n')
    
    print(f"Generated {output} from {source}")

if __name__ == "__main__":
    generate_cursorrules()

Run this in a pre-commit hook to keep files in sync:

# .git/hooks/pre-commit
#!/bin/bash
if git diff --cached --name-only | grep -q "AGENTS.md"; then
  python3 scripts/generate-cursorrules.py
  git add .cursorrules
fi

Step 5: Handle Multi-Tool Conflicts

If you are adding AGENTS.md alongside an existing CLAUDE.md (Claude Code), you need to prevent rule conflicts. The cleanest pattern: have CLAUDE.md import AGENTS.md as its base, then extend it.

# CLAUDE.md

@import AGENTS.md

## Claude Code Extensions

### Hooks
# Run lint on every file Claude writes
PostToolUse[Write]: pnpm lint {path}

### Sub-agent delegation
# For tasks touching /src/api/, use the API sub-agent

With this setup, AGENTS.md is the single source of truth for shared rules. CLAUDE.md is purely additive. Copilot reads AGENTS.md directly. No three-way sync problem.

Common Gotchas

Gotcha 1: “Agent mode still ignores my rules” Cursor’s Agent mode reads AGENTS.md and .cursor/rules/*.mdc. It does not read the root .cursorrules. If you were only using .cursorrules, migrating to AGENTS.md in the root fixes Agent mode. If you were using .cursor/rules/ MDC files, those still work separately.

Gotcha 2: “Codex follows rules that Cursor doesn’t” This is normal. Codex treats AGENTS.md as authoritative configuration and enforces it strictly. Cursor treats it as strong context and applies it opportunistically. Adjust expectations by tool.

Gotcha 3: Token overflow in big AGENTS.md files If your .cursorrules was long (3,000+ tokens), directly copying it into AGENTS.md will hit attention limits in tools like Copilot. After migration, trim explanation and rationale. Keep only instructions. A 1,500-token AGENTS.md with tight instructions outperforms a 4,000-token one with rationale mixed in.

Gotcha 4: Directory-scoped rules applied globally If your .cursorrules had rules that really only applied to specific parts of the codebase, migrating them verbatim into a root AGENTS.md will apply them globally. Consider splitting them into subdirectory AGENTS.md files:

src/
├── AGENTS.md         # Frontend rules
└── api/
    └── AGENTS.md     # Backend rules

Before and After: Real Migration Example

Before (.cursorrules — 480 tokens):

You are an expert TypeScript developer working on a Next.js 15 + Tailwind project.

Always use TypeScript strict mode. Never use `any`. Use `unknown` for external data.

When writing React components, prefer server components. Only add `'use client'` when 
you need browser APIs or state. Use Cursor's diff view to show proposed changes clearly.

Testing is with Vitest. Every component needs a test file co-located.
Run tests with `pnpm test`.

The database is PostgreSQL accessed via Drizzle ORM. Schema is in `src/db/schema.ts`.
Never modify this file directly — always generate migrations with `pnpm db:generate`.

Don't touch the `/migrations/` directory. Ever.

After (AGENTS.md — same content, restructured):

# AGENTS.md

## Project
Next.js 15 + TypeScript + Tailwind. Full-stack app with PostgreSQL + Drizzle ORM.

## Commands
- Install: pnpm install
- Dev: pnpm dev
- Test: pnpm test (Vitest, watch) / pnpm test:run (CI)
- DB: pnpm db:generate (generate migrations), pnpm db:migrate (apply)

## Code Style
- TypeScript strict mode: no `any`, use `unknown` for external data
- React: server components by default, `'use client'` only for browser APIs or state
- Schema file (`src/db/schema.ts`): generate migrations with `pnpm db:generate`, never edit by hand

## Testing
- Vitest for unit tests
- Every component needs a co-located test file

## Boundaries
- Never modify `/migrations/` directly
- Never edit `src/db/schema.ts` by hand — always run `pnpm db:generate`

The Cursor-specific line (“use Cursor’s diff view”) was dropped. Everything else moved into clear sections. The resulting file is easier to scan, and tools like Codex and Copilot apply it more reliably because the instructions are structured, not buried in prose.


Related Articles

Explore the collection

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

Browse Rules