Skip to content
moai-domain-figma logo

Moai Domain Figma

moai-domain-figma

Figma design system integration with API automation, design tokens, and

SKILL.md

Full skill instructions

Design Systems & Figma Integration - Advanced MCP Patterns

Enterprise design system architecture with Figma API, design tokens, and automation

Primary Agent: design-expert, component-designer Stack: Figma API 2025+, MCP integration, design tokens, component libraries, design-to-code automation Keywords: figma, design-system, design-tokens, components, design-to-code, mcp, automation Updated: Enhanced MCP tool patterns, error handling, performance optimization (v4.1.0)

Level 1: Quick Reference

When to Use This Skill

  • ✅ Building enterprise design systems with Figma as SSOT
  • ✅ Automating design-to-code workflows with MCP tools
  • ✅ Managing design tokens and component libraries
  • ✅ Integrating Figma with development pipelines
  • ✅ Scaling design across teams with automation
  • ✅ Exporting design assets and generating component code

Core Capabilities

  • Figma MCP Integration: Direct API access via MCP tools
  • Design System Architecture: Design token management, component organization
  • Figma API Automation: File manipulation, asset export, component generation
  • Design Tokens: CSS variables, JSON, SCSS export strategies
  • Design-to-Code: Automated component generation from Figma designs
  • Performance Optimization: Caching, parallel requests, conditional loading

MCP Tools Overview

ToolPurposeUse Cases
get_design_contextRetrieve design metadata + generated codeComponent generation, design inspection
get_screenshotExport design as PNG/​SVGAsset export, visual documentation
get_variable_defsExtract design tokens/​variablesToken syncing, design system export
export_componentsBatch export multiple componentsLibrary generation, code scaffolding

Level 2: Practical Implementation

Design System Patterns

Design systems connect design and development with MCP automation:

  • Single Source of Truth: Figma as SSOT for design with automated syncing
  • Token Management: Extract from Figma variables → CSS custom properties, JSON
  • Component Library: Reusable design components with automated code generation
  • Documentation: Auto-generated API docs from component metadata
  • Pipeline Integration: Design changes → automatic code updates

MCP Tool Invocation Patterns

Pattern 1: Sequential Calls (Default)

Use when output of one call feeds into the next:

// Step 1: Get design context (metadata + generated code)
const context = await mcp__figma__get_design_context({
  nodeId: "689:1242",
  clientLanguages: "typescript",
  dirForAssetWrites: "./​src/​generated/​figma-assets" // REQUIRED!
});

// Step 2: Get screenshot based on context
const screenshot = await mcp__figma__get_screenshot({
  nodeId: context.nodeId,
  format: "png",
  scale: 2
});

// Step 3: Extract variables from context
const tokens = context.variables || [];

When to use: Design inspection → Asset export → Token extraction

Pattern 2: Parallel Calls (Performance Optimization)

Use for independent requests to reduce total execution time (20-30% speedup):

// Fetch multiple independent resources in parallel
const [context, variables, screenshot] = await Promise.all([
  mcp__figma__get_design_context({
    nodeId: "689:1242",
    clientLanguages: "typescript",
    dirForAssetWrites: "./​src/​generated/​figma-assets"
  }),
  mcp__figma__get_variable_defs({
    fileId: "abc123xyz",
    teamId: "team-456"
  }),
  mcp__figma__get_screenshot({
    nodeId: "689:1242",
    format: "svg"
  })
]);

// All requests complete simultaneously
console.log("Parallel execution time: ~3-4s vs sequential 9-12s");

Speedup calculation:

  • Sequential: get_design_context (3-4s) + get_variable_defs (2-3s) + get_screenshot (3-4s) = 8-11s
  • Parallel: max(3-4s, 2-3s, 3-4s) = 3-4s
  • Improvement: 60-70% faster
Pattern 3: Conditional Loading (Resource Optimization)

Skip unnecessary calls based on requirements:

// Only call what you need
const config = {
  needsCode: true,
  needsAssets: false,
  needsTokens: true
};

const requests = [];

