My Best Practices for MDC rules and troubleshooting

I’ve been exploring how Cursor’s MDC rules work by experimenting with the AI.

I wanted to share what I learned by feeding different files into context and asking the AI what it saw.

mdc_rule_system

Situation: What’s the current state of MDC rules?

So here’s the thing - based on what I understood from the official documentation, it seemed
like you could throw any kind of file into the .cursor/rules folder and Cursor would just
figure it out. But when I actually tried this and showed different files to the AI to see
what it could recognize, I discovered that’s not how it works at all. You specifically need
to use YAML files with the .mdc extension, or the rules won’t get picked up. This was pretty
different from what I thought the docs were saying!

Background: How do these rules actually work?

Once I got that sorted out, I started playing around with these rules more. They’re actually
pretty cool - you can make Cursor handle different files in different ways. I spent a bunch
of time testing stuff with the AI, and we figured out that the rules load based on the numbers
<CURRENT_CURSOR_POSITION>
at the start of the filenames. Oh, and here’s a fun thing - if you have rules that clash,
the last one wins. Kind of like how the last person to touch the thermostat gets to pick
the temperature!

I learned most of this just by throwing different examples at the AI and seeing what stuck.
It was pretty helpful at explaining which patterns it noticed in my test files.

Assessment: What have I found works best?

Format Choice

Look, I tried a bunch of different ways to write these rules, but YAML is definitely
the way to go. Not just because it’s required (which it is), but because it’s so much
easier to read and work with. Plus you can add comments, which has saved my bacon more
times than I can count!

Naming System

Through trial and error, I found this organization system works best.
I use a three-digit format and group rules like this:

  • Core Rules: 001-099
  • Integration Rules: 100-199
  • Pattern/Role Rules: 200-299

Examples:

  • Core Rules:
    • “001-Core-Security.mdc”
    • “015-Core-Logging.mdc”
  • Integration Rules:
    • “100-API-Integration.mdc”
    • “110-CLI-Handler.mdc”
  • Pattern/Role Rules:
    • “200-File-Pattern-Rule.mdc”
    • “210-Data-Validation.mdc”

Recommendation: Here’s what you should do

Creation Method

I’ve found the Settings UI is definitely the most reliable way to create rules -
it’s helped me avoid a lot of mistakes. But if you want to create files directly,
just make sure they end with “.mdc” (like “001-Your-Rule.mdc”).

Rule Structure

Here’s a working example I’ve tested with the AI:

---
name: Example Pattern Rule
version: "1.0"
globs:
  - "src/**/*.py"
triggers:
  - file_change
---
```yaml
rule_definition:
  description: "This rule applies to Python source files in the src directory."

Known Issues

Heads up - there’s this annoying quirk with saving .mdc rule files. Sometimes your changes
just vanish into thin air! But I found a workaround: if stuff isn’t sticking, just
close Cursor completely. You’ll get this “Unsaved Changes” popup - hit “Override” and
then reopen Cursor. Yeah, it’s kind of a pain, but hey - it works!

References

4 Likes

As much as I hate XML - it seems to work very well. But I cannot really confirm if it works any better or worse than json or yaml or if it really matters. But I can at least confirm Yaml is not at all the only format that works within the mdc file. But it does look so much easier to maintain. But I generally use the ai to create and maintain them now that I have a good rule for generating rules, so not as concerned with the format anymore.

1 Like

Yeah, that’s what I am curious about. Cursor team has asked for feedback on documentation in official docs.

I would love to see your rule for making rules if your open to sharing?

Here it is: cursor-xml-rules-trial/.cursor/rules/cursor-rules.mdc at main · bmadcode/cursor-xml-rules-trial · GitHub

with this is place, in agent composer, just say something like ‘create a rule to always whatever…’

btw - if you want to use this with another format - you can ask cursor to maintain the intent but update the rule to reformat as yml or json or whatever and make that the standard

biggest thing that makes this work is that it prioritizes populating the front matter properly and optimized for rule pick up automatically

1 Like

That’s awesome. I am brewing up something having forked a tool for building rules that was set up to use the old method with .cursorrules. I will share it once I get it mostly functional.

2 Likes

Send me your GitHub address so I can follow you and get notified as soon as you share something hahaha

Thanks for the write-up of your investigations!

Can you describe more about this? Do you literally mean the position of the cursor in the editor?

General question, overall I’m seeing a lot of people talk about the naming system like you wrote about

Core Rules: 001-099
Integration Rules: 100-199
Pattern/Role Rules: 200-299

One of the things I want to add into my cursor rules is rules that target and prevent performance-killing issues in the codebase.

Would I want to put those into the 200-299 range?

What if we have more than 100 rules in a category?

I just posted another thread with a link to a template I created that has a rule that will auto generate and auto categories rules also - it has worked really well so far in small and large projects.

1 Like