You pressed Cmd+K and asked Cursor to create a notification card. It generated beautiful code in five seconds — wrong background color, wrong padding, wrong icon tint. You spent five minutes fixing what took five seconds to generate.
Cursor is fast at producing generic code. This guide makes it fast at producing your code.
Two Approaches
There are two ways to close the gap between Cursor's defaults and your design system.
.cursorrules is a plain text file in your project root. Cursor reads it before every generation. It takes ten minutes to set up. The limitation: Cursor can drift from your rules in long sessions, and updating tokens requires manual edits to the file.
MCP integration connects Cursor to your token source programmatically. Cursor queries your actual design system rather than reading a static file. It's always current and can answer questions like "what spacing values are available?" dynamically.
Start with .cursorrules. Add MCP when your team grows or your tokens change often.
Setup Part 1: .cursorrules
Create .cursorrules in your project root:
# Project Design System
## Colors
- Primary brand: bg-brand-primary
- Neutral backgrounds: bg-neutral-50, bg-neutral-100, bg-neutral-900
- Semantic: bg-semantic-success, bg-semantic-error, bg-semantic-warning
## Spacing
Named spacing tokens only — never arbitrary values like px-[17px]:
- xs = 0.5rem
- sm = 0.75rem
- md = 1rem
- lg = 1.5rem
- xl = 2rem
## Component Patterns
Buttons:
- Primary: bg-brand-primary hover:bg-brand-primaryHover text-white px-md py-sm rounded-md
- Secondary: bg-neutral-100 hover:bg-neutral-200 text-neutral-900 px-md py-sm rounded-md
Cards:
- bg-neutral-50 border border-neutral-200 rounded-lg p-lg
Inputs:
- border border-neutral-300 rounded-md px-sm py-xs focus:border-brand-primary
## Code Rules
- TypeScript for all components
- Tailwind classes only — no inline styles
- Never hardcode colors or spacing
- Import shared components from @/components
Test it: ask Cursor to "create a primary button component." If it generates bg-blue-600, your rules need more examples. If it generates bg-brand-primary, you're set.
When Cursor drifts in a long session, reference your rules explicitly in the prompt: "Follow the design tokens in .cursorrules."
Setup Part 2: MCP Integration
MCP gives Cursor programmatic access to your design tokens. Install the FramingUI MCP server:
npx -y @framingui/mcp-server@latest init
This command detects your project type (Next.js or Vite), installs the required packages, configures the CSS import, sets up the provider, and registers the MCP server in .mcp.json.
The generated .mcp.json looks like this:
{
"mcpServers": {
"framingui": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@framingui/mcp-server@latest"]
}
}
}
Restart Cursor after running init. The MCP server starts automatically and Cursor can now query your design system dynamically.
Real Workflow: Building a Settings Page
With both .cursorrules and MCP configured, here's what generation looks like in practice.
Prompt Cursor:
Create a user settings page with:
- Profile section (avatar, name, email)
- Appearance section (theme toggle, language selector)
- Notifications section (email preference checkboxes)
Follow .cursorrules for design tokens.
Cursor generates components using text-neutral-900 instead of text-gray-900, spacing tokens like py-xl and p-lg, and your background token bg-neutral-50. No manual correction needed.
Follow up: "Add a save button at the bottom, primary variant." Cursor produces bg-brand-primary hover:bg-brand-primaryHover — consistent with the design system on the first try.
Troubleshooting
Cursor ignores your rules after a long session. This is a known limitation of .cursorrules. Either upgrade to MCP (which doesn't forget), or include a reminder in your prompt: "Use design tokens from .cursorrules."
Cursor generates invalid token names like bg-brand-primary-500 when you only have bg-brand-primary. Add the explicit available token list to .cursorrules — "Available brand colors: brand.primary, brand.secondary (no numeric scales)."
MCP server not starting. Check Cursor > View > Output > MCP for error logs. Common causes: path to tokens is wrong, Node.js version below 18, or @framingui/mcp-server isn't installed.
Cursor generates inline styles instead of Tailwind classes. Add to .cursorrules: "Always use Tailwind classes. Never use inline styles unless the value is dynamic from a prop."
The Payoff
Before this setup, Cursor is a fast code generator producing generic output. After this setup, Cursor is a fast code generator that knows your conventions.
The .cursorrules approach covers most teams. MCP covers the rest — larger teams, evolving token systems, or projects where consistency across sessions is non-negotiable.