Skip to content

Course · Cursor · Rules · .mdc & AGENTS.md

Project Rules: .mdc frontmatter and the four rule types

AGENTS.md - the plain-Markdown rules file Cursor reads natively - is always on (it carries no attachment controls; the rules documentation presents it as the simple alternative to .cursor/rules, as of October 2026). That’s its strength and its limit - there’s no way to say “load this rule only when editing API handlers” or “let the agent decide whether this is relevant.” That control is exactly what Cursor’s native .mdc format adds.

A Project Rule is a Markdown file with YAML frontmatter, living under .cursor/rules/ in your project - budgetcli, the course’s illustrative TypeScript finance API, in the tree below:

budgetcli/
├── AGENTS.md ← always-on, portable, cross-tool
├── .cursor/
│ └── rules/
│ ├── api-validation.mdc ← file-scoped: globs src/api/**
│ ├── commit-style.mdc ← agent judges relevance
│ └── migrations.mdc ← pulled in on demand: @migrations
└── src/...

The frontmatter carries three control fields - description, globs, and alwaysApply - and the combination you set maps to four behaviors. Conditional attachment is a context decision - what the agent sees, and when - and the frontmatter is how you make it. Cursor’s current terminology names them Always Apply, Apply Intelligently, Apply to Specific Files, and Apply Manually (as of October 2026; rules documentation). Older releases and older tutorials use the shorthand Always, Auto Attached, Agent Requested, and Manual for the same four types, so expect to meet both vocabularies in the wild; this chapter sticks to the current names.

.cursor/rules/api-validation.mdc
---
description: Validate every API request body with a Zod schema
globs: ["src/api/**"]
alwaysApply: false
---
All handlers under src/api/ validate input with a Zod schema before any
business logic. Reject invalid bodies at the boundary; never hand-roll
validation with if-checks.

The four types map to those fields like this:

  • Always Apply - alwaysApply: true. The rule is loaded into every request in this project. With this set, globs and description are ignored - the rule is on, full stop. Use it for repo-wide truths that must never be missed.
  • Apply Intelligently - alwaysApply: false with a description and no globs. The agent reads the description and decides whether the rule is relevant to the task at hand.
  • Apply to Specific Files - a globs: pattern. The rule attaches when a matching file enters the agent’s context - e.g. ["src/api/**"] for the validation rule above.
  • Apply Manually - alwaysApply: false with neither globs nor a description. No automatic attachment at all: you pull the rule in on demand by @-mentioning it in chat, which the linked rules documentation’s type table puts as “When @-mentioned in chat (e.g., @my-rule)” and its FAQ as “You can also @mention rules in chat to apply them manually.”

In short: globs control attachment when present; the description guides the agent when they’re not.

This is the divergence from Codex and OpenCode in one paragraph: there, a rule is on or it isn’t. Here, a rule can be always-on, model-judged, file-scoped, or hand-invoked - and you choose per rule with two lines of frontmatter.

Four types, two lines of frontmatter, all under your control. Except one of the four - the glob-scoped one - isn’t as reliable as it looks. Next: the globbing sharp edge.