Skip to main content
Glama
echobt

@echobt/figma-mcp

by echobt
README.md
# @echobt/figma-mcp

**Complete fork** of [`bilalba/fig-mcp`](https://github.com/bilalba/fig-mcp) — local MCP server for reading and rendering `.fig` files offline (no Figma API, no PAT, no rate limits).

Maintained at **[echobt/figma-mcp](https://github.com/echobt/figma-mcp)**.

## Why this fork

Upstream is a solid fig-kiwi parser + experimental SVG renderer. This fork hardens it for **agent design-to-code workflows** on large local archives (hundreds of MB, 100k+ nodes):

| Area | Improvement |
|------|-------------|
| **File reading** | Lazy ZIP `ImageStore` — only inflate images on demand (canvas/meta/thumbnail eager) |
| **Screenshots** | `pixelPerfect` mode (no 800×600 clamp), `outputPath` disk write, MCP `image` + JSON meta |
| **Agent assets** | `export_asset_pack` (true SVG/files + AGENTS.md) — forbids inventing paths |
| **Images** | `get_image` / `get_thumbnail` return real MCP image content (base64), optional `outputPath` |
| **INSTANCE** | Expand symbol children even when overrides are empty (was incorrectly skipped) |
| **Typography** | Letter-spacing units (`PERCENT` → px via font size) normalized at parse |
| **Tests** | node:test suite + TAOSCAN smoke harness |

Verified against a large real file (`TAOSCAN - Mockups.fig`, ~391MB, 23 pages, ~229k nodes, 1219 images).

## Install

```bash
npm install -g @echobt/figma-mcp
# or
npx @echobt/figma-mcp --help
```

Binaries (identical): `figma-mcp`, `fig-mcp`.

## Quick start (Claude / Cursor / OpenCode)

```bash
# Claude Code
claude mcp add figma-mcp -- npx @echobt/figma-mcp

# Or pin a local path
claude mcp add figma-mcp -- node /path/to/figma-mcp/dist/index.js
```

Example prompts:

> Parse `/path/to/design.fig`, list pages, then export a design spec for the Home frame and take a pixelPerfect screenshot to `/tmp/home.png`.

## CLI

| Command | Description |
|---------|-------------|
| `figma-mcp` | Start MCP server (stdio) + optional image HTTP sidecar |
| `figma-mcp viewer <file> [port]` | Web viewer (default port 3000) |
| `figma-mcp inspect <file> [cmd]` | `list` / `summary` / `stats` / `schema` / `json` / `raw` |
| `figma-mcp --help` / `--version` | Help / version |

## MCP tools

### Document structure
| Tool | Description |
|------|-------------|
| `parse_fig_file` | Simplified document tree |
| `get_document_summary` | Paginated text tree |
| `get_tree_summary` | Hierarchical drill-down |
| `list_pages` | All canvases |
| `get_page_contents` | Contents of one page |

### Nodes
| Tool | Description |
|------|-------------|
| `find_nodes` | By type or name |
| `get_node_details` | By path |
| `get_node_by_id` | By GUID `sessionID:localID` (also accepts `sessionID-localID`) |
| `get_layout_info` | Inferred flex-like layout |

### Content
| Tool | Description |
|------|-------------|
| `get_text_content` | Extract text |
| `get_colors` | Unique solid colors |
| `list_nodes_with_fills` | Nodes with fills |

### Images & rendering
| Tool | Description |
|------|-------------|
| `list_images` | Image inventory (lazy metadata) |
| `get_image` | **MCP image content** + JSON meta; optional `outputPath` |
| `get_thumbnail` | Document thumbnail as MCP image |
| `render_screen` | PNG of node; default `trueGeometry=true` (baked paths → SVG → resvg); `pixelPerfect`, `outputPath` |
| `get_vector` | Export **real** geometry SVG/PDF/PNG — prefer `outputPath`, open the file |

### Agent copy (fork)
| Tool | Description |
|------|-------------|
| **`get_mcp_guide`** | **Read first.** Full rules + UCs (`MCP_GUIDE.md`). No file needed. Also resource `figma-mcp://guide`. |
| `export_asset_pack` | **Primary implement tool.** Writes `MANIFEST.json`, `AGENTS.md`, `images/`, `vectors/*`, `nodes/{id}/node.svg`+`node.png`+`design-spec.json`. Open these files — never invent SVG paths. |
| `export_design_spec` | CSS + layout + tokens + tree + text for a node (JSON, optional `outputPath`) |
| `export_node_assets` / `save_node_assets` | Write real images + true-geometry SVG + PNG for one node to a directory |

### Debug
| Tool | Description |
|------|-------------|
| `get_schema_info` | Kiwi schema meta |
| `get_raw_message` | Raw decoded message (truncated) |
| `list_archive_contents` | ZIP entries |
| `clear_cache` | Drop parsed cache + inflated image LRU |

## Agent guide (required reading)

**Canonical rules + use cases:** [`MCP_GUIDE.md`](./MCP_GUIDE.md), or call **`get_mcp_guide`** / read resource **`figma-mcp://guide`**.

Server initialize also sends short `instructions` pointing agents at that guide.

## Agent workflow (recommended)

**Golden rule:** never invent SVG `d` paths or re-draw icons. Always use exported files.

0. **`get_mcp_guide`** — hard rules + UC catalog (once per session)  
1. `list_pages` / `get_tree_summary` — map the file  
2. `find_nodes` or `get_node_by_id` — pick a frame (`session:local`)  
3. **`export_asset_pack`** with `outputDir` — dumps real assets + `AGENTS.md` policy  
4. Read `MANIFEST.json` and open `nodes/*/node.svg`, `vectors/*.svg`, `images/*`  
5. `export_design_spec` for exact text/CSS tokens  
6. Implement with HTML/CSS + file references (img/src or copied SVG files)  
7. Optional `render_screen` with `trueGeometry: true` (default) + `outputPath` for visual QA  

`get_vector` also exports **real** baked geometry — prefer `outputPath` and open the file.

Node IDs look like `3779:22748` (from the web viewer or any tool that returns `id` / `nodeId`).

## How it works

1. `.fig` files are ZIP archives (`canvas.fig` fig-kiwi binary, `meta.json`, `thumbnail.png`, `images/`).  
2. Schema embedded in each file is decoded with [kiwi](https://github.com/evanw/kiwi).  
3. Flat `nodeChanges` are rebuilt into a tree.  
4. Images stay in the archive until requested (`ImageStore`).  
5. Subtrees render to SVG → PNG via `@resvg/resvg-js`.

## Develop

```bash
npm install
npm run build
npm test
FIG_MCP_TAOSCAN="/path/to/file.fig" npm run smoke:taoscan
```

Smoke writes evidence under `/tmp/opencode/fig-mcp-work/qa-out/` when available.

## Requirements

- Node.js 18+

## Limitations

- `.fig` format is undocumented and may change  
- Local files only (use official Figma MCP for cloud files)  
- Vector **export** uses Figma baked `fillGeometry`/`strokeGeometry` (true path data from the file). Screenshots use that SVG via resvg — not hand-approximated icons. Complex blend modes / full BOOLEAN merge may still be incomplete.  
- Agents must use `export_asset_pack` files, not recreated path strings.  
- Very large files still keep the ZIP buffer in memory (images are lazy; canvas decode can still be multi‑GB on enormous docs)

## License

MIT — see [LICENSE](./LICENSE).

Upstream credit: [bilalba/fig-mcp](https://github.com/bilalba/fig-mcp) by bilal; [kiwi](https://github.com/evanw/kiwi) by Evan Wallace; MCP TypeScript SDK.

TDQS

B3.4/5.0

Scored across 26 tools

Disambiguation2/5

Many tools have overlapping purposes, such as multiple export functions (export_design_spec, save_node_assets, export_node_assets, export_asset_pack, get_vector, render_screen) and several for node retrieval (get_node_details, get_node_by_id, find_nodes). Descriptions try to differentiate but the similarity causes ambiguity.

Naming Consistency4/5

All tool names use snake_case and start with a verb, providing a coherent pattern. However, the verb choice varies (export, save, get, parse, find, list, render) without a strict hierarchical convention, making it slightly less predictable.

Tool Count3/5

26 tools is high for a single-domain server. While the domain (Figma file analysis) is broad, many tools could be consolidated (e.g., merging export functions). The count feels slightly excessive and may overwhelm agents.

Completeness5/5

The tool set comprehensively covers Figma file parsing, node navigation, asset export, image extraction, color and text analysis, and schema info. No obvious gaps for the intended purpose of reading and extracting design data.