skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
reason-machines/design-skills126 installs

figma-ui-mcp-bridge

Bridge AI assistants to Figma Desktop via MCP — draw UI with JavaScript, read designs as structured data, extract screenshots and tokens

How do I install this agent skill?

npx skills add https://github.com/reason-machines/design-skills --skill figma-ui-mcp-bridge
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubfail

    The skill requires downloading a Figma plugin from an unverified personal GitHub repository and running an MCP server via npx from an external package. The discrepancy between the stated author (ara.so) and the resource sources poses a supply chain risk. Additionally, the skill's ability to execute JavaScript in Figma and read document data creates a surface for indirect prompt injection.

  • Socketwarn

    1 alert: gptAnomaly

  • Snykwarn

    Risk: MEDIUM · 1 issue

What does this agent skill do?

Figma UI MCP Bridge

Skill by ara.so — Design Skills collection

Bidirectional MCP bridge between AI assistants and Figma Desktop. Let Claude Code, Cursor, Windsurf, VS Code Copilot, or any MCP-compatible IDE draw UI directly on Figma canvas via JavaScript and read existing designs back as structured data, screenshots, or code-ready tokens. Works entirely over localhost — no Figma API key required.

Requires Figma Desktop (web app cannot access localhost).

Architecture

AI Agent ─figma_write─▶ MCP Server ─HTTP (localhost:38451)─▶ Figma Plugin ─▶ Figma Document
AI Agent ◀figma_read──── MCP Server ◀HTTP (localhost:38451)─ Figma Plugin ◀─ Figma Document

The MCP server starts an HTTP server on localhost:38451. The Figma plugin uses long polling (8s hold, <100ms latency). Multi-instance support — multiple Figma files can connect simultaneously via sessionId.

Installation

Step 1: Add MCP Server

Claude Code (CLI):

# Project scope
claude mcp add figma-ui-mcp -- npx figma-ui-mcp

# Global scope
claude mcp add --scope user figma-ui-mcp -- npx figma-ui-mcp

Claude Desktop: Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "figma": {
      "command": "npx",
      "args": ["-y", "figma-ui-mcp"]
    }
  }
}

Cursor: Edit .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):

{
  "mcpServers": {
    "figma": {
      "command": "npx",
      "args": ["-y", "figma-ui-mcp"]
    }
  }
}

VS Code / Copilot: Edit .vscode/mcp.json:

{
  "mcp": {
    "servers": {
      "figma": {
        "command": "npx",
        "args": ["-y", "figma-ui-mcp"]
      }
    }
  }
}

Windsurf: Edit ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "figma": {
      "command": "npx",
      "args": ["-y", "figma-ui-mcp"]
    }
  }
}

⚠️ MUST restart IDE/AI client after adding MCP server (quit and reopen — saving config is not enough).

Step 2: Install Figma Plugin

  1. Download plugin.zip from https://github.com/TranHoaiHung/figma-ui-mcp/raw/main/plugin.zip
  2. Unzip anywhere on your machine
  3. Open Figma Desktop (required)
  4. Plugins → Development → Import plugin from manifest...
  5. Select manifest.json from unzipped folder
  6. Run Plugins → Development → Figma UI MCP Bridge

Green dot = connected. Orange = server not reachable.

Step 3: Verify Connection

// AI will call this automatically when you say "connect to Figma"
figma_status()
// Returns: { status: "ok", fileName, pageName, pluginVersion, sessions: [...] }

Core MCP Tools

figma_status

Check connection status and list active sessions.

figma_status()
// Response:
// {
//   status: "ok",
//   fileName: "My Project",
//   pageName: "Page 1",
//   pluginVersion: "2.5.12",
//   sessions: [
//     { sessionId: "abc123", fileName: "My Project", pageName: "Page 1" }
//   ]
// }

figma_docs

Get full API reference and examples. Call once at session start to load capabilities.

figma_docs()
// Returns: markdown reference with all operations, params, examples

figma_rules

Generate design system rule sheet — color tokens, typography styles, variables (all modes), component catalog. Equivalent to official Figma MCP's create_design_system_rules. Call once per file.

