Figma 设计读写 MCP 服务

Figma Pilot 通过 MCP 和本地插件连接 AI 智能体与 Figma Desktop,支持设计文档的读取、编辑、批量操作以及设计转代码/代码转设计,适用于 AI 驱动的设计自动化与协作开发场景。

  • by chicunic
  • TypeScript
  • 本地部署
  • 2 星标
  • 更新于
在 GitHub 查看 chicunic/figma-pilot-mcp

使用说明

figma-pilot-mcp

Read and edit Figma designs through MCP and a local plugin.

Figma Pilot connects your AI agent to the open document in Figma Desktop through a local WebSocket relay.

Agent: "Read the Card component and build a matching Modal."
  → pilot_get_selection      inspect what's selected
  → pilot_create_node_tree   build the new frame in one call
  → pilot_set_auto_layout    match the spacing

Five design stages exported during a live MCP session in Figma Desktop: create a canvas, chain commands, add text, apply auto layout, and refine colors and copy.

Features

  • Full read-write access — 97 tools covering nodes, styles, variables, components, prototypes, and export
  • Bidirectional — read a design to generate code, or generate a design from a prompt
  • Batch operations — chain commands with result references ($0.id) in one round trip
  • Flexible deployment — all-in-one, or split MCP and WebSocket for multi-agent setups

How It Works

The MCP server uses stdio to talk to your agent and WebSocket to reach the plugin's UI iframe. The plugin main thread reads and edits the document:

graph LR
  A[AI Agent] <--stdio--> B[MCP Server]
  B <--ws--> C[Figma Plugin]
  C <--> D[Figma Document]

The plugin joins a channel shown in its UI; the MCP server connects to that same channel. The name uses the file key when available, otherwise the document name. Copy the displayed value to avoid connecting to a different document.

Prerequisites

  • Bun 1.0+ — the server uses Bun.serve; development is verified with the version in packageManager.
  • Figma Desktop — import and run the development plugin here.

Getting Started

Clone or download this repository, then run commands from its root.

  1. Install dependencies and build the plugin:

    bun install
    bun run build
    
  2. Import the plugin into Figma Desktop:

    • Plugins → Development → Import plugin from manifest...
    • Select the dist/plugin/manifest.json in this project folder
  3. Configure your AI agent (see below)

  4. Run the plugin and connect:

    • Open a design file in Design mode, run Plugins → Development → Figma Pilot
    • The plugin UI shows a channel name (e.g., figma-pilot-abc123)
    • In your AI agent, use pilot_connect with the channel name

Verify the setup at any time with bunx --package figma-pilot-mcp figma-pilot doctor.

Usage

Once connected, drive it in plain language — the agent picks the tools. A few things it handles well:

Design to code — read what exists, then generate from it:

"Read the selected frame and write a React component that matches it."

Code to design — build new UI from a description:

"Create a 320×180 card with a title, divider, and body text, using auto layout with 12px spacing."

Bulk edits — most modification tools accept an array of node IDs:

"Find every frame named Button/* and set its corner radius to 8."

Chaining commands

pilot_batch runs commands in sequence and lets later steps reference earlier results with $N:

{
  "commands": [
    {
      "command": "create_frame",
      "params": { "name": "Card", "width": 300, "height": 200 },
    },
    {
      "command": "create_text",
      "params": { "parentId": "$0.id", "characters": "Title" },
    },
    {
      "command": "set_auto_layout",
      "params": { "nodeId": "$0.id", "mode": "VERTICAL" },
    },
  ],
}

$0.id resolves to the id field of the first command's result. Dot paths may also index arrays: $0.children.0.id.

A reference must be the entire value. "prefix-$0.id" is left as a literal string, and "$0.id-suffix" is an error — the trailing text is read as part of the property name.

The batch stops on the first error by default. Set stopOnError: false to continue with later commands; failed entries occupy a null slot in results, so references keep their original indexes. Any failure sets isError: true and appears in errors, including reference resolution failures. executed counts processed entries, including failures.

Trimming responses

Read tools accept a fields array to cut response size — useful when a node has more properties than you need:

{ "nodeId": "1:23", "fields": ["id", "name", "width", "height"] }

Configure Your AI Agent

Mode 1: All-in-one (recommended)

graph LR
  A[AI Agent] <--stdio--> B[MCP + WS Server] <--ws--> C[Figma Plugin]
{
  "mcpServers": {
    "figma-pilot": {
      "command": "bunx",
      "args": ["--package", "figma-pilot-mcp", "figma-pilot", "start"],
    },
  },
}

Mode 2: Separate WS + MCP (multi-agent)

