O Cursor lê arquivos de regras de .cursor/rules e os injeta no contexto do modelo, de modo que as convenções do seu projeto sobrevivem entre chats. Essa parte é fácil. O difícil é escrever uma regra que o modelo realmente siga. A maioria das regras por aí falha de uma de três formas: são ignoradas em silêncio (formato de arquivo errado), carregam na hora errada (tipo de ativação errado) ou estão escritas em um estilo que degrada de forma mensurável os modelos atuais. Este guia cobre as três: a anatomia do .mdc, os quatro tipos de regra e o que a pesquisa diz que deve ir dentro de uma regra.
O que é uma Cursor Rule e quando você precisa de uma
Uma Cursor Rule é um arquivo markdown com frontmatter YAML, salvo com a extensão .mdc dentro de .cursor/rules/ na raiz do projeto. Quando uma regra é ativada, o Cursor antepõe o corpo dela ao contexto do modelo para aquela requisição. As regras vivem no repo, então o time inteiro as compartilha, e diretórios .cursor/rules aninhados em subpastas permitem que um monorepo delimite regras por pacote.
Escreva uma regra quando você se pegar corrigindo a IA pela mesma coisa duas vezes: ela insiste em sugerir componentes de classe, insiste em importar do caminho errado, insiste em escrever SQL cru onde seu código usa um query builder. Regras são para fatos que o modelo não consegue descobrir sozinho e convenções que diferem dos padrões do framework.
Não escreva uma regra para coisas que o modelo já sabe (como o npm install funciona) nem para coisas que um linter aplica melhor (formatação, ordem de imports). Cada regra gasta tokens de contexto; gaste-os em sinal específico do projeto.
Duas notas de manutenção. O arquivo único legado .cursorrules na raiz do repo ainda funciona, mas está deprecado; migre o conteúdo para .cursor/rules/. E a falha mais comum de todas: um arquivo .md simples dentro de .cursor/rules é ignorado em silêncio. Sem aviso, sem erro. A extensão precisa ser .mdc e o arquivo precisa de frontmatter.
A anatomia de um arquivo .mdc
Três campos de frontmatter e depois um corpo em markdown. Esta é uma regra completa e funcional:
---
description: React component conventions for the design system
globs:
- "src/components/**/*.tsx"
alwaysApply: false
---
# Component conventions
- Use function components with named exports. Default exports break
our barrel-file codegen.
- Style with Tailwind utilities only. Do not add CSS Modules; the
build pipeline strips them.
- Every component accepts a className prop and merges it via cn()
from src/lib/utils.
- Data fetching lives in hooks under src/hooks, never inside
components, because components are rendered in Storybook without
a network layer.
After edits, run: npm run lint:components (it enforces the export rule).
O que cada campo faz:
description: uma frase dizendo o que a regra cobre. Nas regras Agent Requested (abaixo) este é o texto que o modelo lê para decidir se a regra é relevante, então escreva como a descrição de uma ferramenta: "Use when writing or editing React components."globs: padrões de arquivos que disparam a regra. Quando um arquivo correspondente está no contexto atual, a regra é anexada automaticamente.alwaysApply:truecarrega a regra em toda requisição, independentemente dos outros dois campos.
O corpo é markdown puro. Faça dele instruções, não documentação: bullets imperativos curtos, caminhos de arquivo concretos, comandos executáveis e uma razão anexada a cada proibição.
Os quatro tipos de regra e como escolher o escopo
A combinação do frontmatter determina quando a regra carrega:
| Tipo | Frontmatter | Quando carrega |
|---|---|---|
| Always | alwaysApply: true | Em toda requisição. globs e description são ignorados. |
| Auto Attached | globs definido, alwaysApply: false | Quando um arquivo que bate com o glob está no contexto |
| Agent Requested | description definida, sem globs | O modelo decide, a partir da descrição |
| Manual | nenhum dos anteriores | Só quando você invoca com @nome-da-regra |
Auto Attached é o burro de carga. Suas convenções de React carregam quando há um .tsx em jogo, suas convenções de API carregam nos route handlers, suas convenções de teste carregam em *.test.ts, e nenhuma delas taxa as requisições que não têm a ver. Reserve Always para um punhado de fundamentos do projeto inteiro (declaração do stack, restrições de segurança inegociáveis), porque uma regra Always cobra tokens em cada interação.
Uma armadilha que vale destacar explicitamente: com alwaysApply: true, o Cursor ignora seus globs. Se você definir os dois, a regra carrega em todo lugar e o escopo que você achava que tinha não existe. Se a intenção era delimitar por caminho, use alwaysApply: false e mantenha os globs. (Essa combinação exata é uma das verificações do nosso linter.)
Prefira várias regras estreitas a uma regra ampla. Uma regra por assunto, cada uma delimitada aos arquivos onde importa, mantém cada injeção de contexto pequena e relevante.
O que incluir e o que deixar de fora
É aqui que a maioria das regras perde valor em silêncio. Repassamos a pesquisa por trás de ~30 antipadrões de arquivos de contexto no nosso artigo sobre o linter de arquivos de contexto; esta é a versão curta aplicada às Cursor Rules.
Inclua:
- Fatos não descobríveis. Armadilhas, motivos e decisões que o modelo não consegue inferir do código: "fixamos o Zod na v3 porque a v4 quebra nosso gerador de OpenAPI".
- Desvios dos padrões. O modelo assume as convenções do framework; documente apenas onde você difere.
- Comandos. "Rode npx vitest run antes de afirmar que um conserto funciona" muda o comportamento. Agentes seguem regras ancoradas a um comando e pulam referências de estilo em prosa.
- Proibições com razões. "Nunca use CSS Modules, porque o build os remove" generaliza; um "NEVER use CSS Modules" seco não, e os modelos o descontam cada vez mais.
Deixe de fora:
- Prosa de guia de estilo sem comando. "Siga o guia de estilo do Airbnb" é ignorado. Dê o comando de lint ou apague a linha; nunca mande um LLM fazer o trabalho de um linter.
- Despejos de árvore de diretórios. O benchmark de AGENTS.md da ETH Zurich constatou que os agentes ignoram estruturas de pastas coladas enquanto pagam cerca de 14-22% mais tokens de raciocínio por elas. O agente explora a árvore sozinho.
- Linguagem impositiva. "CRITICAL: You MUST..." foi escrito para corrigir a subativação em modelos da era 2024. Os modelos atuais se sobreativam com isso; a Anthropic agora recomenda um simples "Use X when...", e o Cursor documentou uma regressão em produção no GPT-5 causada por uma instrução "be THOROUGH".
- Inflação de ênfase. Se oito bullets são IMPORTANT em MAIÚSCULAS, nenhum é. Ênfase funciona por contraste.
- Linguagem evasiva. "Tente", "se possível", "idealmente" dizem ao modelo que a regra é opcional, e ele obedece. Enuncie as regras firmes com clareza.
- Qualquer coisa além de 500 linhas. As próprias docs do Cursor recomendam manter as regras abaixo de 500 linhas. Passou disso, divida em regras focadas e delimitadas.
Um exemplo prático: Next.js App Router mais Supabase
Esta é uma regra Auto Attached realista para route handlers de API em um código com Next.js e Supabase:
---
description: Conventions for App Router API route handlers
globs:
- "app/api/**/route.ts"
alwaysApply: false
---
# API route conventions
- Validate the request body with a Zod schema from src/schemas
before any I/O. Return 400 with the flattened error, never a
raw Zod error object (it leaks internal paths).
- Create the Supabase client with createServerClient from
src/lib/supabase/server. Do not import the browser client here;
it has no access to auth cookies.
- Mutating handlers call validateOrigin(req) first. Webhooks are
the only exception; they verify provider signatures instead.
- Return NextResponse.json with an explicit status. Bare
Response objects bypass our logging middleware.
Verify with: npx vitest run __tests__/api
Repare no que a faz funcionar: cada linha é específica do projeto, cada proibição carrega sua razão, o escopo é exatamente os arquivos onde as convenções se aplicam, e ela termina com um comando de verificação executável. Quinze linhas de corpo, e nenhuma é algo que o modelo teria adivinhado.
Erros comuns
- Salvar como
.md. Ignorado em silêncio. Use.mdccom frontmatter. alwaysApply: truecom globs. Os globs são ignorados; a regra carrega em todo lugar.- Uma mega regra Always. Toda requisição paga por ela inteira; a maior parte é irrelevante para qualquer tarefa específica.
- Uma descrição vaga em uma regra Agent Requested. "Orientação geral do projeto" não dá ao modelo nada contra o que comparar, então a regra nunca ativa. Descreva o gatilho: "Use when writing database migrations."
- Duplicar seu linter. ESLint e Prettier já aplicam a formatação de forma determinística e de graça.
- Segredos nas regras. Regras são commitadas e compartilhadas. Arquivos de regras foram também o vetor do ataque "Rules File Backdoor" de 2025, em que Unicode invisível contrabandeou instruções para além da revisão de código, então trate regras de terceiros que você colar como entrada não confiável e escaneie-as.
- Deixar as regras envelhecerem. Uma regra que contradiz o código atual é pior que nenhuma regra; o modelo queima tokens tentando reconciliá-las.
Como validar uma regra
Duas verificações, uma estática e uma empírica.
Estática: passe sua regra no linter no navegador, ou offline com a CLI:
npx promptarch lint .cursor/rules/api-conventions.mdc
O linter verifica que o frontmatter existe e está bem formado, sinaliza a armadilha do alwaysApply mais globs, aplica o orçamento de 500 linhas, escaneia Unicode oculto e segredos vazados, e pontua a escrita contra a pesquisa de antipadrões acima. É grátis, não precisa de conta e roda totalmente offline.
Empírica: abra o Cursor, peça uma tarefa que a regra deveria governar e confira no painel de contexto se a regra foi anexada. Depois olhe a saída. Se o modelo ignorou uma instrução, o conserto costuma ser especificidade: adicione a razão, adicione o comando ou estreite a regra para que a instrução não fique enterrada.
Gere uma de graça
Se você prefere partir de um rascunho funcional em vez de um arquivo em branco, o gerador gratuito de Cursor Rules do PromptArch faz as perguntas estruturadas (stack, tipo de ativação, globs, convenções, restrições) e gera um .mdc completo com o frontmatter já escolhido corretamente. Sua primeira geração é grátis e sem cadastro na página de teste. E se você já tem regras no seu repo, cole-as no linter e veja que nota elas tiram.