nilux-figma-mcp
v0.1.0
Published
Read-only design-to-code MCP server for Figma — reads the LIVE document from a companion Figma plugin over a local WebSocket bridge. Works on any plan (incl. Free), no REST API, no rate limits. A replacement for the official Figma Dev Mode MCP.
Maintainers
Readme
nilux-figma-mcp
A read-only design-to-code MCP server for Figma that works on any plan (including Free) with no REST API and no rate limits. It reads the live document from a companion Figma plugin over a local WebSocket bridge — so there's nothing to pay for and nothing to throttle. Part of the nilux toolkit.
Why
The official Figma Dev Mode MCP needs a paid Dev/Full seat, and the Figma REST API is paywalled on Free/Starter plans — file/image reads are capped at roughly 6 requests per month per file (and the limit follows the file's team, so shared files hit it too). That's unusable for real design-to-code.
A Figma plugin runs inside Figma (browser or desktop), has full local document access and no rate limits, and streams the design to this server. Reads and screenshots are free and unlimited.
How it works
Figma (browser or desktop) + nilux-figma plugin
│ ws://localhost:1994 (the plugin's UI iframe owns the socket)
▼
nilux-figma-mcp server (WebSocket bridge → compact layout/style/token JSON)
▼
your AI agent (nilux / Claude Code / any MCP client)Nothing is saved or cached — data is always read live from the open plugin.
Install
1. Register the MCP server
Register once at user scope so it's available in every project (no Figma token needed):
# nilux
nilux mcp add nilux-figma -s user -- npx -y nilux-figma-mcp@latest
# Claude Code (same CLI surface)
claude mcp add nilux-figma -s user -- npx -y nilux-figma-mcp@latest2. Import the Figma plugin
Importing a development plugin requires the Figma desktop app (the browser can't import from a manifest). Once imported it runs in both desktop and browser.
- Get the plugin folder (from this package's
plugin/directory, or a release zip). - Figma desktop → Plugins → Development → Import plugin from manifest…
- Select
plugin/manifest.json.
3. Use it
Open a Figma file, run the nilux-figma plugin (its window should show Connected), then ask your AI agent. The server connects to the plugin automatically. Restart the AI session after first registering so the tools load.
Tools
| Tool | What it returns |
|------|-----------------|
| list_files | Files currently connected through the plugin. Call first to confirm the connection. |
| list_pages | Pages in the file (id, name, current). Read a non-current page by passing its id as nodeId. |
| get_selection | Nodes the user has selected right now — a great entry point. |
| get_metadata | Sparse node tree (ids, types, sizes, positions) to map a design. |
| get_design_context | The main tool: compact layout + styling (flex, padding, gaps, colors, borders, radius, shadows, typography, text, image fills). |
| get_styles | Design tokens actually used under a node — colors, typography, effects ranked by usage. |
| get_variables | Figma Variables (named tokens): collections, modes, per-mode values. Enterprise-only via REST — free here. |
| get_screenshot | Renders a node to PNG/JPG (inline), SVG markup, or PDF, via the plugin's exportAsync. |
| download_assets | mode=render exports nodes (SVG inline / PNG base64); mode=fills returns image fills as data URIs. |
When a single file is connected you don't pass file — it's auto-selected. For multi-file
work, pass the fileKey from list_files.
Multiple files & sessions
- Several files in one session: open the plugin in each — they all connect to the one
bridge; target a file with its
fileKey. No conflict. - Several AI sessions at once (e.g. one nilux per project): they coordinate via leader/follower election so only one process owns the bridge port and the rest proxy to it.
Browser vs desktop
ws://localhost works from https://figma.com because browsers treat localhost as a secure
context (Chrome/Chromium and the desktop Electron app). Importing a dev plugin requires the
desktop app, but running it works in both.
Limitations
- Read-only — no writing back to Figma (by design).
- Responsive/breakpoints aren't stored by Figma; you implement those from the design.
- The plugin must be open in Figma during a session (data is live, not cached).
Build / test
npm run build # tsc → dist (server)
npm run build:plugin # esbuild → plugin/code.js
npm run typecheck:plugin # tsc with @figma/plugin-typings
npm test # build + node test/bridge_test.mjs (fake-plugin, no real Figma needed)Stack
TypeScript · @modelcontextprotocol/sdk · ws · zod · Node ≥ 20 · plugin built with esbuild.
