How to lint your Cursor rules
TL;DR
Run this from your project root. No install, no config:
npx cursor-doctor lint
Why lint Cursor rules?
Cursor doesn't tell you when a rule is broken. If the YAML frontmatter is malformed, the rule silently disappears. If two rules contradict each other, Cursor picks one and ignores the other. If a glob pattern has a typo, the rule never loads for the files you intended.
You won't see an error message. You'll just notice Cursor "ignoring" your instructions and spend 20 minutes wondering why your .mdc files aren't working.
Linting catches these problems before they cost you time. One command scans your project and reports exactly what's wrong with each rule file.
Quick start
Run this from your project root (where your .cursor/ directory lives):
npx cursor-doctor lint
It scans .cursor/rules/, any .cursorrules file, and agent skill files. No install needed, no config files, zero dependencies.
For a broader health check that includes a letter grade, total token count, and summary:
npx cursor-doctor scan
What gets checked
cursor-doctor runs 100+ checks across your rule files. Here are the categories that catch the most real bugs.
Frontmatter errors
Every .mdc file needs a YAML frontmatter block between --- markers. These checks catch the structural issues that make Cursor rules silently fail.
Missing YAML frontmatter
The file has no --- block at the top. Cursor may ignore the entire file.
YAML frontmatter parse error
The frontmatter has a syntax mistake: bad indentation, a missing colon, or an unclosed quote. The rule won't load correctly.
Rule will never load
alwaysApply: false with no globs. This rule only activates when you reference it by name in chat, which is easy to forget.
Missing description
The description field tells Cursor when to apply the rule. Without one, Cursor has to guess based on the content alone.
Glob pattern issues
Globs control which files trigger a rule. A bad glob means the rule loads for the wrong files, or never loads at all.
Overly broad glob
Patterns like * or ** match everything. If you want the rule to always apply, use alwaysApply: true instead. It's clearer and avoids confusing Cursor's rule loading.
Windows backslashes in glob
Glob patterns use forward slashes. src\components\*.tsx won't match anything on any platform.
Comma-separated globs
Using "*.ts, *.tsx" as a single string instead of a YAML array. This may not match what you expect. Use separate entries instead.
Content quality
Rules that parse correctly can still be ineffective. These checks flag instructions that waste tokens or don't change model behavior.
Vague instruction
Phrases like "write clean code" or "follow best practices" sound helpful but don't change what Cursor does. They just burn context window tokens. Replace them with specific, actionable commands.
Empty rule body
The file has frontmatter but no actual instructions after it. The rule exists but does nothing.
Duplicate content
Two or more .mdc files contain nearly identical instructions. This wastes your token budget by feeding the same text to the model twice.
Cross-file checks
Some problems only show up when you look at all your rules together.
Semantic conflict
One rule says "use semicolons," another says "omit semicolons." Cursor picks one silently. The linter checks 48 contradiction patterns across topics like formatting, error handling, imports, and naming.
Identical globs across rules
Multiple rules share the exact same glob patterns. This often means they should be merged into one file, or their scopes should be narrowed.
Reading the output
The lint command groups results by file:
.cursor/rules/typescript.mdc
⚠ Vague rule detected: "follow best practices" (line 8)
⚠ No alwaysApply or globs set (line 1)
.cursor/rules/react.mdc
✓ All checks passed
.cursor/rules/testing.mdc
✗ YAML frontmatter error: bad indentation (line 2)
──────────────────────────────────────────────────
1 error(s), 2 warning(s), 1 passed
Errors (✗) prevent the rule from working at all. Fix these first. Warnings (⚠) reduce effectiveness or waste tokens.
scan vs. lint
cursor-doctor has two ways to check your rules:
lintshows every issue in every file. Use it when you want the full per-file breakdown.scangives you a health grade (A through F), total token count, file count, and a summary of the most important issues. Think ofscanas the dashboard andlintas the detailed report.
Both commands are free. No account, no API key.
How to fix common issues
Most lint issues have straightforward fixes. For YAML and frontmatter errors, check indentation (use spaces, not tabs) and make sure colons have a space after them. For vague instructions, replace generic phrases with specific commands.
Deeper guides for the most common categories:
- 5 Cursor rule mistakes that make the AI ignore you
- How to fix Cursor rule conflicts
- How to write Cursor rules that actually work
cursor-doctor Pro can auto-fix most issues in one pass:
npx cursor-doctor fix --dry-run # preview what changes
npx cursor-doctor fix # apply the fixes
Lint Cursor rules in CI
Run npx cursor-doctor check in your CI pipeline. It exits with a non-zero code on D or F health grades, failing the build automatically. See the full CI setup guide for a copy-paste GitHub Actions workflow.
Lint in your editor
If you use Cursor (which is VS Code under the hood), the cursor-doctor VS Code extension shows lint warnings inline as you edit .mdc files. Issues appear as squiggly underlines with descriptions, and quick-fix suggestions are available from the lightbulb menu.
Frequently asked questions
How do I check if my Cursor rules are working?
Run npx cursor-doctor lint from your project root. It scans every .mdc file and reports broken frontmatter, invalid globs, vague instructions, and conflicts between rules. No install or config needed.
Is cursor-doctor free?
The scan, lint, init, and install commands are free with no limits. The fix command (auto-fix) requires a Pro license. You can preview what fix would change with npx cursor-doctor fix --dry-run before buying.
What does cursor-doctor check for?
100+ checks including: missing or broken YAML frontmatter, invalid glob patterns, vague instructions, empty rule bodies, duplicate content across files, 48 semantic contradiction patterns (like one rule saying "use semicolons" while another says "omit semicolons"), and rules that will never load due to misconfigured frontmatter.
Can I lint Cursor rules in CI?
Yes. Run npx cursor-doctor check in your CI pipeline. It exits with a non-zero code on D or F health grades, which fails the build. See the CI setup guide for a GitHub Actions workflow.
Related guides
- How to write Cursor rules that actually work
- How to fix Cursor rule conflicts
- Cursor token budget: how many rules is too many?
- Run cursor-doctor in CI with GitHub Actions
Try it now
Run one command to find out what's wrong with your Cursor rules. No install, no config, zero dependencies.
npx cursor-doctor lint
Or paste a single rule into the playground for instant feedback.