graph LR
  A[AI Agent A] <--stdio--> C[MCP only]
  B[AI Agent B] <--stdio--> D[MCP only]
  C <--ws--> E[WS Server]
  D <--ws--> E
  E <--ws--> F[Figma Plugin]
  1. Start the WebSocket server:

    bunx --package figma-pilot-mcp figma-pilot start --mode=ws
    
  2. Configure AI agents:

    {
      "mcpServers": {
        "figma-pilot": {
          "command": "bunx",
          "args": [
            "--package",
            "figma-pilot-mcp",
            "figma-pilot",
            "start",
            "--mode=mcp",
          ],
        },
      },
    }
    

Reference

Mode Summary

Mode CLI MCP WS Server WS Client Use Case
all --mode=all Yes Yes No Single-agent
mcp --mode=mcp Yes No Yes Multi-agent / remote WS
ws --mode=ws No Yes No Standalone relay

CLI Commands

Command Description
bunx --package figma-pilot-mcp figma-pilot init Install dependencies and build the plugin
bunx --package figma-pilot-mcp figma-pilot build Rebuild the Figma plugin
bunx --package figma-pilot-mcp figma-pilot start Start the server (default: all-in-one mode)
bunx --package figma-pilot-mcp figma-pilot doctor Run diagnostics checks

Configuration

Variable Default Description
FIGMA_WS_PORT 3846 WebSocket port
FIGMA_WS_HOST localhost WebSocket host
FIGMA_REQUEST_TIMEOUT 30000 Request timeout (ms)
FIGMA_PILOT_MODE read-write Tool mode: read-write / write-only (omits read tools)
FIGMA_RUN_MODE all Run mode: all / mcp / ws

Troubleshooting

Start with bunx --package figma-pilot-mcp figma-pilot doctor — it checks the runtime, the plugin build, and port availability.

Symptom Cause and fix
Not connected to Figma. Use pilot_connect first. The server is running but no channel is joined. Run the plugin and call pilot_connect with its channel name.
No Figma plugin connected to this channel. The plugin is disconnected or the channel name does not match. Connect the plugin and copy the current channel from its UI.
Port 3846 is already in use. Another instance is running, or a previous one did not exit. Stop it, or set FIGMA_WS_PORT.
Figma plugin disconnected. The plugin was closed or Figma crashed mid-command. Re-open the plugin and reconnect.
Agent has no read tools FIGMA_PILOT_MODE is set to write-only. Unset it, or set it to read-write.
Plugin missing in Figma Import dist/plugin/manifest.json, not the copy under src/. Run bunx --package figma-pilot-mcp figma-pilot build if dist/ is absent.
figma-pilot requires the Bun runtime You ran it under Node.js. Install Bun and use bunx --package figma-pilot-mcp figma-pilot, not npx.
Commands time out after 30s The document may be very large. Raise FIGMA_REQUEST_TIMEOUT, or narrow the operation to fewer nodes.

Available Tools

Connection

Tool Description
pilot_connect Connect to Figma plugin via WebSocket. Required before other operations.
pilot_disconnect Disconnect from Figma plugin.
pilot_status Get WebSocket connection status.

Creation

Tool Description
pilot_create_shape Create shape: frame/rect/ellipse/polygon/star/line/vector
pilot_create_text Create a text layer with content, font, and size
pilot_create_component Create a new empty component
pilot_create_component_from_node Convert an existing node into a reusable component
pilot_create_instance Create / place an instance of a component
pilot_create_page Create a new page in the document
pilot_create_section Create a section container
pilot_create_slice Create export slice
pilot_create_from_svg Import / create a node from an SVG string
pilot_create_image Create image from base64 or URL
pilot_create_table Create table (FigJam)
pilot_create_sticky Create FigJam sticky note
pilot_create_connector Create FigJam connector between nodes
pilot_create_shape_with_text Create FigJam shape with text
pilot_create_node_tree Create nested node tree in one call

Text

Tool Description
pilot_set_text Edit text: content, font family/size/weight, color, line height, letter spacing, alignment, case, and decoration [BATCH]

Modification

