Drawers of a library card catalog filled with index cards

Guide

Migrate from .cursorrules to .cursor/rules

Split the legacy .cursorrules file into scoped .mdc files with frontmatter. Scoped rules cost fewer tokens than one always-on blob, and load only when relevant.

Published July 30, 2026

Split the single .cursorrules file into focused .cursor/rules/*.mdc files with YAML frontmatter that controls when each rule loads. The legacy root file still works in basic chat, but Agent mode expects the directory format — and scoped rules cost fewer tokens than one always-on blob.

What changed, and why it matters

For years, Cursor project instructions lived in one file: .cursorrules at the repo root. Plain markdown, no structure, loaded on every request whether you were editing a React component or a SQL migration. That worked when the editor was mostly autocomplete with context — one blob, one behaviour.

Cursor 0.43 replaced that with Project Rules: one or more .mdc files in .cursor/rules/, each with YAML frontmatter that decides when the rule enters context. The old file still loads in some modes, but it is deprecated, receives no new features, and — critically — is not reliably applied in Agent mode. If your workflow has moved to agents, a .cursorrules file you haven't migrated is a file the agent may never read.

The four ways a rule gets loaded

Every .mdc file declares its activation mode in frontmatter. That decision is the whole design problem: a rule loaded on every request taxes every completion; a rule never loaded may as well not exist.

Always (alwaysApply: true) — in context for every request. Reserve this for the handful of absolutes. Auto Attached (globs) — loads when a file matching the pattern is open or in play. This is where most rules should live. Agent Requested (alwaysApply: false, no globs, but a strong description) — the model pulls the rule in when the description looks relevant. The description is a retrieval key, not a comment. Manual — only when you reference the rule by name in chat.

.cursor/rules/typescript.mdc — auto-attached to TS files
---
description: TypeScript conventions — strict null checks, no any, explicit return types on exports
globs: **/*.ts
alwaysApply: false
---

# TypeScript

- No `any`. Use `unknown` and narrow.
- Exported functions need explicit return types.
- Prefer `interface` over `type` for object shapes.
.cursor/rules/core-standards.mdc — always on, kept short
---
description: Non-negotiable project standards that apply to every change
alwaysApply: true
---

# Core standards

- Run `npm run verify` before reporting done.
- Do not add runtime dependencies without asking.
- Server components by default; `"use client"` only for real interactivity.

A plain .md file dropped into .cursor/rules/ without frontmatter is ignored — Cursor cannot decide when to load it. The extension matters too: it must be .mdc, not .md.

How to migrate in practice

Migration is splitting, not rewriting. Read your existing .cursorrules, identify distinct concerns, and give each concern its own file with the narrowest activation that still catches the edits it governs.

Migration steps
# 1. Create the directory
mkdir -p .cursor/rules

# 2. Split the legacy file by concern — one file per topic
#    Before: one 400-line .cursorrules
#    After:
#      .cursor/rules/core-standards.mdc      (alwaysApply: true, ~30 lines)
#      .cursor/rules/nextjs-performance.mdc  (globs: app/**, components/**)
#      .cursor/rules/wordpress-elementor.mdc (globs: wp-content/**)
#      .cursor/rules/database.mdc            (globs: **/*.sql, prisma/**)

# 3. Open Agent mode, edit a file in each glob, confirm the right rule loads
#    (Cursor Settings → Rules shows active rules for the session)

# 4. Delete .cursorrules once coverage is verified

The split heuristic: if a section only applies when touching a specific tree, it gets globs. If it applies everywhere, it gets alwaysApply: true — but only if it stays short. A 300-line always-on rule is a tax on every completion for the life of the project.

For a concrete scoped example with enforcement outside the editor, see Cursor rules for Core Web Vitals. For page-builder editability, see Cursor rules for Elementor.

AGENTS.md — the plain-markdown alternative

Cursor also reads AGENTS.md at the project root (or in subdirectories). No frontmatter, no globs — it always applies when the agent is working in that tree. The format is stewarded under the Agentic AI Foundation and is gaining adoption across tools, not just Cursor.

Use AGENTS.md when the repo is small and the constraints are universal: how to run tests, where secrets live, which commands must pass before a PR. Use .mdc files when different parts of the codebase need different rules — which is most production repos once you have both an app and infra, or both a theme and a plugin layer.