figma_rules({ sessionId: "abc123" }) // optional sessionId
// Returns: markdown rule sheet with all design tokens

figma_write

Execute JavaScript operations on Figma canvas. Takes operation (string) and params (object).

Single operation:

figma_write({
  operation: "create",
  params: {
    type: "FRAME",
    name: "Login Screen",
    width: 390,
    height: 844,
    fill: "#FFFFFF",
    children: [
      {
        type: "TEXT",
        name: "Title",
        characters: "Welcome Back",
        fontSize: 32,
        fontFamily: "Inter",
        fontWeight: 700,
        fill: "#000000",
        x: 40,
        y: 100
      }
    ]
  }
})

Batch operations:

figma_write({
  operations: [
    {
      operation: "create",
      params: { type: "FRAME", name: "Container", width: 800, height: 600 }
    },
    {
      operation: "modify",
      params: { id: "result[0]", fill: "#F5F5F5" }
    }
  ]
})

Use result[0], result[1] to reference previous operation results.

figma_read

Read data from Figma. Takes operation and params.

Get page structure:

figma_read({
  operation: "get_page_nodes",
  params: {}
})
// Returns: { nodes: [...], totalNodes: 42 }

Get selection:

figma_read({
  operation: "get_selection",
  params: {}
})
// Returns: [{ id, name, type, x, y, width, height, ... }]

Take screenshot:

figma_read({
  operation: "screenshot",
  params: { nodeId: "123:456", scale: 2 }
})
// Returns: { base64: "data:image/png;base64,..." }

Get design context (AI-optimized):

figma_read({
  operation: "get_design_context",
  params: { nodeId: "123:456" }
})
// Returns: flex layout, token-resolved colors, typography with style names,
// component instances with variant properties — best for code generation

Get component map:

figma_read({
  operation: "get_component_map",
  params: { frameId: "123:456" }
})
// Returns: { instances: [{ componentSetName, variantLabel, properties, suggestedImport }] }

Get CSS:

figma_read({
  operation: "get_css",
  params: { nodeId: "123:456" }
})
// Returns: { css: "display: flex; flex-direction: column; ..." }

Common Operations

Create Nodes

Frame with auto-layout:

figma_write({
  operation: "create",
  params: {
    type: "FRAME",
    name: "Card",
    width: 320,
    height: 240,
    fill: "#FFFFFF",
    cornerRadius: 16,
    layoutMode: "VERTICAL",
    paddingTop: 24,
    paddingRight: 24,
    paddingBottom: 24,
    paddingLeft: 24,
    itemSpacing: 16,
    effects: [
      {
        type: "DROP_SHADOW",
        color: "rgba(0,0,0,0.1)",
        offsetX: 0,
        offsetY: 4,
        blur: 12
      }
    ]
  }
})

Text with typography:

figma_write({
  operation: "create",
  params: {
    type: "TEXT",
    name: "Heading",
    characters: "Design System",
    fontSize: 48,
    fontFamily: "Inter",
    fontWeight: 700,
    lineHeight: { value: 120, unit: "PERCENT" },
    letterSpacing: { value: -2, unit: "PERCENT" },
    fill: "#1A1A1A"
  }
})

Rectangle with gradient:

figma_write({
  operation: "create",
  params: {
    type: "RECTANGLE",
    name: "Gradient BG",
    width: 800,
    height: 600,
    fill: {
      type: "LINEAR_GRADIENT",
      angle: 135,
      stops: [
        { position: 0, color: "#667EEA" },
        { position: 1, color: "#764BA2" }
      ]
    }
  }
})

Icon from library:

figma_write({
  operation: "createIcon",
  params: {
    name: "home",
    library: "ionicons", // ionicons | fluent | bootstrap | phosphor | tabler-filled | tabler-outline | lucide
    size: 24,
    fill: "#000000",
    x: 100,
    y: 100
  }
})

Component instance with overrides:

figma_write({
  operation: "instantiate",
  params: {
    componentKey: "abc123",
    overrides: {
      "ButtonLabel": { text: "Submit", fill: "#FFFFFF" },
      "Icon": { visible: false }
    }
  }
})