// Conditionally add only required calls
if (config.needsCode || config.needsAssets) {
  requests.push(
    mcp__figma__get_design_context({
      nodeId: "689:1242",
      clientLanguages: "typescript",
      dirForAssetWrites: config.needsAssets ? "./​assets" : undefined
    })
  );
}

if (config.needsTokens) {
  requests.push(
    mcp__figma__get_variable_defs({
      fileId: "abc123xyz"
    })
  );
}

const results = await Promise.all(requests);

Benefit: Reduce API calls by 30-50% based on actual needs

Parameter Guidelines & Validation

Required Parameters

dirForAssetWrites (CRITICAL - Common Error Source)

// ❌ WRONG: Will cause 400 Bad Request
const context = await mcp__figma__get_design_context({
  nodeId: "689:1242",
  clientLanguages: "typescript"
  // Missing dirForAssetWrites!
});

// ✅ CORRECT: Specify asset output directory
const context = await mcp__figma__get_design_context({
  nodeId: "689:1242",
  clientLanguages: "typescript",
  dirForAssetWrites: "/​tmp/​figma-assets" // Required even if not using assets
});

Why: MCP tool needs to know where to write exported assets (even if not used)

NodeId Format Validation
// NodeId examples (format: "parent-id:component-id")
const validNodeIds = [
  "689:1242",        // Simple component
  "0:1",             // Page/​root
  "689:1242:5678",   // Nested instance
  "I123:456:789"     // Copy instance
];

// Validation pattern
function validateNodeId(nodeId: string): boolean {
  // Format: alphanumeric:digit, optionally nested
  return /^[a-zA-Z0-9]+:[0-9]+(:[0-9a-zA-Z:]+)?$/​.test(nodeId);
}

if (!validateNodeId(nodeId)) {
  throw new Error(`Invalid nodeId format: ${nodeId}`);
}
ClientLanguages/​Frameworks Auto-Detection
// Auto-detect from project context
function detectFramework(projectPath: string): string {
  const packageJson = require(`${projectPath}/​package.json`);

  if (packageJson.dependencies?.react) {
    return packageJson.dependencies.typescript ? "typescript" : "javascript";
  }

  if (packageJson.dependencies?.vue) {
    return "typescript"; // Vue 3 + TS recommended
  }

  if (packageJson.dependencies?.["@angular/​core"]) {
    return "typescript"; // Angular always TS
  }

  return "typescript"; // Default
}

// Usage
const clientLanguages = detectFramework("./");
const context = await mcp__figma__get_design_context({
  nodeId: "689:1242",
  clientLanguages, // Auto-detected
  dirForAssetWrites: "./​src/​generated"
});

Level 3: Advanced Patterns & Error Handling

Error Handling Strategies

Common Error: 400 Bad Request - Missing dirForAssetWrites
// Error symptoms:
// - 400 Bad Request
// - "dirForAssetWrites is required"
// - Asset export fails silently

// Solution
try {
  const context = await mcp__figma__get_design_context({
    nodeId: "689:1242",
    clientLanguages: "typescript",
    dirForAssetWrites: "./​src/​generated/​figma-assets" // Add this!
  });
} catch (error) {
  if (error.message.includes("dirForAssetWrites")) {
    console.error("Missing dirForAssetWrites parameter");
    // Provide default asset directory
    return await mcp__figma__get_design_context({
      nodeId: "689:1242",
      clientLanguages: "typescript",
      dirForAssetWrites: "/​tmp/​figma-assets" // Fallback
    });
  }
  throw error;
}
Rule: Separate get_screenshot and get_variable_defs

Do NOT call in sequence unless necessary - Use parallel calls instead:

// ❌ INEFFICIENT: Sequential calls
const screenshot1 = await mcp__figma__get_screenshot({nodeId: "id1"});
const vars1 = await mcp__figma__get_variable_defs({fileId: "file1"});
const screenshot2 = await mcp__figma__get_screenshot({nodeId: "id2"});
const vars2 = await mcp__figma__get_variable_defs({fileId: "file1"});
// Total time: 16-20s (sequential)

// ✅ EFFICIENT: Parallel calls grouped by type
const [screenshots, variables] = await Promise.all([
  Promise.all([
    mcp__figma__get_screenshot({nodeId: "id1"}),
    mcp__figma__get_screenshot({nodeId: "id2"})
  ]),
  mcp__figma__get_variable_defs({fileId: "file1"})
]);
// Total time: 3-4s (parallel)

