Figma Bridge Mcp

io.github.nguyendinhphongdx由 GitHub 帳號 nguyendinhphongdx 發布v2.6.1更新於 Nov 11, 2026

Bidirectional Figma MCP — AI draws UI on Figma canvas, reads designs back

發布方自己的服務:Figma MCP Server

已驗證STDIO僅桌面開發者工具媒體與設計

概覽

AI 產生的概覽

把 AI 助理連接到你在 Figma 桌面版中開啟的文件,讓它直接在畫布上繪製介面,並把設計讀回成資料與程式碼。

可以做什麼
  • 檢查連線狀態、目前檔案、頁面與外掛工作階段
  • 載入 figma.* API 參考,以及顏色、文字樣式、變數與元件的設計規則表
  • 在沙箱中執行 JavaScript 來建立與修改設計內容:畫框、文字、向量、圖片、元件、變數、樣式與原型互動
  • 擷取設計資料:節點樹、解析後的設計權杖、CSS、元件對應、截圖,以及 SVG/PNG 匯出
  • 依類型、名稱、顏色、字型或尺寸搜尋與掃描節點,並可透過工作階段指定某個已開啟的檔案
適用情境
適合在 Figma 桌面版中工作、希望助理產生或反覆調整版面、套用既有設計系統,或把選取的畫框轉成 Tailwind、React、Swift 等程式碼的情境。
執行需求
以本機 Node.js 程序透過 stdio 執行,通常用 npx 啟動;必須使用 Figma 桌面版,因為網頁版無法連到 localhost。需要在 Figma 桌面版中從 manifest 匯入並執行搭配的外掛。未宣告需要 Figma API 金鑰或帳號憑證。選用環境變數可設定橋接埠、綁定位址、長輪詢時間與私有位址抓取開關。
安裝前請注意
橋接沒有登入機制,能連到該埠的人都能操作它,請維持預設的本機回環綁定位址。figma_write 在 Node vm 沙箱中執行 JavaScript,而 vm 並非程序邊界,不要執行不受信任的程式碼。寫入操作會在您的 Figma 文件中建立、修改與刪除節點,loadImage/loadIcon 會連外抓取網址。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Figma Bridge Mcp,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

[figma-bridge-mcp — Bridge MCP for Figma]

Let AI draw on your Figma canvas — and read your designs back as code.

A bidirectional Model Context Protocol bridge for Figma Desktop.
No Figma API key. No cloud. Everything runs on localhost.

[npm] [CI] [Node] [MCP Registry] [License: MIT]

Quick start · How it works · Tools · Security · Troubleshooting · Changelog

Not affiliated with, endorsed by, or sponsored by Figma, Inc. "Figma" is a trademark of Figma, Inc., used here only to describe compatibility.


Overview

figma-bridge-mcp connects an AI assistant to the document you have open in Figma Desktop.

✍️ WriteThe AI runs JavaScript against a figma.* API to create frames, text, vectors, components, variables, prototypes.
👀 ReadThe AI extracts node trees, resolved design tokens, CSS, component maps and screenshots — ready for design-to-code.
🔒 LocalThe bridge listens on 127.0.0.1 only. Nothing leaves your machine.
🧩 Any MCP client✅ Tested with Claude Code and Antigravity. 🔧 Compatible with Cursor, VS Code, Windsurf, Zed and any stdio MCP client.

Requires Figma Desktop. The plugin talks to the server over localhost, which Figma's web app does not allow.


How it works

Three parts cooperate: your AI client, the MCP server (Node), and the Figma plugin (inside Figma Desktop). The plugin polls the server, so no inbound connection to Figma is ever needed.

mermaid
flowchart LR  subgraph Client["AI client"]    A["Claude Code · Cursor · Windsurf<br/>VS Code · Antigravity · any MCP client"]  end  subgraph Server["figma-bridge-mcp  (Node)"]    B["MCP server<br/>5 tools · stdio"]    C["Code sandbox<br/>runs figma_write code"]    D["HTTP bridge<br/>127.0.0.1:47451"]  end  subgraph Figma["Figma Desktop"]    E["Plugin UI<br/>long-poll client"]    F["Plugin main thread<br/>66 operations"]    G[("Figma document")]  end  A <-->|"MCP / stdio"| B  B --> C  C --> D  B --> D  D <-->|"HTTP long-poll"| E  E <-->|postMessage| F  F <--> G

One round trip

The server holds each poll open for up to 8 s and answers the moment work is queued, so latency is typically under 100 ms.

