- name
- figma-ui-mcp-bridge
- description
- Bridge AI assistants to Figma Desktop via MCP — draw UI with JavaScript, read designs as structured data, extract screenshots and tokens
- triggers
- ["connect to Figma and draw a UI","create a design in Figma using AI","read the selected Figma frame","extract design tokens from Figma","take a screenshot of the Figma canvas","generate a design system rule sheet","draw a mobile app screen in Figma","get component instances from Figma"]
# Figma UI MCP Bridge
> Skill by [ara.so](https://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):**
```bash
# 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):
```json
{
"mcpServers": {
"figma": {
"command": "npx",
"args": ["-y", "figma-ui-mcp"]
}
}
}
```
**Cursor:**
Edit `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):
```json
{
"mcpServers": {
"figma": {
"command": "npx",
"args": ["-y", "figma-ui-mcp"]
}
}
}
```
**VS Code / Copilot:**
Edit `.vscode/mcp.json`:
```json
{
"mcp": {
"servers": {
"figma": {
"command": "npx",
"args": ["-y", "figma-ui-mcp"]
}
}
}
}
```
**Windsurf:**
Edit `~/.codeium/windsurf/mcp_config.json`:
```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
```javascript
// 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.
```javascript
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.
```javascript
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.
```javascript
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:**
```javascript
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:**
```javascript
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:**
```javascript
figma_read({
operation: "get_page_nodes",
params: {}
})
// Returns: { nodes: [...], totalNodes: 42 }
```
**Get selection:**
```javascript
figma_read({
operation: "get_selection",
params: {}
})
// Returns: [{ id, name, type, x, y, width, height, ... }]
```
**Take screenshot:**
```javascript
figma_read({
operation: "screenshot",
params: { nodeId: "123:456", scale: 2 }
})
// Returns: { base64: "data:image/png;base64,..." }
```
**Get design context (AI-optimized):**
```javascript
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:**
```javascript
figma_read({
operation: "get_component_map",
params: { frameId: "123:456" }
})
// Returns: { instances: [{ componentSetName, variantLabel, properties, suggestedImport }] }
```
**Get CSS:**
```javascript
figma_read({
operation: "get_css",
params: { nodeId: "123:456" }
})
// Returns: { css: "display: flex; flex-direction: column; ..." }
```
## Common Operations
### Create Nodes
**Frame with auto-layout:**
```javascript
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:**
```javascript
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:**
```javascript
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:**
```javascript
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:**
```javascript
figma_write({
operation: "instantiate",
params: {
componentKey: "abc123",
overrides: {
"ButtonLabel": { text: "Submit", fill: "#FFFFFF" },
"Icon": { visible: false }
}
}
})
```
### Modify Nodes
**Change properties:**
```javascript
figma_write({
operation: "modify",
params: {
id: "123:456",
fill: "#FF5733",
width: 400,
opacity: 0.8
}
})
```
**Apply design tokens:**
```javascript
figma_write({
operation: "applyVariable",
params: {
nodeId: "123:456",
field: "fills", // fills | strokes | width | height | cornerRadius | paddingTop | etc.
variableName: "color/primary"
}
})
```
**Apply text style:**
```javascript
figma_write({
operation: "applyTextStyle",
params: {
nodeId: "123:456",
styleName: "Heading/H1"
}
})
```
### Setup Design Tokens
**Color tokens (all modes):**
```javascript
figma_write({
operation: "setupDesignTokens",
params: {
colors: {
"color/primary": {
Light: "#667EEA",
Dark: "#A5B4FC"
},
"color/background": {
Light: "#FFFFFF",
Dark: "#1A1A1A"
}
}
}
})
```
**Typography tokens:**
```javascript
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
Voir sur GitHub