Modify Nodes

Change properties:

figma_write({
  operation: "modify",
  params: {
    id: "123:456",
    fill: "#FF5733",
    width: 400,
    opacity: 0.8
  }
})

Apply design tokens:

figma_write({
  operation: "applyVariable",
  params: {
    nodeId: "123:456",
    field: "fills", // fills | strokes | width | height | cornerRadius | paddingTop | etc.
    variableName: "color/primary"
  }
})

Apply text style:

figma_write({
  operation: "applyTextStyle",
  params: {
    nodeId: "123:456",
    styleName: "Heading/H1"
  }
})

Setup Design Tokens

Color tokens (all modes):

figma_write({
  operation: "setupDesignTokens",
  params: {
    colors: {
      "color/primary": {
        Light: "#667EEA",
        Dark: "#A5B4FC"
      },
      "color/background": {
        Light: "#FFFFFF",
        Dark: "#1A1A1A"
      }
    }
  }
})

Typography tokens:

figma_write({
  operation: "setupDesignTokens",
  params: {
    fontSizes: {
      "size/xs": { Compact: 12, Comfortable: 14, Large: 16 },
      "size/sm": { Compact: 14, Comfortable: 16, Large: 18 },
      "size/md": { Compact: 16, Comfortable: 18, Large: 20 }
    },
    fonts: {
      "font/primary": { Compact: "Inter", Comfortable: "Inter", Large: "SF Pro" }
    },
    textStyles: [
      {
        name: "Heading/H1",
        fontFamily: "font/primary",
        fontSize: "size/md",
        fontWeight: 700,
        lineHeightPercent: 120
      }
    ]
  }
})

Prototyping

Add click interaction:

figma_write({
  operation: "setReactions",
  params: {
    nodeId: "123:456",
    reactions: [
      {
        trigger: "ON_CLICK", // ON_CLICK | ON_HOVER | ON_PRESS | ON_DRAG
        action: "NAVIGATE", // NAVIGATE | OVERLAY | SWAP | SCROLL_TO | CLOSE
        destinationId: "789:012",
        transition: "SMART_ANIMATE", // SMART_ANIMATE | DISSOLVE | SLIDE_IN | PUSH | etc.
        duration: 300,
        easing: "EASE_OUT"
      }
    ]
  }
})

Set scroll behavior:

figma_write({
  operation: "setScrollBehavior",
  params: {
    nodeId: "123:456",
    overflow: "VERTICAL" // HORIZONTAL | VERTICAL | BOTH | NONE
  }
})

Component Variants

Set variant properties:

figma_write({
  operation: "setComponentProperties",
  params: {
    instanceId: "123:456",
    properties: {
      "State": "Primary",
      "Size": "Large"
    }
  }
})

Swap component:

figma_write({
  operation: "swapComponent",
  params: {
    instanceId: "123:456",
    newComponentKey: "def789"
  }
})

Read Operations Reference

OperationPurposeKey Params
get_page_nodesList all top-level nodes{ maxDepth }
get_selectionGet selected nodes{}
get_node_detailFull node data with resolved variables/styles{ nodeId }
get_design_contextAI-optimized payload for code generation{ nodeId }
get_component_mapList component instances with variants{ frameId }
get_unmapped_componentsFind components missing code mapping{ frameId }
get_cssGenerate CSS from node{ nodeId }
screenshotCapture PNG{ nodeId, scale }
get_variablesAll variables (all modes){}
get_stylesAll color/text/effect styles{}

Multi-Instance Sessions

When multiple Figma files are open, each plugin instance has a unique sessionId. Target specific files:

// List all sessions
figma_status()
// { sessions: [{ sessionId: "abc123", fileName: "App Design" }, ...] }

// Write to specific session
figma_write({
  operation: "create",
  params: { type: "FRAME", name: "Test" },
  sessionId: "abc123"
})

// Read from specific session
figma_read({
  operation: "get_page_nodes",
  params: {},
  sessionId: "abc123"
})

Omit sessionId to use the first connected session.

Common Patterns

Design System Bootstrap