mermaid
sequenceDiagram  autonumber  participant AI as AI client  participant S as MCP server  participant B as Bridge :47451  participant P as Figma plugin  AI->>S: figma_write { code }  S->>S: run code in sandbox  S->>B: queue operation (create, modify, …)  P->>B: GET /poll  (held up to 8 s)  B-->>P: operations  P->>P: apply to the Figma document  P->>B: POST /response { id, data }  B-->>S: resolve operation  S-->>AI: result + logs

Several Figma files at once

Each open plugin instance registers its own session. Pass the optional sessionId to figma_write / figma_read to target a specific file; if that session is not connected the call fails instead of writing into another file.


Quick start

1 · Add the MCP server to your client

Claude Code
bash
claude mcp add figma-bridge-mcp -- npx @hanoilab/figma-bridge-mcp          # this projectclaude mcp add --scope user figma-bridge-mcp -- npx @hanoilab/figma-bridge-mcp   # all projects
Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

json
{  "mcpServers": {    "figma": { "command": "npx", "args": ["-y", "@hanoilab/figma-bridge-mcp"] }  }}
Cursor

Edit .cursor/mcp.json (project) or ~/.cursor/mcp.json (global) with the same mcpServers block shown for Claude Desktop.

VS Code / GitHub Copilot

Edit .vscode/mcp.json, or add to settings.json:

json
{  "mcp": {    "servers": {      "figma": { "command": "npx", "args": ["-y", "@hanoilab/figma-bridge-mcp"] }    }  }}
Windsurf

Edit ~/.codeium/windsurf/mcp_config.json with the same mcpServers block shown for Claude Desktop.

Antigravity (Google)

Agent panel "…" menu → Manage MCP Servers → View raw config, then add the same mcpServers block to mcp_config.json.

From source
bash
git clone https://github.com/nguyendinhphongdx/figma-bridge-mcpcd figma-bridge-mcp && npm install# point your MCP client at: node /path/to/figma-bridge-mcp/server/index.js

Restart your client after editing its config. MCP servers load only at startup.

2 · Install the Figma plugin

  1. ⬇ Download the plugin and unzip it anywhere.
  2. In Figma Desktop: Plugins → Development → Import plugin from manifest… and pick manifest.json.
  3. Run Plugins → Development → Bridge MCP for Figma.

The plugin window shows a green dot once it reaches the server.

3 · Connect and design

Tell your assistant:

"Connect to figma-bridge-mcp"

It calls figma_status and confirms the file, page and plugin version. Then just describe what you want:

"Draw a mobile login screen with Apple and Google sign-in buttons."

mermaid
flowchart LR  P["Your prompt"] --> D["figma_docs<br/>load API + design rules"]  D --> R["figma_read<br/>inspect the canvas"]  R --> W["figma_write<br/>draw / modify"]  W --> S["figma_read screenshot<br/>verify"]  S -->|"needs fixes"| W  S -->|"looks right"| Done(["Done"])
Prompt ideas and tips
PromptWhat happens
"Draw a mobile login screen with social buttons"A 390×844 frame with inputs and buttons
"Read the selected frame and describe the design"Colors, typography, spacing from your selection
"Convert my selected frame to Tailwind"Reads the node tree, generates code
"Create a dark dashboard with KPI cards"A full layout with stats and charts
"Take a screenshot of the current frame"An inline image the AI can analyze
  • Name the style (dark, glassmorphism, minimal white) and the platform (mobile 390×844, tablet 768×1024, desktop 1440×900).
  • Iterate: "make the buttons bigger" works on existing nodes — the AI reads before it modifies.
  • Use selection: select a frame, then ask "improve this design".

Updating

bash
npx @hanoilab/figma-bridge-mcp@latest --version   # prints the new version and the plugin path

Restart your client, then re-import manifest.json from the printed path (Plugins → Development → Manage plugins in development). The Figma plugin does not auto-update. Run figma_status and check that pluginVersion matches.


Tools

The server exposes five MCP tools.

ToolPurpose
figma_statusConnection check, active file/page, sessions. Call first.
figma_docsThe full API reference and design rules. Call before drawing.
figma_writeRun JavaScript against the figma.* API to create or change the design.
figma_readExtract design data: trees, tokens, CSS, components, screenshots.
figma_rulesOne markdown rule sheet: color tokens, text styles, variables, components. Call once per session.

Design to code

mermaid
flowchart LR  F["Select a frame<br/>in Figma"] --> A["get_design_context<br/>layout · tokens · typography"]  F --> B["get_css<br/>ready-to-paste CSS"]  F --> C["get_component_map<br/>instances + import paths"]  A --> AI(["AI generates<br/>React · Vue · Swift · Tailwind"])  B --> AI  C --> AI

