Imported from reason-machines/mcp-skills (
skills/figma-mcp-bridge/SKILL.md). Install upstream withnpx skills add reason-machines/mcp-skills --skill figma-mcp-bridge. Copyright stays with the author.
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.jsonfrom the downloadedplugin/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
// When multiple Figma files are connected
const files = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "list_files",
arguments: {}
});
// Returns: [{ fileKey: "abc123", name: "Design System" }, ...]
Get File Metadata
const metadata = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_metadata",
arguments: {
fileKey: "abc123" // Optional if only one file connected
}
});
// Returns: { name: "Mobile App", pages: [...], currentPage: {...} }
Reading Document Structure
Get Full Document Tree
const doc = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_document",
arguments: {
fileKey: "abc123" // Optional
}
});
// Returns complete node tree of current page
Get Design Context (Depth-Limited Tree)
// Optimized for AI understanding, limits depth to reduce token usage
const context = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_design_context",
arguments: {
maxDepth: 3, // Default: 3
fileKey: "abc123"
}
});
Get Current Selection
const selection = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_selection",
arguments: { fileKey: "abc123" }
});
// Returns array of selected nodes with full properties
Get Specific Node by ID
// Node IDs use colon format: "4029:12345"
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" }
});
// Returns: { paintStyles: [...], textStyles: [...], effectStyles: [...], gridStyles: [...] }
Get Variable Definitions (Design Tokens)
const variables = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_variable_defs",
arguments: { fileKey: "abc123" }
});
// Returns all variable collections, modes, and values
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", // PNG | SVG | JPG | PDF
scale: 2, // Export scale multiplier
fileKey: "abc123"
}
});
// Returns base64-encoded image data
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", // Absolute or relative to MCP server working dir
format: "PNG",
scale: 2,
fileKey: "abc123"
}
});
// Saves files as: output/node-4029-12345.png
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", // Optional, defaults to current page
fileKey: "abc123"
}
});
// Returns: { id: "4029:12345", message: "Frame created" }
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", // Optional, defaults to Inter Regular
fontStyle: "Bold",
fontSize: 24,
parentId: "4029:100",
fileKey: "abc123"
}
});
Create Shape
// Rectangle, Ellipse, or Line
const shape = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "create_shape",
arguments: {
type: "RECTANGLE", // RECTANGLE | ELLIPSE | LINE
name: "Background",
x: 0,
y: 0,
width: 320,
height: 480,
parentId: "4029:100",
fileKey: "abc123"
}
});
Create Image
// From local path, URL, or data URI
const image = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "create_image",
arguments: {
source: "/path/to/image.png", // Local path (relative to MCP server), URL, or data:image/...
name: "Hero Image",
x: 0,
y: 0,
width: 800,
height: 600,
parentId: "4029:100",
fileKey: "abc123"
}
});
Modifying Nodes
Set Node Properties
// Patch common properties: name, position, size, visibility, opacity, corner radius
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"
}
});
// Automatically loads required fonts
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", // LEFT | CENTER | RIGHT | JUSTIFIED
textAlignVertical: "TOP", // TOP | CENTER | BOTTOM
textAutoResize: "WIDTH_AND_HEIGHT", // NONE | WIDTH_AND_HEIGHT | 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", // "fills" | "strokes"
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", // GRADIENT_LINEAR | GRADIENT_RADIAL | GRADIENT_ANGULAR | GRADIENT_DIAMOND
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"
}
});
// Effect types: DROP_SHADOW | INNER_SHADOW | LAYER_BLUR | BACKGROUND_BLUR
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", // CENTER | INSIDE | OUTSIDE
dashPattern: [5, 3], // Array of dash/gap lengths, [] for solid
strokeCap: "ROUND", // NONE | ROUND | SQUARE | ARROW_LINES | ARROW_EQUILATERAL
strokeJoin: "ROUND", // MITER | BEVEL | 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", // NONE | HORIZONTAL | VERTICAL
primaryAxisAlignItems: "CENTER", // MIN | CENTER | MAX | SPACE_BETWEEN
counterAxisAlignItems: "CENTER", // MIN | CENTER | MAX
paddingLeft: 16,
paddingRight: 16,
paddingTop: 12,
paddingBottom: 12,
itemSpacing: 8,
primaryAxisSizingMode: "AUTO", // FIXED | AUTO
counterAxisSizingMode: "FIXED",
layoutWrap: "NO_WRAP", // NO_WRAP | 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"
}
});
// Returns: { duplicatedIds: ["4029:11111", "4029:22222"] }
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, // Optional insertion index
fileKey: "abc123"
}
});
Group Nodes
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "group_nodes",
arguments: {
nodeIds: ["4029:12345", "4029:67890"], // Must share same parent
name: "Card Group",
fileKey: "abc123"
}
});
// Returns: { groupId: "4029:99999" }
Ungroup Node
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "ungroup_node",
arguments: {
nodeId: "4029:12345", // Must be GROUP or FRAME
fileKey: "abc123"
}
});
// Children move up to parent, group is deleted
Delete Nodes
// Requires explicit confirmation
const result = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "delete_nodes",
arguments: {
nodeIds: ["4029:12345"],
confirm: true, // REQUIRED
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"
}
});
// Works in both design editor and Dev Mode
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"
}
});
// Frames viewport around specified nodes
Animation Tools (Beta)
Get Motion Styles
const styles = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_motion_styles",
arguments: { fileKey: "abc123" }
});
// Returns list of available animation presets
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", // x, y, width, height, opacity, rotation, etc.
keyframes: [
{ time: 0, value: 0 },
{ time: 1, value: 100 }
],
fileKey: "abc123"
}
});
Common Patterns
Extract Design System Tokens
// Get all styles and variables for design system documentation
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" }
})
]);
// Convert to CSS custom properties
const cssVars = variables.collections.flatMap(collection =>
collection.modes.flatMap(mode =>
Object.entries(mode.values).map(([name, value]) =>
`--${name}: ${value};`
)
)
);
Build Component from Selection
// 1. Get currently selected nodes
const selection = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_selection",
arguments: {}
});
// 2. Get detailed node data
const nodeDetails = await Promise.all(
selection.map(node =>
use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_node",
arguments: { nodeId: node.id }
})
)
);
// 3. Generate React component code from node structure
// (Your code generation logic here)
Create Slide Deck from Template
// 1. Create title slide
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
}
});
// 2. Add title text
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
}
});
// 3. Duplicate slide for content pages
const duplicated = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "duplicate_nodes",
arguments: { nodeIds: [titleSlide.id] }
});
// 4. Update duplicated slide content
// ...
Export All Components as SVG
// 1. Get document tree
const doc = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_document",
arguments: {}
});
// 2. Find all component nodes
const components = findNodesByType(doc, "COMPONENT");
// 3. Export each as SVG
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
// 1. List all connected files
const files = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "list_files",
arguments: {}
});
// 2. Get variables from source design system
const sourceVars = await use_mcp_tool({
server_name: "figma-bridge",
tool_name: "get_variable_defs",
arguments: { fileKey: files[0].fileKey } // Design system file
});
// 3. For each project file, validate variable usage
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 }
});
// Check for inconsistent variable references
// ...
}
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.jspath 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 Regularis used as default
Multi-File fileKey Issues
- Use
list_filesto see all connected files and their keys - If
fileKeyis 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_selectionresultsget_documenttree- 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
# Server build
cd server
npm install
npm run build
# Plugin build
cd plugin
bun install
bun run build
# If bun not installed
npm install -g bun
Ensure server/dist/index.js exists after build before configuring MCP client.