Skip to main content
Glama
shinjiyu

figma-meta-mcp

by shinjiyu
README.md
# figma-meta-mcp

Lightweight **Figma MCP** in the same mental model as
[ae-meta-mcp](https://github.com/shinjiyu/ae_meta_mcp) (`ae_exec`) and
CocosMetaMCP (`cocosmcp_exec`): the Cursor agent runs JavaScript **inside a
running Figma** via `figma_exec`.

```text
Cursor Agent  ──stdio MCP──▶  Node (MCP + bridge :3851)
                                   ▲
                                   │ WebSocket /plugin
                              Figma Development plugin (UI + main)
                                   │
                              figma.* Plugin API
```

This path does **not** use the Figma REST API + Personal Access Token, so it
avoids the Viewer-seat REST monthly rate limits. You need the Figma desktop app
and the local Development plugin panel open.

> Repo: [shinjiyu/figma_mcp](https://github.com/shinjiyu/figma_mcp)

## Tools (MVP)

| Tool | Description |
|------|-------------|
| `figma_health` | Bridge up? Plugin WebSocket connected? |
| `figma_exec` | Run arbitrary Plugin-API JS in the main thread; return JSON |
| `figma_selection_info` | Summarize current page + selection bounds |

## Requirements

- Windows / macOS / Linux
- Node.js >= 18
- [Figma desktop app](https://www.figma.com/downloads/)
- Cursor (or any MCP client)

## Install

```bash
git clone https://github.com/shinjiyu/figma_mcp.git
cd figma_mcp
npm install
```

### Wire Cursor

```bash
npm run setup:cursor
```

Paste the printed snippet into `~/.cursor/mcp.json`, then toggle **figma-meta-mcp**
off/on under Cursor Settings → MCP.

Example:

```json
{
  "mcpServers": {
    "figma-meta-mcp": {
      "command": "node",
      "args": ["D:/workspace/figma_mcp/mcp/index.mjs"],
      "env": {
        "FIGMA_MCP_PORT": "3851"
      }
    }
  }
}
```

### Import the Figma plugin

1. Start Cursor so MCP (and the bridge on `127.0.0.1:3851`) is running.
2. Open your design file in the **Figma desktop** app.
3. Menu: **Plugins → Development → Import plugin from manifest…**
4. Select `plugin/manifest.json` from this repo.
5. Run **Plugins → Development → figma-meta-mcp** and **keep the panel open**.

The panel should show `Connected · plugin channel ready`.

## Verify

1. `figma_health` → `{ ok: true, pluginConnected: true }`
2. `figma_selection_info` → current page + selection
3. `figma_exec`:

```javascript
return {
  file: figma.root.name,
  page: figma.currentPage.name,
  count: figma.currentPage.children.length,
};
```

## Writing `figma_exec` code

- Runs in the **plugin main** thread with global `figma`.
- Write an async body; use `return` for the payload.
- Return plain JSON (id / name / type / x / y / width / height). Live node
  proxies are auto-shrunk when possible, but prefer mapping yourself.
- Need document bytes for a node? `await figma.getNodeByIdAsync(id)` (dynamic-page).

See `skills/figma-plugin-api/SKILL.md`.

## Layout

```text
mcp/      stdio MCP server (index, core, context)
bridge/   HTTP + WebSocket host used by the plugin UI
plugin/   Figma Development plugin (manifest, code.js, ui.html)
scripts/  setup-cursor.mjs
skills/   agent notes for Plugin API
examples/ cursor-mcp.json
```

## Env

| Variable | Default | Meaning |
|----------|---------|---------|
| `FIGMA_MCP_PORT` | `3851` | Bridge listen port |
| `FIGMA_MCP_HOST` | _(unset)_ | Default: bind **loopback only** (`127.0.0.1` + `::1`). Set only to override. |
| `FIGMA_MCP_CORS_ORIGINS` | Figma + `null` + localhost | Comma-separated Origin allowlist (not `*`) |
| `FIGMA_MCP_EXEC_TIMEOUT_MS` | `30000` | Per-job timeout |

## Not in scope (yet)

- Official remote Figma MCP OAuth (`mcp.figma.com`) — use that separately if you want cloud tools
- REST PAT wrappers — intentionally avoided for quota reasons
- Recipe/promote layer (CocosMetaMCP-style) — add later if needed

## License

MIT

TDQS

A4.1/5.0

Scored across 3 tools

Disambiguation5/5

The three tools serve clearly distinct functions: health check, arbitrary code execution, and selection introspection. There is no overlap in purpose, even though figma_selection_info could be replicated via figma_exec; it is presented as a convenience wrapper with a distinct scope.

Naming Consistency4/5

All tool names share the figma_ prefix, but the second part is not uniformly verb_noun. figma_health and figma_selection_info are noun phrases, while figma_exec is a verb. This is a minor inconsistency, but the pattern is still predictable and readable.

Tool Count4/5

Three tools is a small but reasonable set for a bridge server. The health and selection tools handle occasional meta needs, while figma_exec provides the core general-purpose capability. It is slightly on the lean side, but not insufficient.

Completeness5/5

figma_exec offers arbitrary access to the Figma Plugin API, making the tool surface effectively complete for any operation. The other two tools cover operational status and a common convenience need. There are no obvious dead ends or missing core workflows.

Maintenance

ActivitySlowing
ResponsivenessNo issues