figma_write — 47 operations

Code runs in a sandbox with the figma object; each call is isolated, so re-query node IDs at the start of every call.

js
const root = await figma.create({  type: "FRAME", name: "Dashboard", width: 1440, height: 900, fill: "#0f172a",});const sidebar = await figma.create({  type: "FRAME", name: "Sidebar", parentId: root.id,  width: 240, height: 900, fill: "#1e293b", stroke: "#334155", strokeWeight: 1,});await figma.create({  type: "TEXT", parentId: sidebar.id, x: 20, y: 24,  content: "My App", fontSize: 16, fontWeight: "SemiBold", fill: "#f8fafc",});
AreaOperations
Nodescreate (FRAME, RECTANGLE, ELLIPSE, LINE, TEXT, SVG, VECTOR, IMAGE) · modify · delete (single or ids: []) · query · append · clone · group / ungroup · flatten · resize · batch (up to 50 ops)
Pages & viewstatus · listPages · setPage · createPage · set_selection · set_viewport
ComponentslistComponents · createComponent · instantiate (with per-layer overrides) · setComponentProperties · swapComponent · addComponentProperty · bindComponentProperty · unbindComponentProperty · removeComponentProperty
Tokens & stylessetupDesignTokens (colors, numbers, fonts, text styles, modes in one idempotent call) · variable collections / modes / values · applyVariable · applyTextStyle · setFrameVariableMode · createPaintStyle · createTextStyle
Images & iconsloadImage(url) · loadIcon(name) · loadIconIn(name) — server-side, with a 7-library icon fallback (Ionicons → Fluent → Bootstrap → Phosphor → Tabler → Lucide)
PrototypingsetReactions / removeReactions (click, hover, press → navigate, overlay, swap; Smart Animate and more) · setScrollBehavior
Styling properties on create / modify
PropertyExample
Solid fill"#6C5CE7", "#6C5CE780" (8-digit hex) or "rgba(108,92,231,0.5)"
Gradient{ type: "LINEAR_GRADIENT", angle: 135, stops: [{ pos: 0, color: "#7C3AED" }, { pos: 1, color: "#EC4899" }] } (also RADIAL_GRADIENT)
CornerscornerRadius: 12 or topLeftRadius / topRightRadius / bottomLeftRadius / bottomRightRadius
Effects[{ type: "DROP_SHADOW", color: "#00000026", offset: {x:0,y:8}, radius: 24 }] — also INNER_SHADOW, LAYER_BLUR, BACKGROUND_BLUR
Vector pathd: "M 150 7 A 143 143 0 1 1 29.26 226.62" — SVG arcs are converted to Béziers
Insert positioninsertIndex: 2 places the node at an exact index in its parent

applyVariable binds FLOAT, COLOR, STRING and BOOLEAN variables to fills, strokes, geometry, corner radii, auto-layout spacing, typography, font family/style, text content and visibility.

figma_read — 19 operations

OperationReturns
get_selection · get_design · get_page_nodesNode trees for the selection, a frame/page, or the top-level frames
get_design_contextAI-optimized payload: flex layout, token-resolved fills as var(--name), typography with style names, component instances
get_component_map · get_unmapped_componentsEvery instance with set name, variant label and suggested import path; instances with no code mapping yet
get_node_detailOne node's properties with variables and styles resolved to names and values, plus a full list of instance overrides
get_cssA ready-to-use CSS string for a node
screenshot · export_image · export_svgInline PNG, base64 PNG/JPG (format, scale), or SVG markup
get_styles · get_variables · get_local_components · get_viewportLocal styles, design tokens (all modes), components, viewport
getReactions · getComponentPropertiesPrototype interactions of a node; variant, boolean, text and instance-swap properties of a component or instance
search_nodes · scan_designFind nodes by type, name, color, font, size; progressive scan of large files

Hidden layers are skipped by default; pass includeHidden: true to get_selection, get_design, search_nodes or scan_design to include them.

Working with an existing design system

Read before you draw, then bind to what exists:

js
const vars = await figma.get_variables();const varMap = {};vars.collections.forEach(c => c.variables.forEach(v => { varMap[v.name] = v.id; }));
const card = await figma.create({  type: "FRAME", name: "Card", width: 360, height: 200,  layoutMode: "VERTICAL", paddingTop: 16, paddingLeft: 16, paddingBottom: 16, paddingRight: 16, itemSpacing: 12,});await figma.applyVariable({ nodeId: card.id, field: "fill", variableId: varMap["bg-surface"] });await figma.applyVariable({ nodeId: card.id, field: "cornerRadius", variableId: varMap["radius-md"] });

