Cursor project rules live in .cursor/rules/ as .mdc files with YAML frontmatter carrying description, globs, and alwaysApply. Those three fields produce four rule types: Always Apply, Apply to Specific Files, Apply Intelligently, and Apply Manually. A plain .md file in that directory is ignored. Cursor also reads AGENTS.md and CLAUDE.md from the project root and subdirectories, and documents the precedence order as Team rules, then Project rules, then User rules.
- Project rules are
.cursor/rules/*.mdc. A plain.mdthere is ignored. - Three frontmatter fields, four rule types: always, glob, intelligent, manual.
- Glob-scoped is usually right: it costs nothing when it does not apply.
- Cursor also reads AGENTS.md and CLAUDE.md, including nested ones.
- Precedence: Team, then Project, then User. Keep each file under 500 lines.
Where rules live
Cursor reads instructions from several places, and they stack rather than compete. Knowing which is which saves you writing the same convention into two of them.
From the Cursor rules documentation, checked August 2026.
| Kind | Location | Scope | Committed? |
|---|---|---|---|
| Project rules | .cursor/rules/*.mdc, subdirectories allowed | This repository | Yes |
| AGENTS.md | Project root and subdirectories | The directory and below | Yes |
CLAUDE.md | Project root | Every conversation | Yes |
| User rules | Cursor settings, under Customize then Rules | Everything you work on | No, personal |
| Team rules | The Cursor dashboard | Every repository in the organisation | Managed centrally |
.cursor/rules/
conventions.mdc alwaysApply: true, keep it under 20 lines
react.mdc globs: src/ui/**/*.tsx
api.mdc globs: src/api/**/*.ts
migrations.mdc description only, the agent decides
release.mdc no description, no globs, manual only
AGENTS.md the cross-tool file, read by Cursor and others
The MDC format
A project rule is a Markdown file with an .mdc extension and YAML frontmatter. There are three frontmatter fields, and the combination you set decides when the rule fires.
---
description: React component conventions for this project
globs: ["src/ui/**/*.tsx", "src/ui/**/*.ts"]
alwaysApply: false
---
- Function components only. No classes.
- Props interfaces are named ComponentNameProps and are exported.
- No inline styles. Use the token classes in src/ui/tokens.css.
- Data fetching lives in hooks under src/hooks/, never inside a component.
- Every interactive element needs an accessible name. No exceptions.
- Example to copy: src/ui/Button.tsx
The four rule types and the frontmatter that produces each.
| Type | alwaysApply | description | globs | Fires when | Context cost |
|---|---|---|---|---|---|
| Always Apply | true | Optional | Not used | Every session | Every request |
| Apply to Specific Files | false | Optional | Required | A matching file is in play | Only then |
| Apply Intelligently | false | Required | Omitted | The agent judges it relevant from the description | Only then |
| Apply Manually | false | Not used | Not used | You mention it in chat as @rule-name | Only then |
Choosing a rule type
| Rule content | Type |
|---|---|
| Universal, short, genuinely true everywhere | Always Apply |
| Language, framework, or directory specific | Apply to Specific Files |
| A procedure for an occasional task, such as writing a migration | Apply Intelligently |
| Something you invoke deliberately, such as a release checklist | Apply Manually |
A good shape for most repositories is one short always-on file with the four or five things that are true everywhere, then glob-scoped rules per area. That way a TypeScript component edit never carries your Go conventions, and your Go files never carry the accessibility rules for React.
Cursor advises keeping rules under 500 lines and splitting anything larger into multiple composable rules, referencing external files rather than duplicating their content. Treat 500 as the hard ceiling and 30 as the target: a rule you can read in ten seconds is a rule you will keep accurate. Its own guidance is blunter still, and correct: start simple, and add a rule only when you notice the agent making the same mistake repeatedly.
Writing rules that change behaviour
| Weak | Strong |
|---|---|
| "Write clean code" | "Functions over 40 lines must be split. Name the extracted function for what it does, not where it came from." |
| "Handle errors properly" | "Throw AppError from src/errors.ts. Never a bare Error, never a string." |
| "Follow our style" | "Named exports only. Default exports fail lint." |
| "Be careful with the database" | "Never write a migration that drops a column. Add a new one and deprecate the old one." |
| "Use good test coverage" | "Every exported function needs a test in the sibling *.test.ts. Copy the structure in src/lib/money.test.ts." |
- Be specific enough to check. If you cannot tell from a diff whether the rule was followed, it is not a rule, it is a mood.
- Say what is forbidden, not only what is preferred. Prohibitions survive paraphrase; preferences do not.
- Point at an example in the repository. One file path is worth a paragraph of description.
- Keep each file short and single-concern. One file for styling, one for testing, one for API conventions.
- Delete rules that stopped being true. A stale rule actively degrades output, because the agent follows it.
Generate the file rather than hand-writing frontmatter
In the editor, open the command palette and search for New Cursor Rule. From the terminal, the Cursor CLI has a generate-rule subcommand. Either way you get valid frontmatter, and getting globs quoted correctly by hand is a surprisingly common source of silent failure.
Commit it and review changes to it like code
Rules are team conventions. A pull request that changes a rule is exactly as worth reviewing as one that changes a function, and more worth reviewing than most.
Test it on a real task
Ask the agent to make a change in a file the rule should cover, then check the diff against the rule. If the behaviour did not change, the rule did not fire, and the wording is not the thing to fix.
When a rule is being ignored
Almost always the trigger, almost never the wording. Work down this list.
| Symptom | Likely cause | Fix |
|---|---|---|
| Never fires anywhere | The file is .md, not .mdc | Rename it, or move the content into AGENTS.md |
| Fires in some files only | The glob does not match the paths you expect | Test the pattern against a real path. Watch for a missing ** |
| Fires rarely and unpredictably | Apply Intelligently, with a vague description | Rewrite the description as the situation it applies to, not the topic |
| Fires but changes nothing | The rule is not checkable | Rewrite it as a prohibition with a named file or symbol |
| Contradicts another rule | Two sources disagree | Remember the order: Team, then Project, then User |
| Worked, then stopped | Too many always-on rules diluting each other | Move most of them to globs |
AGENTS.md and the cross-tool problem
Cursor reads AGENTS.md from the project root and from subdirectories, as plain markdown with no frontmatter, and nested files combine with their parents so the more specific instruction wins. That matters because AGENTS.md is the file the rest of the ecosystem reads too, so it is the only place a convention can be written once for every agent that touches the repository.
| File | Read by | Use it for |
|---|---|---|
AGENTS.md | Cursor, Codex, and a growing set of tools | Conventions every agent should follow |
.cursor/rules/*.mdc | Cursor only | Cursor-specific scoping: globs, intelligent selection, manual rules |
CLAUDE.md | Claude Code, and Cursor picks it up too | Cursor applies it to every conversation regardless of any alwaysApply setting, so keep it short |
.cursorrules | Cursor, legacy single file at the repo root | Migrate it. Cursor documents it as legacy and to be deprecated |
To migrate off .cursorrules: create a new rule from the command palette, paste the old content in, set the type to Always Apply so it matches the previous behaviour, then delete the file from the project root. Do it as one commit so the review shows the move rather than a mystery deletion.
Questions people ask
Project rules live in .cursor/rules/ as .mdc files with YAML frontmatter, and can be organised into subdirectories. Cursor also reads AGENTS.md at the project root and in subdirectories, plus User rules from settings and Team rules from the Cursor dashboard.
alwaysApply sends the rule with every request, so it costs context permanently. globs scope it to matching files, so it costs nothing when irrelevant. Glob-scoped is the right choice for anything language, framework, or directory specific.
Usually the trigger, not the wording. Check the extension is .mdc rather than .md, since plain .md files in that directory are ignored. Then check the glob actually matches your paths, and that an Apply Intelligently rule has a description specific enough to match against.
Markdown with YAML frontmatter carrying three fields: description, globs, and alwaysApply. The combination you set decides which of the four rule types applies: Always Apply, Apply to Specific Files, Apply Intelligently, or Apply Manually.
Yes, from the project root and from subdirectories, as plain markdown with no frontmatter. Nested files are combined with their parents and the more specific instruction takes precedence. It is the right place for conventions you want every agent to follow, not only Cursor.
Cursor documents the root .cursorrules file as legacy and slated for deprecation. Migrate it: create a new rule from the command palette, paste the content in, set the type to Always Apply, then delete the old file. You also gain glob scoping, which one root file cannot do.
One short always-on file plus a handful of glob-scoped ones per area. Cursor advises keeping any rule under 500 lines and splitting larger ones into composable pieces; aim far shorter. Long always-on rule sets dilute the instructions that actually apply to the file being edited.
Yes. Project rules and AGENTS.md are team conventions, and a change to them deserves the same review as a change to code. User rules stay personal and are not committed.
Sources
Every figure above was read from these pages on August 2026. Vendors reprice without notice; if you find a stale number, tell us.