| name | figma-mcp-bridge |
| description | Bypass Figma API limits by streaming live document data from Figma plugin to AI tools via MCP server for design-to-code workflows |
| triggers | ["connect to figma design file","get figma document structure","extract design tokens from figma","export figma components to code","read figma styles and variables","query figma selection and nodes","create frames and text in figma","apply animations to figma nodes"] |
Figma MCP Bridge
Skill by ara.so — MCP Skills collection.
Overview
Figma MCP Bridge is a plugin + MCP server combo that streams live Figma document data to AI tools without hitting Figma's restrictive API rate limits (6 requests/month for free users). It supports multiple simultaneous Figma files, read operations (get nodes, styles, variables, screenshots), and an opt-in set of write tools for safe agent-driven edits.
Key Capabilities
- Read Tools: Document trees, selection, nodes by ID, styles, variables, design context, metadata
- Screenshot Export: PNG/SVG/JPG/PDF, base64-encoded or saved to local filesystem
- Write Tools: Create/edit frames, text, shapes, images; set fills, strokes, effects, auto-layout; duplicate, reparent, group, delete nodes
- Animation Tools (beta): Apply/remove animation styles, keyframe tracks, timeline control
- Multi-File Support: Connect to multiple Figma files simultaneously, query by
fileKey
Installation
1. Add MCP Server to AI Tool
Add to your AI tool's MCP configuration (Cursor, Claude Desktop, Windsurf, etc.):
{
"mcpServers": {
"figma-bridge": {
"command": "npx",
"args": ["-y", "@gethopp/figma-mcp-bridge"]
}
}
}
For local development:
{
"mcpServers": {
"figma-bridge": {
"command": "node",
"args": ["/absolute/path/to/figma-mcp-bridge/server/dist/index.js"]
}
}
}
2. Install Figma Plugin
- Download
plugin/ folder from latest release
- In Figma:
Plugins > Development > Import plugin from manifest
- Select
manifest.json from the downloaded plugin/ folder
3. Connect Plugin to File
- Open your Figma file
- Run the imported plugin:
Plugins > Development > Figma MCP Bridge
- Plugin UI shows "Connected" when WebSocket establishes
For multi-file workflows, repeat step 3 in each Figma file. The bridge maintains all connections simultaneously.
Core Tools
File & Metadata
List Connected Files
const files = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "list_files",
arguments: {}
});
Get File Metadata
const metadata = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_metadata",
arguments: {
fileKey: "abc123"
}
});
Reading Document Structure
Get Full Document Tree
const doc = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_document",
arguments: {
fileKey: "abc123"
}
});
Get Design Context (Depth-Limited Tree)
const context = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_design_context",
arguments: {
maxDepth: 3,
fileKey: "abc123"
}
});
Get Current Selection
const selection = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_selection",
arguments: { fileKey: "abc123" }
});
Get Specific Node by ID
const node = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_node",
arguments: {
nodeId: "4029:12345",
fileKey: "abc123"
}
});
Design Tokens & Styles
Get All Styles
const styles = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_styles",
arguments: { fileKey: "abc123" }
});
Get Variable Definitions (Design Tokens)
const variables = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_variable_defs",
arguments: { fileKey: "abc123" }
});
Screenshots & Export
Get Screenshot (Base64)
const screenshot = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_screenshot",
arguments: {
nodeIds: ["4029:12345", "4029:67890"],
format: "PNG",
scale: 2,
fileKey: "abc123"
}
});
Save Screenshots to Filesystem
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "save_screenshots",
arguments: {
nodeIds: ["4029:12345"],
outputDir: "/path/to/output",
format: "PNG",
scale: 2,
fileKey: "abc123"
}
});
Write Tools (Design Editor Only)
Important: Write tools only work when plugin is opened in Figma's design editor. Dev Mode is read-only and returns clear errors.
Creating Nodes
Create Frame
const frame = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "create_frame",
arguments: {
name: "Card Container",
x: 100,
y: 200,
width: 320,
height: 480,
parentId: "4029:100",
fileKey: "abc123"
}
});
Create Text
const text = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "create_text",
arguments: {
content: "Hello World",
x: 150,
y: 250,
fontFamily: "Inter",
fontStyle: "Bold",
fontSize: 24,
parentId: "4029:100",
fileKey: "abc123"
}
});
Create Shape
const shape = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "create_shape",
arguments: {
type: "RECTANGLE",
name: "Background",
x: 0,
y: 0,
width: 320,
height: 480,
parentId: "4029:100",
fileKey: "abc123"
}
});
Create Image
const image = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "create_image",
arguments: {
source: "/path/to/image.png",
name: "Hero Image",
x: 0,
y: 0,
width: 800,
height: 600,
parentId: "4029:100",
fileKey: "abc123"
}
});
Modifying Nodes
Set Node Properties
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "set_node_properties",
arguments: {
nodeId: "4029:12345",
name: "Updated Frame",
x: 200,
y: 300,
width: 400,
height: 600,
visible: true,
opacity: 0.9,
cornerRadius: 8,
fileKey: "abc123"
}
});
Set Text Content
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "set_text_content",
arguments: {
nodeId: "4029:12345",
content: "New text content",
fileKey: "abc123"
}
});
Set Text Properties
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "set_text_properties",
arguments: {
nodeId: "4029:12345",
fontFamily: "Roboto",
fontStyle: "Medium",
fontSize: 18,
textAlignHorizontal: "CENTER",
textAlignVertical: "TOP",
textAutoResize: "WIDTH_AND_HEIGHT",
color: { r: 0.2, g: 0.3, b: 0.4, a: 1.0 },
x: 100,
y: 200,
width: 300,
height: 100,
fileKey: "abc123"
}
});
Set Solid Fill
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "set_solid_fill",
arguments: {
nodeId: "4029:12345",
color: { r: 0.1, g: 0.5, b: 0.9, a: 1.0 },
paintType: "fills",
fileKey: "abc123"
}
});
Set Gradient Fill
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "set_gradient_fill",
arguments: {
nodeId: "4029:12345",
gradientType: "GRADIENT_LINEAR",
stops: [
{ position: 0, color: { r: 1, g: 0, b: 0, a: 1 } },
{ position: 1, color: { r: 0, g: 0, b: 1, a: 1 } }
],
paintType: "fills",
fileKey: "abc123"
}
});
Set Effects (Shadows, Blurs)
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "set_effects",
arguments: {
nodeId: "4029:12345",
effects: [
{
type: "DROP_SHADOW",
color: { r: 0, g: 0, b: 0, a: 0.25 },
offset: { x: 0, y: 4 },
radius: 8,
visible: true
},
{
type: "LAYER_BLUR",
radius: 4,
visible: true
}
],
fileKey: "abc123"
}
});
Set Stroke Properties
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "set_stroke_properties",
arguments: {
nodeId: "4029:12345",
strokeWeight: 2,
strokeAlign: "INSIDE",
dashPattern: [5, 3],
strokeCap: "ROUND",
strokeJoin: "ROUND",
fileKey: "abc123"
}
});
Set Auto Layout
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "set_auto_layout",
arguments: {
nodeId: "4029:12345",
layoutMode: "VERTICAL",
primaryAxisAlignItems: "CENTER",
counterAxisAlignItems: "CENTER",
paddingLeft: 16,
paddingRight: 16,
paddingTop: 12,
paddingBottom: 12,
itemSpacing: 8,
primaryAxisSizingMode: "AUTO",
counterAxisSizingMode: "FIXED",
layoutWrap: "NO_WRAP",
fileKey: "abc123"
}
});
Node Operations
Duplicate Nodes
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "duplicate_nodes",
arguments: {
nodeIds: ["4029:12345", "4029:67890"],
fileKey: "abc123"
}
});
Reparent Nodes
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "reparent_nodes",
arguments: {
nodeIds: ["4029:12345"],
newParentId: "4029:100",
index: 0,
fileKey: "abc123"
}
});
Group Nodes
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "group_nodes",
arguments: {
nodeIds: ["4029:12345", "4029:67890"],
name: "Card Group",
fileKey: "abc123"
}
});
Ungroup Node
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "ungroup_node",
arguments: {
nodeId: "4029:12345",
fileKey: "abc123"
}
});
Delete Nodes
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "delete_nodes",
arguments: {
nodeIds: ["4029:12345"],
confirm: true,
fileKey: "abc123"
}
});
Selection & Viewport
Set Selection
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "set_selection",
arguments: {
nodeIds: ["4029:12345", "4029:67890"],
fileKey: "abc123"
}
});
Scroll and Zoom into View
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "scroll_and_zoom_into_view",
arguments: {
nodeIds: ["4029:12345"],
fileKey: "abc123"
}
});
Animation Tools (Beta)
Get Motion Styles
const styles = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_motion_styles",
arguments: { fileKey: "abc123" }
});
Apply Animation Style
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "apply_animation_style",
arguments: {
nodeId: "4029:12345",
styleId: "motion-style-id",
fileKey: "abc123"
}
});
Apply Manual Keyframe Track
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "apply_manual_keyframe_track",
arguments: {
nodeId: "4029:12345",
property: "x",
keyframes: [
{ time: 0, value: 0 },
{ time: 1, value: 100 }
],
fileKey: "abc123"
}
});
Common Patterns
Extract Design System Tokens
const [styles, variables] = await Promise.all([
use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_styles",
arguments: { fileKey: "design-system-key" }
}),
use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_variable_defs",
arguments: { fileKey: "design-system-key" }
})
]);
const cssVars = variables.collections.flatMap(collection =>
collection.modes.flatMap(mode =>
Object.entries(mode.values).map(([name, value]) =>
`--${name}: ${value};`
)
)
);
Build Component from Selection
const selection = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_selection",
arguments: {}
});
const nodeDetails = await Promise.all(
selection.map(node =>
use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_node",
arguments: { nodeId: node.id }
})
)
);
Create Slide Deck from Template
const titleSlide = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "create_frame",
arguments: {
name: "Slide 1",
x: 0,
y: 0,
width: 1920,
height: 1080
}
});
await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "create_text",
arguments: {
content: "Presentation Title",
parentId: titleSlide.id,
x: 960,
y: 400,
fontFamily: "Inter",
fontStyle: "Bold",
fontSize: 72
}
});
const duplicated = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "duplicate_nodes",
arguments: { nodeIds: [titleSlide.id] }
});
Export All Components as SVG
const doc = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_document",
arguments: {}
});
const components = findNodesByType(doc, "COMPONENT");
for (const component of components) {
await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "save_screenshots",
arguments: {
nodeIds: [component.id],
outputDir: "./components",
format: "SVG"
}
});
}
Multi-File Design Token Sync
const files = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "list_files",
arguments: {}
});
const sourceVars = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_variable_defs",
arguments: { fileKey: files[0].fileKey }
});
for (const file of files.slice(1)) {
const projectDoc = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_document",
arguments: { fileKey: file.fileKey }
});
}
Troubleshooting
Plugin Shows "Disconnected"
- Ensure MCP server is running (check AI tool logs)
- Restart the Figma plugin
- Check WebSocket port 1994 is not blocked by firewall
- For local dev, verify
server/dist/index.js path is correct
"Cannot edit in Dev Mode" Error
Write tools only work in Figma's design editor. Switch from Dev Mode to design view:
- Click "Design" tab at top of Figma window
- Or close Dev Mode sidebar
Font Loading Errors
When creating/editing text nodes, the plugin must load fonts. Ensure:
- Font family/style names are exact (case-sensitive)
- Fonts are available in your Figma account
- For new text nodes without font specified,
Inter Regular is used as default
Multi-File fileKey Issues
- Use
list_files to see all connected files and their keys
- If
fileKey is omitted and multiple files are connected, tools may fail
- File key format: short alphanumeric string (e.g.,
"abc123XYZ"), not full URL
Screenshot Export Fails
- Ensure nodes exist and are visible
- For
save_screenshots, check output directory permissions
- Large exports may timeout — reduce scale or node count
- SVG export only works for vector-compatible nodes
Node ID Format
Node IDs must use colon format: "4029:12345", not 4029-12345 or other variants. Copy IDs directly from:
get_selection results
get_document tree
- Figma plugin Dev Mode inspector
Leader Election Issues
If multiple MCP server instances are running (e.g., multiple AI tools):
- Only one becomes "leader" and accepts WebSocket connections
- Others become "followers" and proxy requests to leader via HTTP
- If leader crashes, a follower automatically promotes itself
- Check logs for "Elected as leader" or "Running as follower" messages
Local Development Build Issues
cd server
npm install
npm run build
cd plugin
bun install
bun run build
npm install -g bun
Ensure server/dist/index.js exists after build before configuring MCP client.