figma-rust-mcp 3.2.9 → 3.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,404 +1,410 @@
1
- # figma-mcp (figma-rust-mcp)
2
-
3
- High-performance, bidirectional Model Context Protocol (MCP) server written in **Rust** connecting AI coding assistants directly to **Figma Desktop**.
4
-
5
- Enables AI agents (Google Antigravity, Claude Code, Cursor, Windsurf, VS Code, Zed) to **compile Figma designs into production code**, **extract design tokens**, **draw UI directly on canvas**, and **inspect hierarchy, styles, and assets** — with zero external API keys needed.
6
-
7
- ---
8
-
9
- ## ⚡ Highlights
10
-
11
- - **Lossless Rust Tree Compression**: Compact/minimal tree responses share identical style bundles when the complete JSON becomes smaller. Node IDs, hierarchy, text, geometry and state differences remain intact. Full detail bypasses Rust compression; no heuristic merging of screens or repeated items.
12
- - **Pure Rust Native Performance**: Starts in `< 1ms`, uses `~3MB RAM`, zero GC pauses.
13
- - **In-Memory Deep Indexing (`figma_index`)**: Queries layers, components, styles, and tokens in `< 1ms` without slow canvas roundtrips.
14
- - **Binary IPC & Chunk Streaming**: Powered by **MessagePack** (`rmp-serde`) and progressive subtree chunking for instant transfers of massive design files.
15
- - **Incremental Diff Updates**: Sub-millisecond live document sync (`upsert_node`) keeps the server index fresh as you edit in Figma.
16
- - **Instant Design-to-Code (`figma_to_code`)**: Compiles Figma frames into clean, semantic components (**React + Tailwind**, **React Native**, **Vue 3 + Tailwind**, **HTML**, **SwiftUI**).
17
- - **Design Token Exporter (`figma_get_tokens`)**: Exports variables and styles to **Tailwind config**, **CSS custom properties** (`:root` & dark mode), **TypeScript consts**, or **W3C DTCG Token Studio JSON**.
18
- - **Batch Asset Extractor (`figma_export_assets` / `figma_export_asset`)**: Extracts SVG icons and raster images directly to project folders (`outputPath`) with auto-generated TypeScript barrel exports (`index.ts`) — zero chat token bloating.
19
- - **Sandboxed JS Drawing Engine (`figma_write`)**: Powered by **Boa** (pure Rust ECMAScript engine) with built-in asset resolvers and 7 icon packs (*Ionicons, Lucide, Tabler, Bootstrap, Fluent, Phosphor*).
20
- - **Multi-Tab / Multi-Session Support**: Seamlessly connects to multiple open Figma files simultaneously.
21
- - **100% Localhost Privacy**: All communication stays strictly on `127.0.0.1:38451`.
22
-
23
- ---
24
-
25
- ## 🏛️ Architecture & Zero-Touch Connection
26
-
27
- ```text
28
- ┌────────────────────────────────────────────────────────────────────────┐
29
- │ Terminal / Background Service │
30
- │ figma-mcp (Pure Rust Engine) │
31
- │ • MCP Streamable HTTP (/mcp) & legacy SSE (/sse, /message) │
32
- │ • Dynamic Runtime Server (/plugin/code.js, /plugin/ui.html) │
33
- │ • In-Memory Fast Index (<1ms Lookups & Incremental Diffs) │
34
- │ • Design-to-Code Compiler (React/Tailwind, Vue, RN, SwiftUI) │
35
- │ • Design Token Transformer (CSS, Tailwind, TypeScript, W3C DTCG) │
36
- │ • Sandboxed JS Runtime (Boa ECMAScript Engine) │
37
- │ • Binary MessagePack & Progressive Subtree Chunk Receiver │
38
- └───────────────▲────────────────────────────────────────▲───────────────┘
39
- │ (ws://127.0.0.1:38451/ws) │ (http://127.0.0.1:38451/mcp)
40
- │ (Dynamic Code Streaming & Hot-Reload) │ (JSON-RPC 2.0 / Streamable HTTP)
41
- ┌─────────┴─────────┐ ┌─────────┴─────────┐
42
- │ Figma Desktop │ │ AI Assistant(s) │
43
- │ (Thin Loader) │ │ Google Antigravity│
44
- │ │ │ Cursor / Windsurf │
45
- │ • Zero-Touch Sync │ │ Claude Code / Zed │
46
- │ • Live Hot-Reload │ └───────────────────┘
47
- │ • SVG/PNG Render │
48
- └───────────────────┘
49
- ```
50
-
51
- ### 🔌 How the Zero-Touch Connection Works:
52
- 1. **Permanent Thin Loader**: You only import the Figma plugin **once** (`~/.figma-mcp/plugin/manifest.json`).
53
- 2. **Dynamic Runtime Streaming**: Upon launch, the Thin Loader contacts `http://127.0.0.1:38451/plugin/code.js` to fetch and execute the latest runtime in memory.
54
- 3. **Live WebSocket Hot-Reload**: The plugin connects to `ws://127.0.0.1:38451/ws`. When you upgrade `figma-rust-mcp` or restart the daemon, the plugin automatically detects the new server version and hot-reloads seamlessly — **no need to re-import or restart the plugin in Figma**.
55
- 4. **Auto-Reconnect & Offline Buffer**: If Figma is opened before the Rust service starts, the plugin displays a waiting screen and connects automatically the instant the service is up.
56
-
57
- ---
58
-
59
- ## 🚀 Quick Start
60
-
61
- ### 1. One-Line Setup & Launch with NPX (No Rust toolchain needed)
62
-
63
- ```bash
64
- # Launch interactive MCP server
65
- npx -y figma-rust-mcp@latest
66
- ```
67
- *(Automatically downloads precompiled native binary for macOS Apple Silicon/Intel, Linux, or Windows).*
68
-
69
- ---
70
-
71
- ### 2. Install the Figma Plugin (Permanent One-Time Setup)
72
-
73
- Create the permanent Thin Loader folder in your home directory:
74
-
75
- ```bash
76
- npx -y figma-rust-mcp@latest --setup-plugin
77
- ```
78
-
79
- 1. Open **Figma Desktop**.
80
- 2. Go to **Plugins** → **Development** → **Import plugin from manifest...**
81
- 3. Select `~/.figma-mcp/plugin/manifest.json` (or `plugin/manifest.json` inside this repository).
82
- 4. Run the plugin: **Plugins** → **Development** → **Figma MCP Bridge**.
83
- 5. **Done!** Future updates to `figma-rust-mcp` will stream to Figma automatically.
84
-
85
- ---
86
-
87
- ### 3. Run as Auto-Start Background Service (Recommended)
88
-
89
- Run `figma-rust-mcp` seamlessly in the background across all your AI editors without keeping a terminal open:
90
-
91
- ```bash
92
- # Install and start background service (macOS LaunchAgent, Linux systemd, Windows Task)
93
- npx -y figma-rust-mcp@latest --install-service
94
-
95
- # Check live background service status & bridge health
96
- npx -y figma-rust-mcp@latest --service-status
97
-
98
- # One-command upgrade to latest version & auto-restart background service
99
- npx -y figma-rust-mcp@latest --upgrade
100
-
101
- # Add convenient 'figma-mcp' alias to your shell profile (~/.zshrc, ~/.bashrc)
102
- npx -y figma-rust-mcp@latest --alias
103
-
104
- # Stop and remove background service
105
- npx -y figma-rust-mcp@latest --uninstall-service
106
- ```
107
-
108
- ---
109
-
110
- ### Windows background mode
111
-
112
- Double-clicking `figma-mcp.exe` starts the server in a detached process and closes
113
- its launcher console. From PowerShell or Command Prompt, use:
114
-
115
- ```powershell
116
- .\figma-mcp.exe --background
117
- ```
118
-
119
- The server keeps running after the terminal closes. Logs are appended to
120
- `%LOCALAPPDATA%\figma-mcp\logs\server.log`. Use `--server` for the foreground
121
- terminal dashboard, or `--stdio` for an MCP client subprocess.
122
-
123
- `--install-service` through the npm runner configures background startup at login.
124
- Re-run the installation command to update an existing Windows task. Removing the
125
- task disables future login startup; stop an already detached server through Task
126
- Manager (`figma-mcp.exe`). The launcher console may appear briefly when opening
127
- the executable; the server itself does not retain a console window.
128
-
129
- ### 4. Build from Source (Optional)
130
-
131
- If you prefer building directly with the [Rust toolchain](https://rustup.rs/) (`cargo >= 1.80`):
132
-
133
- ```bash
134
- git clone https://github.com/BuiHung1612/figma-mcp.git
135
- cd figma-mcp
136
- cargo build --release
137
- ./target/release/figma-mcp
138
- ```
139
-
140
- ---
141
-
142
- ### 5. Configure Your MCP Client
143
-
144
- #### Codex and clients using Streamable HTTP (Recommended)
145
-
146
- Use the `/mcp` endpoint. It accepts `POST` JSON-RPC requests directly:
147
-
148
- ```toml
149
- [mcp_servers.figma-mcp]
150
- url = "http://127.0.0.1:38451/mcp"
151
- ```
152
-
153
- For Codex CLI, the equivalent command is:
154
-
155
- ```bash
156
- codex mcp add figma-mcp --url http://127.0.0.1:38451/mcp
157
- ```
158
-
159
- #### Google Antigravity (SSE Transport)
160
- Add to your `~/.gemini/config/mcp_config.json` or project `.agents/mcp_config.json`:
161
- ```json
162
- {
163
- "mcpServers": {
164
- "figma-mcp": {
165
- "serverUrl": "http://127.0.0.1:38451/sse"
166
- }
167
- }
168
- }
169
- ```
170
-
171
- #### Claude Code / Cursor / Windsurf / VS Code / Zed
172
-
173
- **Option A: SSE Transport (for clients that require SSE)**
174
- ```json
175
- {
176
- "mcpServers": {
177
- "figma-mcp": {
178
- "url": "http://127.0.0.1:38451/sse"
179
- }
180
- }
181
- }
182
- ```
183
-
184
- The SSE transport uses `GET /sse` to open the event stream and `POST /message`
185
- (or `/messages`) for JSON-RPC messages. Do not configure a Streamable HTTP
186
- client such as Codex against `/sse`: that endpoint does not accept `POST`, so
187
- the initialize request will return HTTP 405. Use `/mcp` instead.
188
-
189
- **Option B: Stdio Subprocess (via NPX)**
190
- ```json
191
- {
192
- "mcpServers": {
193
- "figma-rust-mcp": {
194
- "command": "npx",
195
- "args": ["-y", "figma-rust-mcp", "--stdio"]
196
- }
197
- }
198
- }
199
- ```
200
-
201
- ### 6. Diagnose a stale Figma runtime
202
-
203
- Check the runtime bundle currently served to Figma Desktop:
204
-
205
- ```bash
206
- curl http://127.0.0.1:38451/plugin/version
207
- ```
208
-
209
- The response includes `version` and `runtimeHash`. If the hash changes after an
210
- upgrade, the dynamic plugin runtime is refreshed automatically. Restart the
211
- Figma plugin only if the reported hash does not change.
212
-
213
- ---
214
-
215
- ## 🛠️ MCP Tools Reference
216
-
217
- `figma-mcp` provides **15 first-class MCP tools**:
218
-
219
- ### 1. `figma_status`
220
- Checks live bridge connection status, connected Figma tabs/files, in-memory index health, queue length, and latency statistics.
221
-
222
- ### 2. `figma_inspect_node`
223
- Inspects a specific node by ID or name, returning CSS styles, flex layout rules, tokens, typography, and fills in a clean format (served in `< 1ms` via in-memory index or direct bridge).
224
-
225
- ### 3. `figma_to_code`
226
- Compiles any Figma node (Frame, Component, Section, or selection) directly into clean, production-ready component code.
227
- - **`framework`**: `"react-tailwind"` (default), `"react-native"`, `"vue-tailwind"`, `"html"`, `"swiftui"`.
228
- - **`outputPath`**: Directly saves the generated component to your codebase (e.g. `src/components/UserProfileCard.tsx`).
229
- - **`componentName`**: Custom component name override.
230
-
231
- ### 4. `figma_get_tokens`
232
- Exports Figma Variables (Design Tokens), Color Styles, Typography Styles, and Elevation/Shadow Styles directly into frontend code.
233
- - **`format`**: `"tailwind"` (`tailwind.config.js` theme.extend), `"css"` (`:root` CSS custom properties with light/dark theme modes), `"typescript"` (`tokens.ts`), `"w3c"` (W3C DTCG Token Studio JSON), or `"json"`.
234
- - **`outputPath`**: Writes directly to disk (e.g. `src/styles/tokens.css` or `tailwind.config.js`).
235
- - **`collection`** / **`mode`** / **`prefix`**: Optional filters and naming prefixes.
236
-
237
- Token exports use schema v2 and preserve full paint/effect stacks, alpha, gradient
238
- transforms, collection modes and raw alias values. CSS, Tailwind, TypeScript and
239
- JSON share one normalized model. The `w3c` output uses DTCG 2025.10 color,
240
- dimension, gradient-stop and shadow values, with Figma-specific geometry and
241
- unsupported values retained in `$extensions`.
242
-
243
- Linear gradients on a node are projected using its actual dimensions. A diagonal
244
- gradient style has no target aspect ratio: use `get_css` on its consuming node.
245
- Radial/angular/diamond paints, unsupported blend modes and progressive blurs
246
- retain their raw data and report diagnostics recommending SVG instead of emitting
247
- approximate CSS. Unknown modes, unresolved aliases and sanitized name collisions
248
- fail explicitly. CSS exports include non-default modes under `data-theme`
249
- selectors; opacity/font-weight variables stay unitless.
250
-
251
- The plugin UI badge is stamped from the build version and updated from the
252
- connected server handshake. Package/Cargo/tag mismatches fail the build pipeline.
253
- Run `npm run build:plugin` after changing plugin source, and `npm run test:tokens`
254
- for the token/contract/version regression suite. Existing background servers need
255
- a restart with the new binary to load the updated runtime.
256
-
257
-
258
- ### 5. `figma_get_selection`
259
- Inspection of currently selected layers/frames, with shared-style compression when it reduces response size.
260
- - **`detail`**: `"compact"` (default), `"minimal"`, `"full"`.
261
-
262
- Compact/minimal `get_selection` and `get_design` responses may contain a root
263
- `_compression` object with `version: 1` and a `styles` dictionary. For each node
264
- with `styleRef`, merge `_compression.styles[node.styleRef]` into that node and
265
- remove `styleRef`; remove root `_compression` to reconstruct the plugin payload
266
- exactly. Style references are dictionary lookups, not inherited CSS. Payloads
267
- with reserved-field collisions or no net byte savings stay inline. `detail: "full"` bypasses this Rust transformation and queries the plugin rather than a
268
- compact selection cache. Plugin detail, visibility, precision, depth and node
269
- budgets still determine the source payload; compression cannot restore fields
270
- omitted there. Code generation continues to consume inline styles.
271
-
272
- No token-reduction or AI-latency percentage is claimed without a tokenizer and
273
- end-to-end benchmark on real designs.
274
- - **`depth`**: Tree depth limit or `"full"`.
275
-
276
- ### 6. `figma_export_asset`
277
- Exports any Figma node/layer directly into PNG, JPG, or SVG.
278
- - **`outputPath`**: When specified (e.g. `src/assets/logo.png`), saves directly to disk and returns minimal JSON metadata instead of bloating context with large base64 strings.
279
- - **`format`**: `"png"` (default), `"jpg"`, `"svg"`.
280
- - **`scale`**: Scaling factor (default `2` for high-res).
281
-
282
- ### 7. `figma_export_assets`
283
- Batch extracts all SVG icons and PNG images from a Figma frame/page directly into project directories.
284
- - **`iconDir`**: Directory path for SVG icons (e.g. `src/assets/icons`).
285
- - **`imageDir`**: Directory path for raster images (e.g. `public/images`).
286
- - **`createBarrel`**: Automatically creates an `index.ts` barrel export file in `iconDir`.
287
-
288
- ### 8. `figma_index`
289
- Instant `< 1ms` in-memory queries against pre-indexed Figma file structures.
290
- - **`operation`**:
291
- - `"status"`: View index health and node counts.
292
- - `"search_nodes"`: Search nodes by text name, query, and type (`FRAME`, `TEXT`, `COMPONENT`, `INSTANCE`).
293
- - `"get_node"`: Instant node lookup by ID.
294
- - `"search_components"`: Find component sets and variants.
295
- - `"search_styles"`: Find paint, text, and effect styles.
296
- - `"search_variables"`: Find design token variables by name or collection.
1
+ # figma-mcp (figma-rust-mcp)
2
+
3
+ High-performance, bidirectional Model Context Protocol (MCP) server written in **Rust** connecting AI coding assistants directly to **Figma Desktop**.
4
+
5
+ Enables AI agents (Google Antigravity, Claude Code, Cursor, Windsurf, VS Code, Zed) to **compile Figma designs into production code**, **extract design tokens**, **draw UI directly on canvas**, and **inspect hierarchy, styles, and assets** — with zero external API keys needed.
6
+
7
+ ---
8
+
9
+ ## ⚡ Highlights
10
+
11
+ - **Lossless Rust Tree Compression**: Compact/minimal tree responses share identical style bundles when the complete JSON becomes smaller. Node IDs, hierarchy, text, geometry and state differences remain intact. Full detail bypasses Rust compression; no heuristic merging of screens or repeated items.
12
+ - **Pure Rust Native Performance**: Starts in `< 1ms`, uses `~3MB RAM`, zero GC pauses.
13
+ - **In-Memory Deep Indexing (`figma_index`)**: Queries layers, components, styles, and tokens in `< 1ms` without slow canvas roundtrips.
14
+ - **Binary IPC & Chunk Streaming**: Powered by **MessagePack** (`rmp-serde`) and progressive subtree chunking for instant transfers of massive design files.
15
+ - **Incremental Diff Updates**: Sub-millisecond live document sync (`upsert_node`) keeps the server index fresh as you edit in Figma.
16
+ - **Instant Design-to-Code (`figma_to_code`)**: Compiles Figma frames into clean, semantic components (**React + Tailwind**, **React Native**, **Vue 3 + Tailwind**, **HTML**, **SwiftUI**).
17
+ - **Design Token Exporter (`figma_get_tokens`)**: Exports variables and styles to **Tailwind config**, **CSS custom properties** (`:root` & dark mode), **TypeScript consts**, or **W3C DTCG Token Studio JSON**.
18
+ - **Batch Asset Extractor (`figma_export_assets` / `figma_export_asset`)**: Extracts SVG icons and raster images directly to project folders (`outputPath`) with auto-generated TypeScript barrel exports (`index.ts`) — zero chat token bloating.
19
+ - **Sandboxed JS Drawing Engine (`figma_write`)**: Powered by **Boa** (pure Rust ECMAScript engine) with built-in asset resolvers and 7 icon packs (*Ionicons, Lucide, Tabler, Bootstrap, Fluent, Phosphor*).
20
+ - **Multi-Tab / Multi-Session Support**: Seamlessly connects to multiple open Figma files simultaneously.
21
+ - **100% Localhost Privacy**: All communication stays strictly on `127.0.0.1:38451`.
22
+
23
+ ---
24
+
25
+ ## 🏛️ Architecture & Zero-Touch Connection
26
+
27
+ ```text
28
+ ┌────────────────────────────────────────────────────────────────────────┐
29
+ │ Terminal / Background Service │
30
+ │ figma-mcp (Pure Rust Engine) │
31
+ │ • MCP Streamable HTTP (/mcp) & legacy SSE (/sse, /message) │
32
+ │ • Dynamic Runtime Server (/plugin/code.js, /plugin/ui.html) │
33
+ │ • In-Memory Fast Index (<1ms Lookups & Incremental Diffs) │
34
+ │ • Design-to-Code Compiler (React/Tailwind, Vue, RN, SwiftUI) │
35
+ │ • Design Token Transformer (CSS, Tailwind, TypeScript, W3C DTCG) │
36
+ │ • Sandboxed JS Runtime (Boa ECMAScript Engine) │
37
+ │ • Binary MessagePack & Progressive Subtree Chunk Receiver │
38
+ └───────────────▲────────────────────────────────────────▲───────────────┘
39
+ │ (ws://127.0.0.1:38451/ws) │ (http://127.0.0.1:38451/mcp)
40
+ │ (Dynamic Code Streaming & Hot-Reload) │ (JSON-RPC 2.0 / Streamable HTTP)
41
+ ┌─────────┴─────────┐ ┌─────────┴─────────┐
42
+ │ Figma Desktop │ │ AI Assistant(s) │
43
+ │ (Thin Loader) │ │ Google Antigravity│
44
+ │ │ │ Cursor / Windsurf │
45
+ │ • Zero-Touch Sync │ │ Claude Code / Zed │
46
+ │ • Live Hot-Reload │ └───────────────────┘
47
+ │ • SVG/PNG Render │
48
+ └───────────────────┘
49
+ ```
50
+
51
+ ### 🔌 How the Zero-Touch Connection Works:
52
+ 1. **Permanent Thin Loader**: You only import the Figma plugin **once** (`~/.figma-mcp/plugin/manifest.json`).
53
+ 2. **Dynamic Runtime Streaming**: Upon launch, the Thin Loader contacts `http://127.0.0.1:38451/plugin/code.js` to fetch and execute the latest runtime in memory.
54
+ 3. **Live WebSocket Hot-Reload**: The plugin connects to `ws://127.0.0.1:38451/ws`. When you upgrade `figma-rust-mcp` or restart the daemon, the plugin automatically detects the new server version and hot-reloads seamlessly — **no need to re-import or restart the plugin in Figma**.
55
+ 4. **Auto-Reconnect & Offline Buffer**: If Figma is opened before the Rust service starts, the plugin displays a waiting screen and connects automatically the instant the service is up.
56
+
57
+ ---
58
+
59
+ ## 🚀 Quick Start
60
+
61
+ ### 1. One-Line Setup & Launch with NPX (No Rust toolchain needed)
62
+
63
+ ```bash
64
+ # Launch interactive MCP server
65
+ npx -y figma-rust-mcp@latest
66
+ ```
67
+ *(Automatically downloads precompiled native binary for macOS Apple Silicon/Intel, Linux, or Windows).*
68
+
69
+ ---
70
+
71
+ ### 2. Install the Figma Plugin (Permanent One-Time Setup)
72
+
73
+ Create the permanent Thin Loader folder in your home directory:
74
+
75
+ ```bash
76
+ npx -y figma-rust-mcp@latest --setup-plugin
77
+ ```
78
+
79
+ 1. Open **Figma Desktop**.
80
+ 2. Go to **Plugins** → **Development** → **Import plugin from manifest...**
81
+ 3. Select `~/.figma-mcp/plugin/manifest.json` (or `plugin/manifest.json` inside this repository).
82
+ 4. Run the plugin: **Plugins** → **Development** → **Figma MCP Bridge**.
83
+ 5. **Done!** Future updates to `figma-rust-mcp` will stream to Figma automatically.
84
+
85
+ ---
86
+
87
+ ### 3. Run as Auto-Start Background Service (Recommended)
88
+
89
+ Run `figma-rust-mcp` seamlessly in the background across all your AI editors without keeping a terminal open:
90
+
91
+ ```bash
92
+ # Install and start background service (macOS LaunchAgent, Linux systemd, Windows Task)
93
+ npx -y figma-rust-mcp@latest --install-service
94
+
95
+ # Check live background service status & bridge health
96
+ npx -y figma-rust-mcp@latest --service-status
97
+
98
+ # One-command upgrade to latest version & auto-restart background service
99
+ npx -y figma-rust-mcp@latest --upgrade
100
+
101
+ # Add convenient 'figma-mcp' alias to your shell profile (~/.zshrc, ~/.bashrc)
102
+ npx -y figma-rust-mcp@latest --alias
103
+
104
+ # Stop and remove background service
105
+ npx -y figma-rust-mcp@latest --uninstall-service
106
+ ```
107
+
108
+ ---
109
+
110
+ ### Windows background mode
111
+
112
+ Double-clicking `figma-mcp.exe` starts the server in a detached process and closes
113
+ its launcher console. From PowerShell or Command Prompt, use:
114
+
115
+ ```powershell
116
+ .\figma-mcp.exe --background
117
+ ```
118
+
119
+ The server keeps running after the terminal closes. Logs are appended to
120
+ `%LOCALAPPDATA%\figma-mcp\logs\server.log`. Use `--server` for the foreground
121
+ terminal dashboard, or `--stdio` for an MCP client subprocess.
122
+
123
+ `--install-service` through the npm runner configures background startup at login.
124
+ Re-run the installation command to update an existing Windows task. Removing the
125
+ task disables future login startup; stop an already detached server through Task
126
+ Manager (`figma-mcp.exe`). The launcher console may appear briefly when opening
127
+ the executable; the server itself does not retain a console window.
128
+
129
+ ### 4. Build from Source (Optional)
130
+
131
+ If you prefer building directly with the [Rust toolchain](https://rustup.rs/) (`cargo >= 1.80`):
132
+
133
+ ```bash
134
+ git clone https://github.com/BuiHung1612/figma-mcp.git
135
+ cd figma-mcp
136
+ cargo build --release
137
+ ./target/release/figma-mcp
138
+ ```
139
+
140
+ ---
141
+
142
+ ### 5. Configure Your MCP Client
143
+
144
+ #### Codex and clients using Streamable HTTP (Recommended)
145
+
146
+ Use the `/mcp` endpoint. It accepts `POST` JSON-RPC requests directly:
147
+
148
+ ```toml
149
+ [mcp_servers.figma-mcp]
150
+ url = "http://127.0.0.1:38451/mcp"
151
+ ```
152
+
153
+ For Codex CLI, the equivalent command is:
154
+
155
+ ```bash
156
+ codex mcp add figma-mcp --url http://127.0.0.1:38451/mcp
157
+ ```
158
+
159
+ #### Google Antigravity (SSE Transport)
160
+ Add to your `~/.gemini/config/mcp_config.json` or project `.agents/mcp_config.json`:
161
+ ```json
162
+ {
163
+ "mcpServers": {
164
+ "figma-mcp": {
165
+ "serverUrl": "http://127.0.0.1:38451/sse"
166
+ }
167
+ }
168
+ }
169
+ ```
170
+
171
+ #### Claude Code / Cursor / Windsurf / VS Code / Zed
172
+
173
+ **Option A: SSE Transport (for clients that require SSE)**
174
+ ```json
175
+ {
176
+ "mcpServers": {
177
+ "figma-mcp": {
178
+ "url": "http://127.0.0.1:38451/sse"
179
+ }
180
+ }
181
+ }
182
+ ```
183
+
184
+ The SSE transport uses `GET /sse` to open the event stream and `POST /message`
185
+ (or `/messages`) for JSON-RPC messages. Do not configure a Streamable HTTP
186
+ client such as Codex against `/sse`: that endpoint does not accept `POST`, so
187
+ the initialize request will return HTTP 405. Use `/mcp` instead.
188
+
189
+ **Option B: Stdio Subprocess (via NPX)**
190
+ ```json
191
+ {
192
+ "mcpServers": {
193
+ "figma-rust-mcp": {
194
+ "command": "npx",
195
+ "args": ["-y", "figma-rust-mcp", "--stdio"]
196
+ }
197
+ }
198
+ }
199
+ ```
200
+
201
+ ### 6. Diagnose a stale Figma runtime
202
+
203
+ Check the runtime bundle currently served to Figma Desktop:
204
+
205
+ ```bash
206
+ curl http://127.0.0.1:38451/plugin/version
207
+ ```
208
+
209
+ The response includes `version` and `runtimeHash`. If the hash changes after an
210
+ upgrade, the dynamic plugin runtime is refreshed automatically. Restart the
211
+ Figma plugin only if the reported hash does not change.
212
+
213
+ ---
214
+
215
+ ## 🛠️ MCP Tools Reference
216
+
217
+ `figma-mcp` provides **15 first-class MCP tools**:
218
+
219
+ ### 1. `figma_status`
220
+ Checks live bridge connection status, connected Figma tabs/files, in-memory index health, queue length, and latency statistics.
221
+
222
+ ### 2. `figma_inspect_node`
223
+ Inspects a specific node by ID or name, returning CSS styles, flex layout rules, tokens, typography, and fills in a clean format (served in `< 1ms` via in-memory index or direct bridge).
224
+
225
+ ### 3. `figma_to_code`
226
+ Compiles any Figma node (Frame, Component, Section, or selection) directly into clean, production-ready component code.
227
+ - **`framework`**: `"react-tailwind"` (default), `"react-native"`, `"vue-tailwind"`, `"html"`, `"swiftui"`.
228
+ - **`outputPath`**: Directly saves the generated component to your codebase (e.g. `src/components/UserProfileCard.tsx`).
229
+ - **`componentName`**: Custom component name override.
230
+
231
+ ### 4. `figma_get_tokens`
232
+ Exports Figma Variables (Design Tokens), Color Styles, Typography Styles, and Elevation/Shadow Styles directly into frontend code.
233
+ - **`format`**: `"tailwind"` (`tailwind.config.js` theme.extend), `"css"` (`:root` CSS custom properties with light/dark theme modes), `"typescript"` (`tokens.ts`), `"w3c"` (W3C DTCG Token Studio JSON), or `"json"`.
234
+ - **`outputPath`**: Writes directly to disk (e.g. `src/styles/tokens.css` or `tailwind.config.js`).
235
+ - **`collection`** / **`mode`** / **`prefix`**: Optional filters and naming prefixes.
236
+
237
+ Token exports use schema v2 and preserve full paint/effect stacks, alpha, gradient
238
+ transforms, collection modes and raw alias values. CSS, Tailwind, TypeScript and
239
+ JSON share one normalized model. The `w3c` output uses DTCG 2025.10 color,
240
+ dimension, gradient-stop and shadow values, with Figma-specific geometry and
241
+ unsupported values retained in `$extensions`.
242
+
243
+ Linear gradients on a node are projected using its actual dimensions. A diagonal
244
+ gradient style has no target aspect ratio: use `get_css` on its consuming node.
245
+ Radial/angular/diamond paints, unsupported blend modes and progressive blurs
246
+ retain their raw data and report diagnostics recommending SVG instead of emitting
247
+ approximate CSS. Unknown modes, unresolved aliases and sanitized name collisions
248
+ fail explicitly. CSS exports include non-default modes under `data-theme`
249
+ selectors; opacity/font-weight variables stay unitless.
250
+
251
+ The plugin UI badge is stamped from the build version and updated from the
252
+ connected server handshake. Package/Cargo/tag mismatches fail the build pipeline.
253
+ Run `npm run build:plugin` after changing plugin source, and `npm run test:tokens`
254
+ for the token/contract/version regression suite. Existing background servers need
255
+ a restart with the new binary to load the updated runtime.
256
+
257
+
258
+ ### 5. `figma_get_selection`
259
+ Inspection of currently selected layers/frames, with shared-style compression when it reduces response size.
260
+ - **`detail`**: `"compact"` (default), `"minimal"`, `"full"`.
261
+
262
+ Compact/minimal `get_selection` and `get_design` responses may contain a root
263
+ `_compression` object with `version: 1` and a `styles` dictionary. For each node
264
+ with `styleRef`, merge `_compression.styles[node.styleRef]` into that node and
265
+ remove `styleRef`; remove root `_compression` to reconstruct the plugin payload
266
+ exactly. Style references are dictionary lookups, not inherited CSS. Payloads
267
+ with reserved-field collisions or no net byte savings stay inline. `detail: "full"` bypasses this Rust transformation and queries the plugin rather than a
268
+ compact selection cache. Plugin detail, visibility, precision, depth and node
269
+ budgets still determine the source payload; compression cannot restore fields
270
+ omitted there. Code generation continues to consume inline styles.
271
+
272
+ No token-reduction or AI-latency percentage is claimed without a tokenizer and
273
+ end-to-end benchmark on real designs.
274
+ - **`depth`**: Tree depth limit or `"full"`.
275
+
276
+ ### 6. `figma_export_asset`
277
+ Exports any Figma node/layer directly into PNG, JPG, or SVG.
278
+ - **`outputPath`**: When specified (e.g. `src/assets/logo.png`), saves directly to disk and returns minimal JSON metadata instead of bloating context with large base64 strings.
279
+ - **`format`**: `"png"` (default), `"jpg"`, `"svg"`.
280
+ - **`scale`**: Scaling factor (default `2` for high-res).
281
+
282
+ ### 7. `figma_export_assets`
283
+ Batch extracts all SVG icons and PNG images from a Figma frame/page directly into project directories.
284
+ - **`iconDir`**: Directory path for SVG icons (e.g. `src/assets/icons`).
285
+ - **`imageDir`**: Directory path for raster images (e.g. `public/images`).
286
+ - **`createBarrel`**: Automatically creates an `index.ts` barrel export file in `iconDir`.
287
+
288
+ ### 8. `figma_index`
289
+ Instant `< 1ms` in-memory queries against pre-indexed Figma file structures.
290
+ - **`operation`**:
291
+ - `"status"`: View index health and node counts.
292
+ - `"search_nodes"`: Search nodes by text name, query, and type (`FRAME`, `TEXT`, `COMPONENT`, `INSTANCE`).
293
+ - `"get_node"`: Instant node lookup by ID.
294
+ - `"search_components"`: Find component sets and variants.
295
+ - `"search_styles"`: Find paint, text, and effect styles.
296
+ - `"search_variables"`: Find design token variables by name or collection.
297
297
  - `"refresh"`: Trigger full background re-indexing of the canvas.
298
-
299
- ### 9. `figma_read`
300
- Universal reader for advanced queries:
301
- - **Design-to-code**: `get_design_context`, `get_css`, `get_component_map`, `get_unmapped_components`.
302
- - **Inspection & Hierarchy**: `get_selection`, `get_design`, `get_page_nodes`, `get_node_detail`, `scan_design`, `search_nodes`.
303
- - **Design Systems**: `get_styles`, `get_variables`, `get_local_components`, `get_tokens`.
304
- - **Visuals & Canvas**: `screenshot`, `export_svg`, `export_image`, `get_viewport`.
305
-
306
- ### 10. `figma_write`
307
- Executes JavaScript draw commands inside the sandboxed VM to build or modify designs on the Figma canvas.
308
- - Supports Auto-layout (`layoutMode`, `itemSpacing`, `padding`), typography, fills, strokes, corner radius, drop shadows, and component creation.
309
- - Supports icon loading: `figma.loadIcon("ionicons", "heart", { size: 24, fill: "#ff4757" })`.
310
- - Supports image insertion: `figma.loadImage(url, { width: 300, height: 200 })`.
311
- - Supports Design Tokens: `createVariableCollection`, `createVariable`, `addVariableMode`, `applyVariable`.
312
- - Supports Prototyping & Reactions: `setReactions`, `getReactions`, `setScrollBehavior`.
313
-
314
- ### 11. `figma_rules`
315
- Audits the current Figma document and generates a complete design system rule sheet (color tokens, typography styles, variables, component catalog) in `< 1ms` from cache.
316
-
317
- ### 12. `figma_docs`
318
- Fetches built-in documentation, design rules, layout guidelines, and code examples for `figma_write`.
319
- - **`section`**: `"rules"` | `"layout"` | `"api"` | `"tokens"` | `"icons"`
320
-
321
- ### 13. `figma_verify_ui`
322
- Validates and compares actual rendered HTML/React UI styles and layout against Figma design specifications.
323
- - Checks dimensions, padding, flex gap, colors, border-radius, and typography.
324
- - Returns an exact match percentage (`match_percentage`), discrepancy breakdown, and actionable CSS/Tailwind fixes.
325
- - **`nodeId`** / **`nodeName`**: Target Figma node spec.
326
- - **`computedStyles`**: Key-value pairs of computed CSS properties from browser/component inspection.
327
- - **`url`** / **`selector`**: Contextual target URL or CSS selector inspected.
328
-
329
- ### 14. `figma_match_components`
330
- Scans your local codebase directories (`src/components`, `components/ui`) to discover existing React/Vue components and matches them directly against Figma design layers, preventing duplicate component creation and ensuring reuse of existing design systems.
331
- - **`projectDir`**: Base directory of your project (default: current directory `"."`).
332
- - **`nodeId`**: Optional Figma node ID to check specific match against local components.
333
-
334
- ### 15. `figma_prepare_design`
335
- **All-In-One Multimodal Grounding Pack for AI**: The ultimate single-call tool for code generation that eliminates missing UI elements and icon guesswork.
336
- - Simultaneously extracts **100% of visible text elements** (greeting, badges, timestamps, labels).
337
- - Automatically **exports all SVG vector icons** into your local project directory (`iconDir`) and provides exact TypeScript import statements.
338
- - Captures high-res **visual canvas screenshots** saved locally for immediate multimodal LLM inspection.
339
- - Discovers existing components in your codebase for direct reuse.
340
- - Generates an actionable **Implementation Checklist** ensuring complete design fidelity in 1 single shot.
341
- - **`nodeId`**: Target Figma screen/frame ID.
342
- - **`iconDir`**: Target directory for SVG icons (e.g. `src/assets/icons` or `assets/images`).
343
- - **`projectDir`**: Base directory for component discovery.
344
-
345
- ---
346
-
347
- ### Multiple tabs and frame tasks
348
-
349
- Each plugin runtime has its own `sessionId`; tabs of the same file share a
350
- `documentId`. Use `figma_status` to discover tabs. With multiple connected tabs,
351
- pass an exact `sessionId`; the server rejects ambiguous routing.
352
-
353
- For multiple agents editing one file, call `figma_task` with `action: "start"`,
354
- `sessionId` and `frameId`, then pass the returned `taskId` on subsequent tools.
355
- Each task reserves a separate FRAME directly under a PAGE or SECTION, without
356
- shared component definitions. Writes stay inside that frame; global styles,
357
- variables, page and selection changes are blocked. A frame cannot be reserved
358
- twice, including across tabs of the same document. Release it with `figma_task`
359
- using `action: "end"` and `taskId`; restart tasks after a plugin reload.
360
-
361
- Tools on one tab run sequentially, including every awaited operation in a
362
- `figma_write` call. Different tabs run independently. `npm run test:sessions`
363
- (Node >=22) checks real WebSocket/HTTP transport with a simulated plugin canvas;
364
- it does not replace validation in Figma Desktop.
365
-
366
- ### Startup indexing
367
-
368
- Opening the bridge indexes top-level nodes on the active page and local tokens.
369
- It does not preload every page or scan the document-wide component catalogue.
370
- `figma_index` status exposes `components_indexed: false` until a full reindex;
371
- this means deferred, not an empty catalogue. Live component queries populate
372
- the Rust cache for subsequent reads while the index remains valid. Component reads/searches and rules
373
- that require the complete catalogue fall back to a live query.
374
-
375
- The plugin listens to active-page `nodechange` and global `stylechange` events,
376
- and rebuilds the lightweight index when the active page changes. It does not
377
- subscribe to document-wide node changes by preloading the whole file. Explicit
378
- reindexing still includes all local components; discovery loads pages one at a
379
- time and yields after at most 100 nodes or an 8ms traversal slice. Figma's native
380
- page load itself cannot be interrupted by the plugin. Concurrent identical
381
- index requests share one scan, and results from a previously active page are
382
- not published as the current index.
383
-
384
- ## 💻 Development & Testing
385
-
386
- ```bash
387
- # Run server in debug mode
388
- cargo run
389
-
390
- # Build optimized release binary
391
- cargo build --release
392
-
393
- # Run automated MCP test suite
394
- ./scripts/test-rust-mcp.sh
395
-
396
- # Rebuild Figma plugin bundle (if plugin-src/ is modified)
397
- node scripts/build-plugin.js
398
- ```
399
-
400
- ---
401
-
402
- ## 📄 License
403
-
404
- MIT © [BuiHung1612](https://github.com/BuiHung1612) — Free to use, modify, and distribute. See [LICENSE](LICENSE) for details.
298
+ - `"subtree"`: Read/cache one `nodeId`, default depth 2 and 1000 nodes. Increase `depth` or `maxNodes` only for the section you need; check `meta` for truncation.
299
+ - `"typography"`: Rust-generated text/font table for one `nodeId`, with mixed-style runs preserved. Default limit 200 rows. Null font fields mean unknown/mixed, not a guessed default.
300
+
301
+ `status` includes per-tab dispatch cache hits/misses, bridge calls and total bridge wait time, plus process-wide tool call counts and total/average milliseconds. Node changes invalidate related subtrees; style changes, unknown events and global writes invalidate the whole cache. Detailed subtree data is loaded on demand. The initial index remains shallow.
302
+
303
+ For typography verification, call `figma_verify_ui` with a text `nodeId` and browser `computedStyles` (`font-size` in px, numeric `font-weight`, `font-family`). Mixed text accepts `computedStyles.segments`, an ordered array of CSS objects matching the Figma runs. Size checks preserve fractional pixels.
304
+
305
+ ### 9. `figma_read`
306
+ Universal reader for advanced queries:
307
+ - **Design-to-code**: `get_design_context`, `get_css`, `get_component_map`, `get_unmapped_components`.
308
+ - **Inspection & Hierarchy**: `get_selection`, `get_design`, `get_page_nodes`, `get_node_detail`, `scan_design`, `search_nodes`.
309
+ - **Design Systems**: `get_styles`, `get_variables`, `get_local_components`, `get_tokens`.
310
+ - **Visuals & Canvas**: `screenshot`, `export_svg`, `export_image`, `get_viewport`.
311
+
312
+ ### 10. `figma_write`
313
+ Executes JavaScript draw commands inside the sandboxed VM to build or modify designs on the Figma canvas.
314
+ - Supports Auto-layout (`layoutMode`, `itemSpacing`, `padding`), typography, fills, strokes, corner radius, drop shadows, and component creation.
315
+ - Supports icon loading: `figma.loadIcon("ionicons", "heart", { size: 24, fill: "#ff4757" })`.
316
+ - Supports image insertion: `figma.loadImage(url, { width: 300, height: 200 })`.
317
+ - Supports Design Tokens: `createVariableCollection`, `createVariable`, `addVariableMode`, `applyVariable`.
318
+ - Supports Prototyping & Reactions: `setReactions`, `getReactions`, `setScrollBehavior`.
319
+
320
+ ### 11. `figma_rules`
321
+ Audits the current Figma document and generates a complete design system rule sheet (color tokens, typography styles, variables, component catalog) in `< 1ms` from cache.
322
+
323
+ ### 12. `figma_docs`
324
+ Fetches built-in documentation, design rules, layout guidelines, and code examples for `figma_write`.
325
+ - **`section`**: `"rules"` | `"layout"` | `"api"` | `"tokens"` | `"icons"`
326
+
327
+ ### 13. `figma_verify_ui`
328
+ Validates and compares actual rendered HTML/React UI styles and layout against Figma design specifications.
329
+ - Checks dimensions, padding, flex gap, colors, border-radius, and typography.
330
+ - Returns an exact match percentage (`match_percentage`), discrepancy breakdown, and actionable CSS/Tailwind fixes.
331
+ - **`nodeId`** / **`nodeName`**: Target Figma node spec.
332
+ - **`computedStyles`**: Key-value pairs of computed CSS properties from browser/component inspection.
333
+ - **`url`** / **`selector`**: Contextual target URL or CSS selector inspected.
334
+
335
+ ### 14. `figma_match_components`
336
+ Scans your local codebase directories (`src/components`, `components/ui`) to discover existing React/Vue components and matches them directly against Figma design layers, preventing duplicate component creation and ensuring reuse of existing design systems.
337
+ - **`projectDir`**: Base directory of your project (default: current directory `"."`).
338
+ - **`nodeId`**: Optional Figma node ID to check specific match against local components.
339
+
340
+ ### 15. `figma_prepare_design`
341
+ **All-In-One Multimodal Grounding Pack for AI**: The ultimate single-call tool for code generation that eliminates missing UI elements and icon guesswork.
342
+ - Simultaneously extracts **100% of visible text elements** (greeting, badges, timestamps, labels).
343
+ - Automatically **exports all SVG vector icons** into your local project directory (`iconDir`) and provides exact TypeScript import statements.
344
+ - Captures high-res **visual canvas screenshots** saved locally for immediate multimodal LLM inspection.
345
+ - Discovers existing components in your codebase for direct reuse.
346
+ - Generates an actionable **Implementation Checklist** ensuring complete design fidelity in 1 single shot.
347
+ - **`nodeId`**: Target Figma screen/frame ID.
348
+ - **`iconDir`**: Target directory for SVG icons (e.g. `src/assets/icons` or `assets/images`).
349
+ - **`projectDir`**: Base directory for component discovery.
350
+
351
+ ---
352
+
353
+ ### Multiple tabs and frame tasks
354
+
355
+ Each plugin runtime has its own `sessionId`; tabs of the same file share a
356
+ `documentId`. Use `figma_status` to discover tabs. With multiple connected tabs,
357
+ pass an exact `sessionId`; the server rejects ambiguous routing.
358
+
359
+ For multiple agents editing one file, call `figma_task` with `action: "start"`,
360
+ `sessionId` and `frameId`, then pass the returned `taskId` on subsequent tools.
361
+ Each task reserves a separate FRAME directly under a PAGE or SECTION, without
362
+ shared component definitions. Writes stay inside that frame; global styles,
363
+ variables, page and selection changes are blocked. A frame cannot be reserved
364
+ twice, including across tabs of the same document. Release it with `figma_task`
365
+ using `action: "end"` and `taskId`; restart tasks after a plugin reload.
366
+
367
+ Tools on one tab run sequentially, including every awaited operation in a
368
+ `figma_write` call. Different tabs run independently. `npm run test:sessions`
369
+ (Node >=22) checks real WebSocket/HTTP transport with a simulated plugin canvas;
370
+ it does not replace validation in Figma Desktop.
371
+
372
+ ### Startup indexing
373
+
374
+ Opening the bridge indexes top-level nodes on the active page and local tokens.
375
+ It does not preload every page or scan the document-wide component catalogue.
376
+ `figma_index` status exposes `components_indexed: false` until a full reindex;
377
+ this means deferred, not an empty catalogue. Live component queries populate
378
+ the Rust cache for subsequent reads while the index remains valid. Component reads/searches and rules
379
+ that require the complete catalogue fall back to a live query.
380
+
381
+ The plugin listens to active-page `nodechange` and global `stylechange` events,
382
+ and rebuilds the lightweight index when the active page changes. It does not
383
+ subscribe to document-wide node changes by preloading the whole file. Explicit
384
+ reindexing still includes all local components; discovery loads pages one at a
385
+ time and yields after at most 100 nodes or an 8ms traversal slice. Figma's native
386
+ page load itself cannot be interrupted by the plugin. Concurrent identical
387
+ index requests share one scan, and results from a previously active page are
388
+ not published as the current index.
389
+
390
+ ## 💻 Development & Testing
391
+
392
+ ```bash
393
+ # Run server in debug mode
394
+ cargo run
395
+
396
+ # Build optimized release binary
397
+ cargo build --release
398
+
399
+ # Run automated MCP test suite
400
+ ./scripts/test-rust-mcp.sh
401
+
402
+ # Rebuild Figma plugin bundle (if plugin-src/ is modified)
403
+ node scripts/build-plugin.js
404
+ ```
405
+
406
+ ---
407
+
408
+ ## 📄 License
409
+
410
+ MIT © [BuiHung1612](https://github.com/BuiHung1612) — Free to use, modify, and distribute. See [LICENSE](LICENSE) for details.