You can run both. A short AGENTS.md for repo-wide orientation (“read CLAUDE.md before changing anything in dev/”) plus scoped .mdc files for file-type-specific constraints is a common split. Just don't duplicate the same prohibition in three places — pick one home for each fact.

The rest of the .cursor/ directory

Project rules are the most visible piece, but .cursor/ holds other agent-facing config worth committing alongside them.

MCP servers (.cursor/mcp.json) — tools the agent can call: a browser for verification, a database reader, a docs search. Per-project config here means every teammate gets the same tool surface. Global overrides live in ~/.cursor/mcp.json.

.cursor/mcp.json — browser MCP for verification
{
  "mcpServers": {
    "cursor-ide-browser": {
      "command": "npx",
      "args": ["-y", "@anthropic-ai/mcp-server-puppeteer"]
    }
  }
}

Hooks (.cursor/hooks.json plus hook scripts) — lifecycle automation: format on save, run a linter after an agent edit, block commits that touch certain paths. Hooks are the closest thing to enforcement inside the editor; they can exit non-zero. Rules cannot.

Project skills (.cursor/skills/) — reusable procedure files the agent reads when a task matches. User-level skills in ~/.cursor/skills-cursor/ apply across all projects and are not checked into the repo. Commit skills that encode your stack's procedures; leave generic tooling skills personal.

User Rules (Cursor Settings → Rules) — personal preferences that follow you everywhere: commit message format, tone, “never amend commits.” These are not in the repo. Project rules in .cursor/rules/ are what the team shares via git. The distinction matters when onboarding — clone the repo, get project rules for free; user rules each person configures once.

Cursor rules vs CLAUDE.md

If you use both Cursor and Claude Code on the same repo, you maintain two constraint surfaces. They serve the same purpose — persistent agent instructions — but load differently.

CLAUDE.md at the project root is always loaded by Claude Code, with no glob scoping. .cursor/rules/*.mdc load conditionally in Cursor. The practical split: put reasoning and history in CLAUDE.md (why a rule exists, what failure produced it), and put file-scoped execution detail in .mdc files (which API to use, which budget applies, which path is banned). When the same fact must exist in both tools, one file should own the number and the other should point at it — not restate it.

More on structuring repos so agents need less prompting in part one of the agent-environment series.

Rules are context, not a gate

None of this replaces a pre-commit hook or a CI job. Rules shape what the model tries to do; they cannot return a non-zero exit code. If a constraint must never ship — a bundle budget, a banned import, a secret pattern — it needs enforcement outside the editor. The Core Web Vitals rules article walks through that two-layer pattern: scoped rules for intent, hooks and CI for thresholds.

Tooling conventions move faster than codebases do. Keeping a repository legible to whatever tool comes next is a standing concern on AI integration engagements.

Questions

Does .cursorrules still work?

Yes, for now — Cursor still loads a root-level .cursorrules file in basic chat. It is legacy though, and Agent mode does not treat it as a first-class project rule. If you rely on agents, migrate to .cursor/rules/*.mdc or your rules simply stop applying in the mode you actually use.

Should I use AGENTS.md instead of .mdc files?

AGENTS.md is the simpler path: one markdown file at the repo root, no frontmatter, always loaded. It is a good fit for small repos with a handful of universal constraints. The moment you need different rules for different file types — performance rules for components, editability rules for a page builder — .mdc files with globs are the format that keeps each rule relevant instead of ambient.

What else belongs in .cursor/ besides rules?

MCP server config (.cursor/mcp.json) for tools the agent can call, hooks (.cursor/hooks.json) for lifecycle automation, and optionally project skills. User-level skills and user rules live in your Cursor settings or ~/.cursor/, not in the repo — only commit what the whole team should share.

Can I delete .cursorrules after migrating?

Once the .mdc files cover everything and you have verified them in Agent mode, yes. Keeping both with overlapping content is worse than keeping either alone — the model gets the same instruction twice, sometimes phrased differently, and compliance becomes unpredictable. Migrate, verify, then remove the legacy file.

Written by

Karol

Senior engineer and systems architect behind Tall Karol. Everything published here is grounded in real client work — no roundups, no tools that haven't run in production.

Why Tall KarolWork with Tall Karol

Related notes

More on ai integration

Related service: AI Integration

Want this kind of engineering on your project?

Tall Karol takes on fractional and project-based engagements for startups and agencies.

Book a working session