Benefits: 4-5x faster for batch operations

Rate Limiting Handling
// Exponential backoff for rate-limited requests
async function callWithBackoff(
  fn: () => Promise<any>,
  maxRetries = 3,
  initialDelay = 1000
): Promise<any> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error) {
      if (error.status === 429) { // Rate limited
        const delay = initialDelay * Math.pow(2, attempt);
        console.log(`Rate limited. Retrying in ${delay}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
      } else {
        throw error;
      }
    }
  }
  throw new Error(`Max retries exceeded`);
}

// Usage
const screenshot = await callWithBackoff(() =>
  mcp__figma__get_screenshot({nodeId: "689:1242"})
);

Performance Optimization Tips

Caching Strategy
// Cache metadata with different TTLs based on change frequency
const cacheConfig = {
  metadata: { ttl: 72 * 3600 }, // Design rarely changes (72h)
  variables: { ttl: 24 * 3600 }, // Tokens updated daily (24h)
  screenshots: { ttl: 6 * 3600 }, // Visual assets change frequently (6h)
  components: { ttl: 48 * 3600 } // Component structure stable (48h)
};

// Implementation
const cache = new Map();

async function getWithCache(key: string, fetcher: () => Promise<any>, ttl: number) {
  const cached = cache.get(key);
  const now = Date.now();

  if (cached && (now - cached.timestamp) < (ttl * 1000)) {
    console.log(`Cache hit for ${key}`);
    return cached.value;
  }

  const value = await fetcher();
  cache.set(key, { value, timestamp: now });
  return value;
}

// Usage
const variables = await getWithCache(
  `variables:abc123`,
  () => mcp__figma__get_variable_defs({fileId: "abc123"}),
  cacheConfig.variables.ttl
);
Batch Processing Optimization
// Process components in optimal batch sizes (10-20 per batch)
async function exportComponentsBatch(
  nodeIds: string[],
  batchSize = 15
): Promise<any[]> {
  const results = [];

  for (let i = 0; i < nodeIds.length; i += batchSize) {
    const batch = nodeIds.slice(i, i + batchSize);

    // Parallel requests within batch
    const batchResults = await Promise.all(
      batch.map(nodeId =>
        mcp__figma__get_design_context({
          nodeId,
          clientLanguages: "typescript",
          dirForAssetWrites: "./​src/​generated"
        })
      )
    );

    results.push(...batchResults);

    // Small delay between batches to respect rate limits
    if (i + batchSize < nodeIds.length) {
      await new Promise(resolve => setTimeout(resolve, 100));
    }
  }

  return results;
}

// Usage: Export 150 components in 10 parallel requests
const allComponents = await exportComponentsBatch(
  Array.from({length: 150}, (_, i) => `component:${i}`)
);

Level 4: Design System Integration Workflow

Complete Design-to-Code Pipeline

import * as fs from "fs";
import * as path from "path";

interface DesignSystemConfig {
  figmaFileId: string;
  figmaTeamId?: string;
  outputDir: string;
  componentNodeIds: string[];
  clientLanguages: "typescript" | "javascript";
}

async function syncDesignSystem(config: DesignSystemConfig) {
  const {figmaFileId, outputDir, componentNodeIds, clientLanguages} = config;

  console.log(`Starting design system sync for ${componentNodeIds.length} components...`);

  // Phase 1: Extract design tokens
  console.log("Phase 1: Extracting design tokens...");
  const variables = await mcp__figma__get_variable_defs({
    fileId: figmaFileId,
    teamId: config.figmaTeamId
  });

  const tokensOutput = path.join(outputDir, "tokens.json");
  fs.writeFileSync(tokensOutput, JSON.stringify(variables, null, 2));
  console.log(`✓ Tokens exported to ${tokensOutput}`);

  // Phase 2: Generate component code (parallel batch processing)
  console.log("Phase 2: Generating component code...");
  const components = await exportComponentsBatch(componentNodeIds, 15);

  const componentsDir = path.join(outputDir, "components");
  fs.mkdirSync(componentsDir, {recursive: true});

  components.forEach((component, index) => {
    const componentFile = path.join(
      componentsDir,
      `${component.componentName || `Component-${index}`}.ts`
    );
    fs.writeFileSync(componentFile, component.generatedCode || "");
  });

  console.log(`✓ Generated ${components.length} components`);

  // Phase 3: Export visual assets (parallel)
  console.log("Phase 3: Exporting visual assets...");
  const screenshots = await Promise.all(
    componentNodeIds.slice(0, 10).map(nodeId => // Limit to 10 for performance
      mcp__figma__get_screenshot({
        nodeId,
        format: "png",
        scale: 2
      })
    )
  );

  const assetsDir = path.join(outputDir, "assets");
  fs.mkdirSync(assetsDir, {recursive: true});

  screenshots.forEach((screenshot, index) => {
    const assetFile = path.join(assetsDir, `component-${index}.png`);
    fs.writeFileSync(assetFile, screenshot.imageData);
  });

  console.log(`✓ Exported ${screenshots.length} component previews`);

  // Phase 4: Generate documentation
  console.log("Phase 4: Generating documentation...");
  const docMarkdown = generateComponentDocs(components, variables);
  const docsFile = path.join(outputDir, "COMPONENTS.md");
  fs.writeFileSync(docsFile, docMarkdown);

  console.log(`✓ Documentation generated at ${docsFile}`);
  console.log(`\nDesign system sync complete!`);
  console.log(`Output directory: ${outputDir}`);
}

// Helper function
function generateComponentDocs(components: any[], tokens: any[]): string {
  let md = "# Auto-Generated Component Documentation\n\n";
  md += `Generated: ${new Date().toISOString()}\n\n`;

  md += "## Design Tokens\n\n";
  tokens.forEach(token => {
    md += `- \`${token.name}\`: ${token.value}\n`;
  });

  md += "\n## Components\n\n";
  components.forEach((comp, i) => {
    md += `### ${comp.componentName || `Component ${i}`}\n`;
    md += `Path: \`${comp.nodePath}\`\n`;
    md += "```typescript\n";
    md += comp.generatedCode?.substring(0, 200) + "...\n";
    md += "```\n\n";
  });

  return md;
}

