figma-bridge-mcp について
figma-bridge-mcpは、AIクライアントをFigma Desktopで開いているドキュメントに接続するローカルMCPサーバーです。JavaScriptによるキャンバス編集に加え、デザインデータ、トークン、CSS、コンポーネント、スクリーンショットを読み取れます。
主な機能
- 01キャンバスデザインの作成と変更
- 02ノードツリーとデザイントークンの読み取り
- 03CSSとコンポーネントマップの抽出
- 04スクリーンショット撮影と画像のエクスポート
- 05複数のFigmaセッションに対応
- 06localhost上でのローカル実行
活用シーン
- 01FigmaキャンバスでのUIレイアウト生成
- 02選択したデザインの実装向け確認
- 03フレーム情報からCSSを作成
- 04スクリーンショットを確認してデザインを反復
MCP 対応
接続状態、APIとデザインのガイド、JavaScriptによる書き込み、デザインの読み取り、ルール取得の5つのツールをMCPクライアントに提供します。Figma Desktopプラグインとローカルブリッジを介して接続します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
AI が Figma キャンバスに描画し、デザインをコードとして読み取れるようにします。
Figma Desktop 向けの双方向 Model Context Protocol ブリッジです。
Figma API キーは不要です。クラウドも不要です。すべて localhost 上で動作します。
Figma, Inc. とは提携、推奨、スポンサー関係にありません。 「Figma」は Figma, Inc. の商標であり、ここでは互換性を説明する目的でのみ使用しています。
概要
figma-bridge-mcp は、AI アシスタントを Figma Desktop で開いているドキュメントに接続します。
| ✍️ 書き込み | AI が figma.* API に対して JavaScript を実行し、フレーム、テキスト、ベクター、コンポーネント、変数、プロトタイプを作成します。 |
| 👀 読み取り | AI がノードツリー、解決済みデザイントークン、CSS、コンポーネントマップ、スクリーンショットを抽出します。デザインからコードへの変換にすぐ使えます。 |
| 🔒 ローカル | ブリッジは 127.0.0.1 のみで待ち受けます。データがマシンの外に出ることはありません。 |
| 🧩 あらゆる MCP クライアント | ✅ Claude Code と Antigravity でテスト済みです。🔧 Cursor、VS Code、Windsurf、Zed、およびあらゆる stdio MCP クライアントと互換性があります。 |
Figma Desktop が必要です。 プラグインは
localhost経由でサーバーと通信しますが、Figma のウェブアプリではこれが許可されていません。
仕組み
AI クライアント、MCP サーバー(Node)、Figma プラグイン(Figma Desktop 内)の 3 つが連携します。プラグインがサーバーをポーリングするため、Figma へのインバウンド接続は必要ありません。
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
1 回の往復処理
サーバーは各ポーリングを最大 8 秒間保留し、処理がキューに入るとすぐに応答するため、通常のレイテンシは 100 ms 未満です。
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
複数の Figma ファイルを同時に扱う
開いているプラグインの各インスタンスは、それぞれ独自のセッションを登録します。特定のファイルを対象にするには、任意の sessionId を figma_write / figma_read に渡します。そのセッションが接続されていない場合、別のファイルに書き込む代わりに呼び出しが失敗します。
クイックスタート
1 · クライアントに MCP サーバーを追加する
Claude Code
claude mcp add figma-bridge-mcp -- npx @hanoilab/figma-bridge-mcp # this project
claude mcp add --scope user figma-bridge-mcp -- npx @hanoilab/figma-bridge-mcp # all projects
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json(macOS)または %APPDATA%\Claude\claude_desktop_config.json(Windows)を編集します。
{
"mcpServers": {
"figma": { "command": "npx", "args": ["-y", "@hanoilab/figma-bridge-mcp"] }
}
}
Cursor
.cursor/mcp.json(プロジェクト)または ~/.cursor/mcp.json(グローバル)を編集し、Claude Desktop 用に示されているのと同じ mcpServers ブロックを追加します。
VS Code / GitHub Copilot
.vscode/mcp.json を編集するか、settings.json に追加します。
{
"mcp": {
"servers": {
"figma": { "command": "npx", "args": ["-y", "@hanoilab/figma-bridge-mcp"] }
}
}
}
Windsurf
~/.codeium/windsurf/mcp_config.json を編集し、Claude Desktop 用に示されているのと同じ mcpServers ブロックを追加します。
Antigravity(Google)
エージェントパネルの 「…」メニュー → Manage MCP Servers → View raw config を開き、同じ mcpServers ブロックを mcp_config.json に追加します。
ソースから実行
git clone https://github.com/nguyendinhphongdx/figma-bridge-mcp
cd figma-bridge-mcp && npm install
# point your MCP client at: node /path/to/figma-bridge-mcp/server/index.js
設定を編集した後、クライアントを再起動してください。 MCP サーバーは起動時にのみ読み込まれます。
2 · Figma プラグインをインストールする
- **⬇ プラグインをダウンロード**し、任意の場所に解凍します。
- Figma Desktopで、*プラグイン → 開発 → マニフェストからプラグインをインポート…*を選び、
manifest.jsonを指定します。 - プラグイン → 開発 → Bridge MCP for Figmaを実行します。
サーバーに接続すると、プラグインのウィンドウに緑色の点が表示されます。
3 · 接続してデザインする
アシスタントに次のように伝えます。
「figma-bridge-mcp に接続して」
figma_statusを呼び出し、ファイル、ページ、プラグインのバージョンを確認します。その後、作成したいものを説明します。
「Apple と Google のサインインボタンがあるモバイルのログイン画面を描いて」
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"])
プロンプトのアイデアとヒント
| プロンプト | 実行される内容 |
|---|---|
| 「ソーシャルボタンのあるモバイルのログイン画面を描いて」 | 入力欄とボタンを備えた390×844のフレーム |
| 「選択したフレームを読み取って、デザインを説明して」 | 選択範囲の色、タイポグラフィ、間隔 |
| 「選択したフレームをTailwindに変換して」 | ノードツリーを読み取り、コードを生成 |
| 「KPIカードのあるダークなダッシュボードを作成して」 | 統計情報とチャートを含む全体レイアウト |
| 「現在のフレームのスクリーンショットを撮って」 | AI が分析できるインライン画像 |
- スタイル(
dark、glassmorphism、minimal white)とプラットフォーム(mobile390×844、tablet768×1024、desktop1440×900)を指定します。 - 繰り返し調整する:「ボタンを大きくして」は既存のノードに適用されます。AI は変更前に内容を読み取ります。
- 選択範囲を使う:フレームを選択してから、「このデザインを改善して」と依頼します。
更新
npx @hanoilab/figma-bridge-mcp@latest --version # prints the new version and the plugin path
クライアントを再起動し、表示されたパスからmanifest.jsonを再インポートします(プラグイン → 開発 → 開発中のプラグインを管理)。Figma プラグインは自動更新されません。figma_statusを実行し、pluginVersionが一致していることを確認します。
ツール
サーバーは5つの MCP ツールを公開しています。
| ツール | 目的 |
|---|---|
figma_status | 接続状況、アクティブなファイル/ページ、セッションを確認します。最初に呼び出してください。 |
figma_docs | API リファレンス全体とデザインルールを参照します。描画する前に呼び出してください。 |
figma_write | figma.* API に対して JavaScript を実行し、デザインを作成または変更します。 |
figma_read | ツリー、トークン、CSS、コンポーネント、スクリーンショットなどのデザインデータを抽出します。 |
figma_rules | 色トークン、テキストスタイル、変数、コンポーネントをまとめた1つの Markdown ルールシートを取得します。セッションごとに1回呼び出してください。 |
デザインからコードへ
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 個の操作
コードは figma オブジェクトを使用するサンドボックス内で実行されます。呼び出しはそれぞれ独立しているため、各呼び出しの開始時にノード ID を再取得してください。
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",
});
| 領域 | 操作 |
|---|---|
| ノード | create(FRAME、RECTANGLE、ELLIPSE、LINE、TEXT、SVG、VECTOR、IMAGE) · modify · delete(単一または ids: []) · query · append · clone · group / ungroup · flatten · resize · batch(最大 50 件の操作) |
| ページと表示 | status · listPages · setPage · createPage · set_selection · set_viewport |
| コンポーネント | listComponents · createComponent · instantiate(レイヤーごとの overrides に対応) · setComponentProperties · swapComponent · addComponentProperty · bindComponentProperty · unbindComponentProperty · removeComponentProperty |
| トークンとスタイル | setupDesignTokens(色、数値、フォント、テキストスタイル、モードを 1 回の冪等な呼び出しで設定) · 変数コレクション / モード / 値 · applyVariable · applyTextStyle · setFrameVariableMode · createPaintStyle · createTextStyle |
| 画像とアイコン | loadImage(url) · loadIcon(name) · loadIconIn(name) — サーバー側で実行され、7 つのアイコンライブラリへのフォールバックに対応(Ionicons → Fluent → Bootstrap → Phosphor → Tabler → Lucide) |
| プロトタイピング | setReactions / removeReactions(クリック、ホバー、押下 → 移動、オーバーレイ、入れ替え。Smart Animate などにも対応) · setScrollBehavior |
create / modify のスタイル設定プロパティ
| プロパティ | 例 |
|---|---|
| 単色塗りつぶし | "#6C5CE7"、"#6C5CE780"(8 桁の 16 進数)、または "rgba(108,92,231,0.5)" |
| グラデーション | { type: "LINEAR_GRADIENT", angle: 135, stops: [{ pos: 0, color: "#7C3AED" }, { pos: 1, color: "#EC4899" }] }(RADIAL_GRADIENT にも対応) |
| 角 | cornerRadius: 12 または topLeftRadius / topRightRadius / bottomLeftRadius / bottomRightRadius |
| エフェクト | [{ type: "DROP_SHADOW", color: "#00000026", offset: {x:0,y:8}, radius: 24 }] — INNER_SHADOW、LAYER_BLUR、BACKGROUND_BLUR にも対応 |
| ベクターパス | d: "M 150 7 A 143 143 0 1 1 29.26 226.62" — SVG の円弧はベジェ曲線に変換されます |
| 挿入位置 | insertIndex: 2 を指定すると、親要素内の正確なインデックスにノードが配置されます |
applyVariable は、FLOAT、COLOR、STRING、BOOLEAN の各変数を、塗りつぶし、線、ジオメトリ、角の半径、自動レイアウトの間隔、タイポグラフィ、フォントファミリー / スタイル、テキストコンテンツ、表示状態にバインドします。
| 操作 | 戻り値 |
|---|---|
get_selection · get_design · get_page_nodes | 選択範囲、フレーム/ページ、または最上位のフレームのノードツリー |
get_design_context | AI 向けに最適化されたペイロード:フレックスレイアウト、トークンを解決した塗りつぶし(var(--name))、スタイル名付きのタイポグラフィ、コンポーネントインスタンス |
get_component_map · get_unmapped_components | セット名、バリアントラベル、推奨インポートパスを含むすべてのインスタンス、およびコードとのマッピングがまだないインスタンス |
get_node_detail | 変数とスタイルを名前と値に解決した単一ノードのプロパティと、インスタンスのオーバーライドの全一覧 |
get_css | ノード用のすぐに使える CSS 文字列 |
screenshot · export_image · export_svg | インライン PNG、base64 PNG/JPG(format、scale)、または SVG マークアップ |
get_styles · get_variables · get_local_components · get_viewport | ローカルスタイル、デザイントークン(すべてのモード)、コンポーネント、ビューポート |
getReactions · getComponentProperties | ノードのプロトタイプインタラクション、およびコンポーネントまたはインスタンスのバリアント、ブール値、テキスト、インスタンス差し替えプロパティ |
search_nodes · scan_design | タイプ、名前、色、フォント、サイズでノードを検索し、大きなファイルを段階的にスキャン |
デフォルトでは非表示レイヤーはスキップされます。includeHidden: true を get_selection、get_design、search_nodes、または scan_design に渡すと、非表示レイヤーも含められます。
既存のデザインシステムを使用する
描画する前に読み込み、既存のものに結び付けます。
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"] });
既存のコンポーネントを描き直すより、figma.instantiate({ componentId, parentId, overrides }) を使用してください。また、setFrameVariableMode でフレームをモードに固定すると、ライトとダークを並べてプレビューできます。完全なリファレンスは figma_docs を 1 回呼び出すだけで確認できます。
セキュリティモデル
このブリッジにはログイン機能がないため、アクセスはネットワーク境界で制御されます。また、figma_write のコードはユーザーと同じ信頼レベルで扱われます。
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"]
| レイヤー | 保護 |
|---|---|
| ネットワーク | 127.0.0.1 のみをバインドします。ウェブページの Origin またはループバック以外の Host を含むリクエストには 403 を返すため、開いているサイトからブリッジを操作することはできません。 |
| 許可リスト | MCP パスと /exec では、名前付きの 66 個の操作のみが許可されます。 |
| サンドボックス | figma_write は、ホストオブジェクトを一切受け取らない Node vm コンテキストで実行されます。境界を越えるのは文字列のみで、require、process、fs、fetch は使用できません。既知のコンストラクターエスケープに対して強化されていますが、vm はプロセス境界ではありません。信頼できないコードは実行しないでください。 |
| 外部へのフェッチ | loadImage/loadIcon がフェッチできるのは、公開された http(s) URL のみです。プライベート、ループバック、リンクローカルの宛先は、リダイレクト後も含めてブロックされます。 |
| セッション | 接続されていない固定の sessionId はエラーとなり、別のファイルへのサイレントフォールバックは行われません。 |
| 制限 | リクエスト本文 5 MB · サンドボックス実行 30 秒 · プラグイン操作ごとに 60~90 秒。 |
脆弱性を発見しましたか?SECURITY.md をご覧ください。
設定
| 変数 | デフォルト | 用途 |
|---|---|---|
FIGMA_MCP_PORT | 47451 | ブリッジのポートです。使用中の場合は、次の 9 個のポートを試します。 |
FIGMA_MCP_HOST | 127.0.0.1 | バインドアドレスです。変更すると認証のないブリッジが公開されるため、変更しないでください。 |
FIGMA_MCP_LONG_POLL_MS | 8000 | アイドル状態のポーリングを開いたままにする時間です。 |
FIGMA_MCP_ALLOW_PRIVATE_FETCH | unset | 1 に設定すると、loadImage がプライベート/ループバックホスト(ローカルのアセットサーバーなど)にアクセスできるようになります。 |
トラブルシューティング
| 症状 | 対処方法 |
|---|---|
Plugin not connected | Figma Desktop でプラグインを実行してください(Plugins → Development → Bridge MCP for Figma)。ウェブアプリからは localhost に接続できません。 |
| AI クライアントにツールが表示されない | MCP の設定を編集した後、クライアントを完全に再起動してください。 |
| 緑色の点が表示されない | ポート 47451 をほかのプロセスが使用していないか確認するか、FIGMA_MCP_PORT を設定してプラグインを再インポートしてください。 |
47451–47460 のすべてのポートが「使用中」になっている | netstat -ano | findstr :47451 で使用しているプロセスを確認します。それが自分の残留プロセスであれば、npx -y kill-port 47451 でポートを解放してください(ポートを使用しているプロセスを終了するため、事前に確認してください)。または、FIGMA_MCP_PORT で別のポートを選択してください。 |
| プラグインとサーバーのバージョンが異なる | アップグレード後に manifest.json を再インポートしてください。プラグインは自動更新されません。 |
Session "…" is not connected | 対象の Figma ファイルが閉じているか、そのプラグインが停止しています。ファイルを開くか、sessionId を省略してアクティブなファイルを使用してください。 |
figma_write で variable is not defined が表示される | 各呼び出しは独立しています。呼び出しごとに、最初にノード ID を再取得してください。 |
Icon "…" not found | Ionicons の名前をケバブケースで指定してください(notifications、chevron-back、lock-closed)。 |
プロジェクトの構成
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
開発
npm install
npm run build:plugin # src/plugin/*.js → plugin/code.js (generated — never edit by hand)
npm test # every scripts/test-*.mjs; no live Figma needed
プラグインのファイルは連結されると同じスコープを共有します。ファイルの順序は scripts/lib/plugin-files.mjs で管理されています。変更前に把握しておくべき不変条件については、CLAUDE.md を参照してください。
リリース: package.json の version を更新し、最上部の CHANGELOG.md の見出しを ## [x.y.z] — date に変更して、main にプッシュしてください。CI がテストを実行し、npm に公開し、コミットにタグを付け、プラグインの zip を添付した GitHub Release を作成して、MCP Registry を更新します。
ライセンス
MIT © nguyendinhphongdx。TranHoaiHung/figma-ui-mcp からフォークされています。元の著作権表示は LICENSE に保持されています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。