Rules are a Cursor feature, not an add-on. They live in the repo as files, so they are version controlled and arrive with a clone.
Cursor rules
Most Cursor rules do nothing, because the frontmatter decides when a rule applies and a rule with the wrong extension is ignored entirely. Four rule types, one directory, and the MCP servers worth adding on top. $20/mo, and the rules themselves are free.
Rules tell the agent how you work; this tells it how a library works today. Together they cover the two things it otherwise guesses.
A rule can say 'always check the schema first'. This is what makes that instruction possible to follow.
Rules shape what gets written. Nothing in the editor checks whether the result was right, and the agent that wrote it is the wrong reviewer.
- cursor$20
- context7$0
- supabase-mcp$0
- coderabbit$0 OSS
- cursor$20
- context7$0
- supabase-mcp$0
- coderabbit$30
- cursor$120 Business ×3
- context7$0
- supabase-mcp$0
- coderabbit$90
- 1Put the rule in the right place, with the right extensionCursor
Project rules live in .cursor/rules as .mdc files and are version controlled, so they arrive with a clone. The extension matters more than it looks: a plain .md file in that directory is ignored by the rules system, because it has no frontmatter to carry description, globs and alwaysApply. That is the single most common reason a rule appears to do nothing.
Prompt · Create onemkdir -p .cursor/rules # .mdc, not .md. A .md file here is silently ignored. touch .cursor/rules/conventions.mdc # Or let Cursor scaffold it: type /create-rule in Agent and # describe what you want.
- 2Pick the type, because the frontmatter is the triggerCursor
There are four types and the frontmatter alone decides which one you get. alwaysApply: true applies the rule to every chat session. A description with alwaysApply: false leaves it to the agent to decide when it is relevant. A globs pattern with alwaysApply: false fires only when a matching file is in play. Nothing at all means the rule only runs when you @-mention it. Most rules people write want the third and get the first.
Prompt · Always: conventions that are never wrong to apply--- alwaysApply: true --- - The middleware file is proxy.ts, not middleware.ts. - Content lives under content/, not lib/. The lib/*.ts files are thin loaders. - Do not add a dependency without saying why in the PR description.
Prompt · Scoped: only when the agent touches these files--- globs: ["**/*.test.ts", "**/*.spec.ts"] alwaysApply: false --- - Tests use the real database against a scratch schema, not mocks. - One assertion per test. If a test needs three, it is three tests. - Never assert on a snapshot of generated output.
Prompt · Agent-decided: describe when it matters--- description: Use when writing or changing a database migration. alwaysApply: false --- - Read the live schema before writing SQL. Do not infer it from the types. - Every migration is additive. No destructive change without a separate PR. - RLS is on. A new table with no policy is invisible to the client, which is the intended default, not a bug to work around.
- 3Add MCP servers for what rules cannot supplyContext7
A rule can tell the agent to check the current docs before writing code. Whether it can actually do that is a separate question, and the answer is MCP. This is the split worth internalising: rules are instructions, servers are capabilities, and an instruction to do something impossible just gets ignored.
- 4Review outside the editorCodeRabbit
Rules shape what gets written and nothing in the editor checks the result. Open the pull request and let something read it cold, without the reasoning that produced it. Feed the comments back into the session and let the agent apply the fixes.
The rules that earn their place are the ones that encode a thing the agent gets wrong repeatedly, not the ones that describe your project. 'The middleware file is proxy.ts, not middleware.ts' prevents a specific failure every time it fires. 'This is a Next.js app with Tailwind' prevents nothing: the agent can read package.json. A useful test is whether you can name the last time the rule saved you. If you cannot, delete it.
A plain .md file in .cursor/rules is ignored by the rules system, because it carries no frontmatter to specify description, globs or alwaysApply. Nothing warns you. The rule sits in the repo looking correct and never fires.
Every always-on rule is in the context of every request, including the ones it has nothing to do with. Test conventions loaded while writing a migration are noise that crowds out what matters. Scope with globs unless the rule really is never wrong to apply.
For agent-decided rules, the description is the trigger. 'Database conventions' tells the agent nothing about when to reach for it. 'Use when writing or changing a database migration' does. Write it as a condition, not a label.
Rules that restate what package.json already says cost context and prevent nothing. The agent can read your dependencies. It cannot know that your middleware lives under a name the framework does not expect.
A rule saying 'check the current documentation' cannot make the agent able to. That needs an MCP server. Instructions and capabilities are different things, and an instruction to do something impossible is just ignored.
What changed in AI tools and the stacks that ship. One email a week.