Prefer figma.instantiate({ componentId, parentId, overrides }) over redrawing existing components, and pin frames to a mode with setFrameVariableMode to preview Light and Dark side by side. The complete reference is one figma_docs call away.


Security model

The bridge has no login, so access is controlled at the network edge, and figma_write code is treated as having your user's trust level.

mermaid
flowchart LR  R["HTTP request"] --> O{"Origin missing<br/>or 'null'?"}  O -->|no| X1["403 — web page"]  O -->|yes| H{"Host is<br/>loopback?"}  H -->|no| X2["403 — DNS rebinding"]  H -->|yes| A{"Operation on<br/>the allowlist?"}  A -->|no| X3["400"]  A -->|yes| Q["Queued for the plugin"]
LayerProtection
NetworkBinds 127.0.0.1 only. Requests carrying a web-page Origin or a non-loopback Host get 403, so a site you have open cannot drive the bridge.
AllowlistOnly the 66 named operations are accepted, on the MCP path and on /exec.
Sandboxfigma_write runs in a Node vm context that receives no host objects — only strings cross the boundary — and has no require, process, fs or fetch. It is hardened against the known constructor escape, but vm is not a process boundary: do not run code you do not trust.
Outbound fetchloadImage / loadIcon fetch only public http(s) URLs; private, loopback and link-local targets are blocked, including after redirects.
SessionsA pinned sessionId that is not connected is an error, never a silent fallback to another file.
Limits5 MB request body · 30 s sandbox execution · 60–90 s per plugin operation.

Found a vulnerability? See SECURITY.md.


Configuration

VariableDefaultPurpose
FIGMA_MCP_PORT47451Bridge port. If taken, the next 9 ports are tried.
FIGMA_MCP_HOST127.0.0.1Bind address. Changing it exposes an unauthenticated bridge — avoid.
FIGMA_MCP_LONG_POLL_MS8000How long an idle poll is held open.
FIGMA_MCP_ALLOW_PRIVATE_FETCHunsetSet to 1 to let loadImage reach private/loopback hosts (e.g. a local asset server).

Troubleshooting

SymptomFix
Plugin not connectedRun the plugin in Figma Desktop (Plugins → Development → Bridge MCP for Figma). The web app cannot reach localhost.
Tools missing in the AI clientRestart the client fully after editing its MCP config.
Green dot never appearsCheck nothing else holds port 47451, or set FIGMA_MCP_PORT and re-import the plugin.
Every port in 47451–47460 is "in use"Find the owner with netstat -ano | findstr :47451. If it is a leftover process of yours, free the port with npx -y kill-port 47451 (it kills whatever holds the port, so check first), or choose another with FIGMA_MCP_PORT.
Plugin and server versions differRe-import manifest.json after upgrading; the plugin does not auto-update.
Session "…" is not connectedThe targeted Figma file is closed or its plugin stopped. Open it, or omit sessionId to use the active file.
variable is not defined in figma_writeEach call is isolated. Re-query node IDs at the start of every call.
Icon "…" not foundUse Ionicons names in kebab-case (notifications, chevron-back, lock-closed).

Project layout

text
figma-bridge-mcp/├── server/                 npm package: MCP server + bridge│   ├── index.js            MCP entry (stdio) and tool handlers│   ├── bridge-server.js    HTTP bridge: long-poll, sessions, origin gate│   ├── code-executor.js    sandbox for figma_write│   ├── figma-proxy.js      the figma.* API seen by user code│   ├── http-fetch.js       guarded fetch for images and icons│   ├── allowed-ops.js      operation allowlist│   └── docs/               reference served by figma_docs├── src/plugin/             plugin source (plain files, concatenated)├── plugin/                 manifest.json, ui.html, code.js (generated)└── scripts/                build, test runner, regression tests

Development

bash
npm installnpm run build:plugin    # src/plugin/*.js  →  plugin/code.js  (generated — never edit by hand)npm test                # every scripts/test-*.mjs; no live Figma needed

Plugin files share one scope when concatenated; their order lives in scripts/lib/plugin-files.mjs. See CLAUDE.md for the invariants worth knowing before you change anything.

Releasing: bump version in package.json, rename the top CHANGELOG.md heading to ## [x.y.z] — date, push to main. CI runs the tests, publishes to npm, tags the commit, creates a GitHub Release with the plugin zip attached, and updates the MCP Registry.


License

MIT © nguyendinhphongdx. Forked from TranHoaiHung/figma-ui-mcp; the original copyright notice is preserved in LICENSE.

來源:README.md,提交 8212237

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

1
  1. v2.6.1最新Nov 11, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分

其他 Figma 整合