VDK Docs
Blueprints

MDC Format

Cursor's enhanced rule format combining Markdown with XML-like directives

MDC Format Blueprint

MDC (Markdown with Directives) is Cursor's enhanced rule format that combines standard Markdown with XML-like directives for richer AI context and interactive features.

Format Specification

Basic Structure

---
title: "Rule Title"
description: "Brief description"
version: "2.0.1"
schema: "cursor-mdc-v1"
tags: ["tag1", "tag2"]
---

# Rule Title

```xml
<cursor:context>
High-level project context and overview
</cursor:context>

Standard Markdown Content

<cursor:patterns>
Code patterns and examples
</cursor:patterns>
<cursor:rules>
- Specific coding rules
- Guidelines and conventions
</cursor:rules>

YAML Frontmatter Schema

# Required fields
title: string                    # Rule title
description: string              # Brief description
version: string                  # Semantic version
schema: "cursor-mdc-v1"         # MDC schema version

# Standard fields (inherited from Markdown)
tags: array<string>             # Technology tags
created: string                 # ISO 8601 timestamp
updated: string                 # ISO 8601 timestamp

# MDC-specific fields
priority: number                # Rule priority (1-10)
scope: array<string>           # File patterns where rule applies
enableDirectives: boolean      # Enable/disable directive processing
validateOnSave: boolean        # Validate when file is saved

# Cursor-specific fields
cursor:
  version: string              # Minimum Cursor version
  features: array<string>      # Required Cursor features
  experimental: boolean        # Uses experimental features

MDC Directives

Core Directives

<cursor:context>

Provides high-level project context for the AI assistant.

<cursor:context>
This is a Next.js 15 e-commerce application using TypeScript, Tailwind CSS, and Prisma. 
The project follows a feature-based architecture with server components as the default 
pattern and client components only for interactive features.

Key architectural decisions:
- App Router for file-based routing
- Server actions for form handling  
- Zustand for client-side state management
- React Query for server state
</cursor:context>

Best Practices:

  • Keep context concise but comprehensive
  • Include architectural decisions and reasoning
  • Mention key technologies and patterns
  • Explain project-specific conventions

<cursor:patterns>

Defines coding patterns with examples.

API Route Pattern

All API routes follow this error handling pattern:

// app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';

const createUserSchema = z.object({
  name: z.string().min(1),
  email: z.string().email()
});

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const data = createUserSchema.parse(body);
    
    const user = await createUser(data);
    return NextResponse.json(user, { status: 201 });
  } catch (error) {
    if (error instanceof z.ZodError) {
      return NextResponse.json(
        { error: 'Validation failed', details: error.errors },
        { status: 400 }
      );
    }
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    );
  }
}

Component Pattern

React components follow this structure:

interface ComponentProps {
  // Props with JSDoc comments
  /** User data object */
  user: User;
  /** Optional edit handler */
  onEdit?: (user: User) => void;
}

export default function UserCard({ user, onEdit }: ComponentProps) {
  return (
    <div className="p-4 border rounded-lg">
      <h3 className="font-semibold">{user.name}</h3>
      <p className="text-gray-600">{user.email}</p>
      {onEdit && (
        <button 
          onClick={() => onEdit(user)}
          className="mt-2 px-3 py-1 bg-blue-500 text-white rounded"
        >
          Edit
        </button>
      )}
    </div>
  );
}

Best Practices:

  • Include complete, working examples
  • Show the full pattern, not just snippets
  • Explain the reasoning behind patterns
  • Provide multiple related examples

<cursor:rules>

Specific coding rules and guidelines.

  • Always use TypeScript with proper interface definitions
  • Prefer server components over client components
  • Use 'use client' directive only when interactivity is required
  • Include proper error handling in all async operations
  • Follow the repository pattern for data access
  • Use absolute imports with @/ prefix
  • Include JSDoc comments for complex functions
  • Implement proper loading and error states
  • Use Tailwind utility classes instead of custom CSS
  • Follow the established naming conventions (PascalCase for components, camelCase for functions)

**Best Practices:**
- Be specific and actionable
- Order rules by importance
- Use consistent language
- Reference project-specific conventions

#### `<cursor:technologies>`
Technology stack information.

<cursor:technologies>
Frontend:
- Framework: Next.js 15 (App Router)
- Language: TypeScript 5.0+
- Styling: Tailwind CSS v3
- State: Zustand + React Query
- UI Components: Headless UI + Custom

Backend:
- Runtime: Node.js 18+
- Database: PostgreSQL 15
- ORM: Prisma 5.0+
- Authentication: NextAuth.js v4
- API: Next.js Route Handlers

Development:
- Package Manager: pnpm
- Linting: ESLint + Prettier
- Testing: Jest + React Testing Library
- Type Checking: TypeScript strict mode
</cursor:technologies>

Advanced Directives

<cursor:structure>

Project structure and organization.

app/                    # Next.js App Router
├── (auth)/            # Authentication routes
│   ├── login/         # Login page
│   └── register/      # Registration page
├── (dashboard)/       # Protected dashboard routes
│   ├── users/         # User management
│   └── settings/      # Settings pages
├── api/               # API routes
│   ├── auth/          # Authentication endpoints
│   └── users/         # User CRUD operations
├── globals.css        # Global styles
└── layout.tsx         # Root layout

components/            # Reusable components
├── ui/               # Base UI components (Button, Input, etc.)
├── forms/            # Form components
├── layout/           # Layout components (Header, Sidebar)
└── features/         # Feature-specific components

lib/                  # Utilities and configurations
├── auth.ts           # Authentication configuration
├── db.ts             # Database connection
├── utils.ts          # Utility functions
└── validations.ts    # Zod schemas

types/                # TypeScript type definitions
├── auth.ts           # Authentication types
├── user.ts           # User-related types
└── api.ts            # API response types

<cursor:examples>

Extended examples with explanations.

Complete Feature Example: User Management

1. Database Schema (Prisma)

// prisma/schema.prisma
model User {
  id        String   @id @default(cuid())
  name      String
  email     String   @unique
  avatar    String?
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  
  @@map("users")
}

2. API Route

// app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { createUserSchema } from '@/lib/validations';
import { createUser, getUsers } from '@/lib/db/users';

export async function GET() {
  try {
    const users = await getUsers();
    return NextResponse.json(users);
  } catch (error) {
    return NextResponse.json(
      { error: 'Failed to fetch users' },
      { status: 500 }
    );
  }
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const data = createUserSchema.parse(body);
    
    const user = await createUser(data);
    return NextResponse.json(user, { status: 201 });
  } catch (error) {
    if (error instanceof z.ZodError) {
      return NextResponse.json(
        { error: 'Validation failed', details: error.errors },
        { status: 400 }
      );
    }
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    );
  }
}

3. Server Component (List)

// app/users/page.tsx
import { getUsers } from '@/lib/db/users';
import { UserCard } from '@/components/features/UserCard';
import { AddUserButton } from '@/components/features/AddUserButton';

export default async function UsersPage() {
  const users = await getUsers();
  
  return (
    <div className="container mx-auto py-8">
      <div className="flex justify-between items-center mb-6">
        <h1 className="text-2xl font-bold">Users</h1>
        <AddUserButton />
      </div>
      
      <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
        {users.map(user => (
          <UserCard key={user.id} user={user} />
        ))}
      </div>
    </div>
  );
}

4. Client Component (Interactive)

// components/features/AddUserButton.tsx
'use client'

import { useState } from 'react';
import { Button } from '@/components/ui/Button';
import { Modal } from '@/components/ui/Modal';
import { UserForm } from '@/components/forms/UserForm';

export function AddUserButton() {
  const [isOpen, setIsOpen] = useState(false);
  
  return (
    <>
      <Button onClick={() => setIsOpen(true)}>
        Add User
      </Button>
      
      <Modal isOpen={isOpen} onClose={() => setIsOpen(false)}>
        <UserForm 
          onSuccess={() => setIsOpen(false)}
          onCancel={() => setIsOpen(false)}
        />
      </Modal>
    </>
  );
}

MDC Processing

Directive Processing

Cursor processes MDC directives in this order:

  1. Parse YAML frontmatter - Extract metadata and configuration
  2. Identify directives - Find all <cursor:*> tags in content
  3. Validate syntax - Check directive syntax and nesting
  4. Extract content - Parse content within directives
  5. Apply context - Use directive content to enhance AI understanding

Context Hierarchy

Directives create a hierarchy of context for the AI:

Project Context (cursor:context)
├── Technologies (cursor:technologies)
├── Structure (cursor:structure)
├── Patterns (cursor:patterns)
│   ├── Code Examples
│   └── Implementation Details
├── Rules (cursor:rules)
│   ├── Coding Standards
│   └── Best Practices
└── Examples (cursor:examples)
    ├── Complete Implementations
    └── Real-world Usage

Scope Application

MDC rules can be scoped to specific files or directories:

---
scope: 
  - "app/**/*.tsx"        # App Router pages only
  - "components/**/*.tsx" # React components only
  - "lib/**/*.ts"         # Utility functions only
---

When working in scoped files, Cursor gives higher priority to matching rules.

Validation

Schema Validation

MDC files are validated against the schema:

# Validate MDC syntax
vdk validate --format mdc --file .cursor/rules/patterns.mdc

# Validate all MDC files
vdk validate --format mdc --directory .cursor/rules/

# Fix common MDC issues
vdk blueprints fix --format mdc .cursor/rules/

Directive Validation

Common validation rules:

  • Proper nesting: Directives cannot be nested
  • Valid syntax: XML-like tags must be properly closed
  • Content requirements: Some directives require non-empty content
  • Schema compliance: Content must match expected schema

Cursor Integration

Cursor validates MDC files automatically:

  • On file save (if validateOnSave: true)
  • On project open
  • When rules are updated
  • Before AI context application

Conversion from Markdown

Automatic Conversion

VDK can convert standard Markdown rules to MDC format:

# Convert single file
vdk blueprints convert \
  --from markdown \
  --to mdc \
  --input .ai/rules/react-patterns.md \
  --output .cursor/rules/react-patterns.mdc

# Convert entire directory
vdk blueprints convert \
  --from markdown \
  --to mdc \
  --input .ai/rules/ \
  --output .cursor/rules/

Conversion Mapping

Markdown SectionMDC DirectiveNotes
Project Context<cursor:context>High-level overview
Technology Stack<cursor:technologies>Structured tech info
Code Examples<cursor:patterns>Patterns with examples
Best Practices<cursor:rules>Bullet-point rules
File Structure<cursor:structure>Directory layout

Manual Enhancement

After conversion, enhance with Cursor-specific features:

Before (Markdown):

## Component Pattern
Use TypeScript interfaces for props.

After (MDC):

Component Pattern

Always define TypeScript interfaces for component props:

interface UserCardProps {
  user: User;
  onEdit?: () => void;
}

export default function UserCard({ user, onEdit }: UserCardProps) {
  return <UserCardComponent user={user} onEdit={onEdit} />;
}

Best Practices

Directive Usage

  1. Use appropriate directives - Choose the right directive for content type
  2. Keep content focused - Each directive should have a single purpose
  3. Provide complete examples - Include full, working code examples
  4. Maintain consistency - Use consistent terminology and patterns
  5. Update regularly - Keep directives current with project evolution

Content Organization

<!-- Good: Logical flow -->
<cursor:context>
Project overview and key decisions
</cursor:context>

<cursor:technologies>
Tech stack details
</cursor:technologies>

<cursor:patterns>
Implementation patterns with examples
</cursor:patterns>

<cursor:rules>
Specific coding guidelines
</cursor:rules>

<!-- Avoid: Mixed content in single directive -->
<cursor:patterns>
Project uses React and TypeScript.
Use interfaces for props.
Here's an example...
</cursor:patterns>

Performance Optimization

  1. Limit directive size - Keep individual directives under 5KB
  2. Use specific scopes - Apply rules only where relevant
  3. Avoid redundancy - Don't repeat information across directives
  4. Optimize examples - Include only essential code in examples
  5. Regular cleanup - Remove outdated or unused rules

Cursor-Specific Features

Real-time Updates

MDC files are monitored for changes:

---
# Enable real-time updates
autoUpdate: true
watchFiles: true
reloadOnChange: true
---

AI Context Enhancement

MDC directives enhance Cursor's AI in specific ways:

  • cursor:context → Provides project understanding
  • cursor:patterns → Improves code generation
  • cursor:rules → Enforces coding standards
  • cursor:technologies → Enables tech-specific suggestions
  • cursor:examples → Provides reference implementations

Integration with Cursor Features

  • Code completion uses patterns and rules
  • Chat context includes project context
  • Code generation follows established patterns
  • Refactoring suggestions respect project conventions

Migration to Other Formats

To Standard Markdown

# Extract content from MDC directives
vdk blueprints convert \
  --from mdc \
  --to markdown \
  --input .cursor/rules/ \
  --output .ai/rules/

To Windsurf XML

# Convert to XML-enhanced format
vdk blueprints convert \
  --from mdc \
  --to xml \
  --input .cursor/rules/ \
  --output .windsurf/rules/

Next Steps