Skill Store 33

Figma Mcp Bridge

Bypass Figma API limits by streaming live document data from Figma plugin to AI tools via MCP ser…

by reason-machines · MIT

The skill

Bypass Figma API limits by streaming live document data from Figma plugin to AI tools via MCP server for design-to-code workflows

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

  1. Download plugin/ folder from latest release
  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
// 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"

  1. Ensure MCP server is running (check AI tool logs)
  2. Restart the Figma plugin
  3. Check WebSocket port 1994 is not blocked by firewall
  4. 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

# 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.

Use this skill

Connect your agent to the Skill Store MCP server and ask for it by ref: reason-machines/figma-mcp-bridge-42097400114.

Download SKILL.md · Markdown version

Details

Publisher
reason-machines
Category
Software Development › Frontend & UI
License
MIT
Updated
2026-10-09

References

More from reason-machines