// Step 1: Generate rule sheet
figma_rules()

// Step 2: Setup color tokens
figma_write({
  operation: "setupDesignTokens",
  params: {
    colors: {
      "color/primary": { Light: "#667EEA", Dark: "#A5B4FC" },
      "color/text": { Light: "#1A1A1A", Dark: "#F5F5F5" }
    }
  }
})

// Step 3: Setup typography
figma_write({
  operation: "setupDesignTokens",
  params: {
    fontSizes: {
      "size/h1": { Compact: 32, Comfortable: 40, Large: 48 }
    },
    textStyles: [
      {
        name: "Heading/H1",
        fontSize: "size/h1",
        fontWeight: 700
      }
    ]
  }
})

Design-to-Code Workflow

// Step 1: Get design context
const context = await figma_read({
  operation: "get_design_context",
  params: { nodeId: "123:456" }
})
// Returns: flex layout, resolved color tokens, typography with style names

// Step 2: Get component map
const components = await figma_read({
  operation: "get_component_map",
  params: { frameId: "123:456" }
})
// Returns: { instances: [{ componentSetName: "Button", variantLabel: "State=Primary", suggestedImport: "@/components/Button" }] }

// Step 3: Get CSS
const css = await figma_read({
  operation: "get_css",
  params: { nodeId: "123:456" }
})
// Returns: { css: "display: flex; ..." }

Batch Create + Reference

figma_write({
  operations: [
    // Create container
    {
      operation: "create",
      params: {
        type: "FRAME",
        name: "Container",
        width: 800,
        height: 600,
        layoutMode: "VERTICAL",
        itemSpacing: 24
      }
    },
    // Create child, insert into container
    {
      operation: "create",
      params: {
        type: "RECTANGLE",
        name: "Header",
        width: 800,
        height: 80,
        fill: "#667EEA",
        parentId: "result[0]" // Reference first operation's result
      }
    }
  ]
})

Troubleshooting

Plugin shows orange dot

  • Cause: MCP server not running or wrong port
  • Fix: Restart IDE/AI client (MCP server loads on startup). Check server logs for port conflicts.

"Plugin not connected" error

  • Cause: Plugin not running in Figma Desktop
  • Fix: Figma Desktop → Plugins → Development → Figma UI MCP Bridge. Must be Figma Desktop (web app cannot access localhost).

Operations fail silently

  • Cause: Invalid node ID or operation params
  • Fix: Call figma_read get_page_nodes first to get valid node IDs. Check figma_docs for param schema.

Font not found

  • Cause: Font not installed on system
  • Fix: Use fontFamily: "Inter" (ships with Figma) or install custom fonts locally.

Multi-instance targeting wrong file

  • Cause: No sessionId specified with multiple files open
  • Fix: Call figma_status to list sessions, then pass sessionId to figma_write/figma_read.

Variable binding fails

  • Cause: Variable doesn't exist or wrong type
  • Fix: Call figma_read get_variables first. Ensure FLOAT variables for dimensions, COLOR for fills.

Best Practices

  1. Always call figma_docs at session start to load API reference into AI context
  2. Call figma_rules once per file to get design system tokens before generating code
  3. Use get_design_context for code generation — single call returns all layout/color/typography data
  4. Use get_component_map for import statements — returns suggestedImport paths
  5. Batch operations when possible — reduces round-trips (single figma_write with operations array)
  6. Reference previous results with result[0], result[1] in batch operations
  7. Use design tokens (applyVariable) instead of hardcoded colors for maintainability
  8. Check figma_status first to verify connection and list sessions
  9. Use sessionId when multiple Figma files are open to avoid ambiguity
  10. Take screenshots to verify AI-generated designs match intent

Version Updates

# Get latest version + plugin path
npx figma-ui-mcp@latest --version

# Re-link Figma plugin (manual step required)
# Figma Desktop → Plugins → Development → Manage plugins in development
# Remove old → Import from manifest → Select new plugin path

Plugin does not auto-update — must re-link after npm update.

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/reason-machines/design-skills/figma-ui-mcp-bridge">View figma-ui-mcp-bridge on skillZs</a>