Tool Description
pilot_set_fill Set fill / background color of a node: solid color or gradient [BATCH]
pilot_set_stroke Set stroke / border color and weight: solid color or gradient [BATCH]
pilot_set_corners Set corner radius / rounded corners (uniform or per-corner) [BATCH]
pilot_move_node Move node to position
pilot_resize_node Resize node [BATCH]
pilot_set_rotation Rotate a node (degrees) [BATCH]
pilot_set_opacity Set opacity / transparency (0-1) [BATCH]
pilot_set_blend_mode Set blend mode (multiply, overlay, screen, etc.) [BATCH]
pilot_set_visible Show or hide a node (visibility) [BATCH]
pilot_set_locked Lock or unlock a node against editing [BATCH]
pilot_set_name Rename a node (set layer name)
pilot_set_effect Add drop shadow or blur effect, or clear all effects [BATCH]
pilot_set_auto_layout Set auto layout on a frame: direction, spacing, padding, alignment [BATCH]
pilot_set_constraints Set resize constraints / pinning relative to parent [BATCH]
pilot_delete_node Delete / remove a node from the document [BATCH]
pilot_clone_node Clone / duplicate a node
pilot_group_nodes Group multiple nodes into a group
pilot_ungroup_node Ungroup a group, releasing its children
pilot_flatten_nodes Flatten to single vector
pilot_boolean Boolean operation on nodes
pilot_set_current_page Set current page
pilot_set_viewport Set viewport center/zoom
pilot_scroll_to_node Scroll and zoom the viewport to show a node
pilot_set_selection Select nodes on the canvas (set current selection)
pilot_notify Show notification
pilot_set_image_fill Set image fill on node (by hash, base64, or URL)
pilot_set_image_filters Set filters on existing IMAGE fill [BATCH]

Layout

Tool Description
pilot_set_layout_child Set auto layout child behavior: fill/hug sizing, min/max size, align, or absolute positioning. One group per call [BATCH]
pilot_set_layout_wrap Set layout wrap mode
pilot_set_clips_content Set frame clips content [BATCH]
pilot_set_overflow Set overflow direction [BATCH]
pilot_set_guides Set guides on frame/page

Node Hierarchy

Tool Description
pilot_move_child Append/insert/reorder child in parent

Instance Operations

Tool Description
pilot_detach_instance Detach instance from component
pilot_reset_overrides Reset instance overrides
pilot_swap_component Swap instance to different component

Styles

Tool Description
pilot_create_style Create paint/text/effect/grid style
pilot_apply_style Apply style to node
pilot_move_style Reorder style in list

Variables & Properties

Tool Description
pilot_create_variable_collection Create variable collection
pilot_create_variable Create variable
pilot_set_variable_value Set variable value for mode
pilot_create_variable_alias Create variable alias
pilot_bind_variable Bind variable to property/paint/effect/grid
pilot_set_component_properties Set instance properties

Team Library

Tool Description
pilot_import_library Import component/style/variable from library
pilot_import_style_by_key Import style by key
pilot_import_variable_by_key Import variable by key

Export & Prototype

Tool Description
pilot_set_export_settings Set export settings
pilot_set_reactions Set prototype reactions

Reading

Tool Description
pilot_get_node Read a node: geometry, styles, fills, text, and layout properties
pilot_get_selection Get the nodes currently selected on the canvas
pilot_find_nodes Search / find nodes by type or name pattern (supports wildcards)
pilot_get_children List direct children of a node (traverse the layer tree)
pilot_get_top_frame Get top-level frame containing node
pilot_get_current_page Get current page info
pilot_get_pages List all pages in the document
pilot_get_local_styles List local paint, text, effect, and grid styles
pilot_get_local_components List local components in the file
pilot_get_local_variables Get local variables
pilot_get_variable_collections Get variable collections
pilot_get_viewport Get viewport center and zoom level
pilot_export_node Export / render a node as a PNG, JPG, SVG, or PDF image
pilot_get_component_properties Get component/instance properties
pilot_get_export_settings Get export settings of node
pilot_get_reactions Get prototype reactions of node
pilot_get_library_variable_collections Get library variable collections
pilot_get_library_variables Get library variables by collection
pilot_get_component_set_variants Get variants of library component set
pilot_get_image Get image info/bytes by hash
pilot_list_available_fonts List available font families and styles (searchable)
pilot_get_selection_colors Get all colors used in the current selection
pilot_parse_color Parse color string to RGB/RGBA
pilot_get_event_subscriptions Get event subscription status

Events & Utilities

Tool Description
pilot_event Subscribe/unsubscribe to events
pilot_create_solid_paint Create solid paint object
pilot_combine_as_variants Combine components as variants

Batch

Tool Description
pilot_batch Execute multiple commands in sequence. Use $N to reference previous result (e.g., $0.id).

Development

bun install --frozen-lockfile
bun run check
bun run build

check runs TypeScript checks for the server and plugin, Biome, and tests. The TypeScript dependency uses npm:@typescript/typescript6@^6.0.2, and checks invoke tsc6 to stay on TypeScript 6. The build uses the installed esbuild dependency and writes dist/plugin; reload the development plugin after rebuilding.

Use bun run dev for the server, or bun run dev:ws and bun run dev:mcp for separate relay and MCP processes. The plugin implementation notes describe the message flow, API helpers, and how to add a tool. The manifest currently enables the Figma editor; FigJam commands require an appropriate editor configuration.

License

MIT