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-bridgeIs 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
- Download
plugin.zipfrom https://github.com/TranHoaiHung/figma-ui-mcp/raw/main/plugin.zip - Unzip anywhere on your machine
- Open Figma Desktop (required)
- Plugins → Development → Import plugin from manifest...
- Select
manifest.jsonfrom unzipped folder - 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
| Operation | Purpose | Key Params |
|---|---|---|
get_page_nodes | List all top-level nodes | { maxDepth } |
get_selection | Get selected nodes | {} |
get_node_detail | Full node data with resolved variables/styles | { nodeId } |
get_design_context | AI-optimized payload for code generation | { nodeId } |
get_component_map | List component instances with variants | { frameId } |
get_unmapped_components | Find components missing code mapping | { frameId } |
get_css | Generate CSS from node | { nodeId } |
screenshot | Capture PNG | { nodeId, scale } |
get_variables | All variables (all modes) | {} |
get_styles | All 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_nodesfirst to get valid node IDs. Checkfigma_docsfor 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
sessionIdspecified with multiple files open - Fix: Call
figma_statusto list sessions, then passsessionIdtofigma_write/figma_read.
Variable binding fails
- Cause: Variable doesn't exist or wrong type
- Fix: Call
figma_read get_variablesfirst. EnsureFLOATvariables for dimensions,COLORfor fills.
Best Practices
- Always call
figma_docsat session start to load API reference into AI context - Call
figma_rulesonce per file to get design system tokens before generating code - Use
get_design_contextfor code generation — single call returns all layout/color/typography data - Use
get_component_mapfor import statements — returnssuggestedImportpaths - Batch operations when possible — reduces round-trips (single
figma_writewithoperationsarray) - Reference previous results with
result[0],result[1]in batch operations - Use design tokens (
applyVariable) instead of hardcoded colors for maintainability - Check
figma_statusfirst to verify connection and list sessions - Use
sessionIdwhen multiple Figma files are open to avoid ambiguity - 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.
How can the creator link this skill?
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>