- 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](https://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.):
```json
{
"mcpServers": {
"figma-bridge": {
"command": "npx",
"args": ["-y", "@gethopp/figma-mcp-bridge"]
}
}
}
```
For **local development**:
```json
{
"mcpServers": {
"figma-bridge": {
"command": "node",
"args": ["/absolute/path/to/figma-mcp-bridge/server/dist/index.js"]
}
}
}
```
### 2. Install Figma Plugin
1. Download `plugin/` folder from [latest release](https://github.com/gethopp/figma-mcp-bridge/releases)
2. In Figma: `Plugins > Development > Import plugin from manifest`
3. Select `manifest.json` from the downloaded `plugin/` folder
### 3. Connect Plugin to File
1. Open your Figma file
2. Run the imported plugin: `Plugins > Development > Figma MCP Bridge`
3. 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
```typescript
// 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
```typescript
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
```typescript
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)
```typescript
// 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
```typescript
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
```typescript
// 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
```typescript
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)
```typescript
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)
```typescript
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
```typescript
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
```typescript
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
```typescript
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
```typescript
// 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
```typescript
// 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
```typescript
// 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
```typescript
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
```typescript
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
```typescript
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
```typescript
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)
```typescript
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
View on GitHub