Design Token Management

Token Extraction & Export

// Extract tokens from Figma and export to multiple formats
async function exportTokens(figmaFileId: string, outputDir: string) {
  const variables = await mcp__figma__get_variable_defs({
    fileId: figmaFileId
  });

  // Format 1: CSS Custom Properties
  let cssContent = ":root {\n";
  variables.forEach(token => {
    cssContent += `  --${token.name}: ${token.value};\n`;
  });
  cssContent += "}\n";
  fs.writeFileSync(path.join(outputDir, "tokens.css"), cssContent);

  // Format 2: JSON (for JavaScript)
  const jsonTokens = Object.fromEntries(
    variables.map(token => [token.name, token.value])
  );
  fs.writeFileSync(
    path.join(outputDir, "tokens.json"),
    JSON.stringify(jsonTokens, null, 2)
  );

  // Format 3: SCSS Variables
  let scssContent = "";
  variables.forEach(token => {
    scssContent += `$${token.name}: ${token.value};\n`;
  });
  fs.writeFileSync(path.join(outputDir, "tokens.scss"), scssContent);

  console.log(`✓ Exported ${variables.length} tokens in 3 formats`);
}

References


Last Updated: 2025-11-19 Format: Markdown | Language: English Status: Stable (v4.1.0) Version: 4.1.0

Changelog

v4.1.0 (2025-11-19)

  • Added MCP tool invocation patterns (sequential, parallel, conditional)
  • Comprehensive error handling guide with solutions
  • Performance optimization strategies (caching, batch processing)
  • Parameter validation and auto-detection examples
  • Complete design-to-code pipeline workflow
  • Rate limiting and retry strategy documentation
  • Token extraction and multi-format export examples
  • Performance improvement metrics (20-70% speedup for parallel calls)

v4.0.0 (2025-11-18)

  • Initial stable release
  • Core design system patterns
  • Basic Figma API overview

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View