Skip to main content
Glama
w4ndaja

FreeMCP for Figma

by w4ndaja

FreeMCP for Figma — Universal MCP Bridge

A local MCP bridge that lets AI coding agents read and write a user's Figma file through the Figma Plugin API (native, in-desktop) instead of the public REST API. No official-MCP rate limits, no Figma API token, and no design data ever leaves the machine.

  • Offline & private — everything runs on 127.0.0.1; a startup guard blocks any outbound HTTP from the server process.

  • Native design-system writes — create frames/shapes/text, author components, insert library component instances, bind variables & styles, configure Auto Layout, constraints and effects — all executed inside Figma via the Plugin API.

  • Design-to-code — generate React (Tailwind), Vue 3, or HTML/CSS from a selected node.

  • Batched & undoablebatch_run applies 100+ ops in one consented request without blocking the Figma UI; undo reverts the last write(s).

Transport: the bridge is HTTP long-poll (POST /register, GET /next, POST /result) on 127.0.0.1:3700, not WebSocket. The Figma plugin sandbox has no WebSocket global — only fetch — so the plugin long-polls a loopback HTTP server hosted by the local MCP process.

Architecture

┌──────────────┐  MCP/STDIO   ┌────────────────────────────┐  HTTP long-poll  ┌──────────────────┐
│  AI client   │ ◀──────────▶ │  local MCP server (Node)   │ ◀───────────────▶ │  Figma plugin     │
│ Claude/VS    │  JSON-RPC     │  packages/server            │  /register       │  packages/plugin   │
│ Cursor/Ollama│              │  127.0.0.1:3700             │  /next  /result  │  (Plugin API)     │
└──────────────┘              └────────────────────────────┘                   └──────────────────┘

Every MCP tool is a thin dispatch. The server validates arguments (Zod), translates the call into a typed bridge frame, and forwards it over loopback HTTP to the Figma plugin, which executes the actual Plugin API call and returns the result. Deep-dive: docs/ARCHITECTURE.md.

Related MCP server: figma-developer-mcp

Quickstart (< 5 min)

1. Install

npm install
npm run build:plugin

2. Load the plugin in Figma

Figma → Plugins → Development → Import plugin from manifest… → select packages/plugin/manifest.json. The plugin auto-connects to http://127.0.0.1:3700 (a small status panel shows connection state).

3. Start the server (own terminal)

npm run start:server

Expect: FreeMCP Figma bridge on http://127.0.0.1:3700. Open the plugin in Figma to connect.

4. Point your AI client at the MCP server (STDIO)

{
  "mcpServers": {
    "figma-free-mcp": {
      "command": "node",
      "args": ["C:/path/to/repo/packages/server/dist/index.js"]
    }
  }
}

Claude Desktop: Settings → Developer → Edit Config. VS Code / Cursor: .mcp.json. You can also run the built bundle directly: node packages/server/dist/index.js.

Using it

Intent

What the agent does

"Describe this design"

get_design_context / get_selection → full node tree, fills, typography, effects, Auto Layout

"What tokens exist?"

get_variables / get_styles → local variables, collections, text/effect/grid styles

"Create a card component"

create_frame (Auto Layout) + create_text children → native Figma nodes

"Insert our primary button"

create_component_instance by key → reuses the design system (local or library)

"Make 100 variants"

batch_run → many ops in one consented request, no UI block

"Undo last change"

undo → reverts creates/duplicates/fills/layout

"Generate React for this"

to_react / to_vue / to_html

Consent: the first write always prompts for consent — every write tool requires confirm: true in its params (FR-504). Nothing is written silently.

Tool reference

Every input is validated by the Zod schema in packages/contracts/src/tool-schemas.ts (single source of truth) before dispatch (FR-404). The per-tool contract lives in specs/001-freemcp-figma-bridge/contracts/tools.md.

Read

Tool

Purpose

Key params

get_selection

Current selection → DesignContext[] (optionally a node by id)

nodeId?, maxDepth?

get_design_context

Deep hierarchical context for a node subtree

nodeId, maxDepth?

get_metadata

Lightweight tree: ids, types, names, bounds

nodeId?

get_screenshot

Raster/SVG export of a node (base64)

nodeId, format (png|jpg|svg), scale?

get_variables

Local variables + collections + mode values

get_styles

Local text/effect/grid styles

get_components

Local components + component sets with importable keys

get_page_children

Top-level nodes on the current page (id/name/type/bounds)

Write (all require confirm: true)

Tool

Purpose

Key params

create_frame

Frame at position/size, optional Auto Layout + sizing

x, y, width, height, layout?, parent?, primaryAxisSizing?, counterAxisSizing?, stroke?, strokeWeight?, cornerRadius?

create_shape

Rectangle / ellipse / polygon

type, x, y, width, height, fill?, stroke?, layoutAlign?, layoutGrow?, parent?

create_text

Text node with font props + text polish

characters, x, y, fontFamily?, fontSize?, fontWeight?, color?, lineHeight?, letterSpacing?, textCase?, textDecoration?, textAutoResize?, layoutAlign?, layoutGrow?, parent?

apply_fill

Apply solid/gradient fill to a node (image fills deferred — need a Figma imageHash)

nodeId, fill

set_auto_layout

Auto Layout direction, padding, spacing, alignment

nodeId, mode, itemSpacing?, padding?, primaryAxisAlignItems?, counterAxisAlignItems?

duplicate_node

Clone preserving properties + children

nodeId, offset?

delete_node

Delete a node (not undoable)

nodeId

create_component_instance

Insert an instance by key (local or published library)

componentKey, x?, y?, parent?, overrides?

create_component

Author a reusable ComponentNode (design-system library)

x, y, width, height, layout?, parent?

set_variable

Bind a variable to a node property; "" unbinds

nodeId, property (fill|strokes|cornerRadius|opacity), variableId

apply_style

Apply a text/effect/grid style; "" clears

nodeId, kind (text|effect|grid), styleId

set_constraints

Layout constraints (align/grow + frame sizing)

nodeId, layoutAlign?, layoutGrow?, primaryAxisSizing?, counterAxisSizing?

set_effect

Set arbitrary effect array (e.g. DROP_SHADOW); [] clears

nodeId, effects

Batch

Tool

Purpose

Key params

batch_run

Run many write ops in one consented batch (100+ < 3s)

ops: { tool, params }[], confirm

Code generation

Tool

Purpose

Key params

to_react

JSX + Tailwind classes

nodeId, includeStyles?

to_vue

Vue 3 Composition API SFC

nodeId

to_html

Semantic HTML + CSS

nodeId

Utility

Tool

Purpose

Key params

undo

Revert last executed write op(s)

count? (1–100)

ping

Health check; returns bridge connectivity + latency

Error envelope (FR-405): every tool result is { ok: true, data } or { ok: false, error: { code, message, suggestion } }, serialized as a JSON string in the MCP text content. suggestion carries a fixable hint.

Security & privacy model

  • No tokens, no cloud (FR-501/502/503) — the server binds only to 127.0.0.1; a startup guard (installOfflineGuard) monkey-patches global fetch to reject any non-loopback request, and an OpLog records every dispatch so an operator can assert only local calls happened.

  • Consent before writes (FR-504) — write tools require confirm: true; the plugin never re-prompts for a single consented batch.

  • Sandbox-bound — design data only ever crosses loopback HTTP between the MCP process and the Figma plugin. Nothing is transmitted off-machine.

Configuration

Env

Default

Purpose

FREEMCP_PORT

3700

Server port. Note: the plugin's target port is compiled in (DEFAULT_PORT in packages/contracts/src/messages.ts), so changing this also requires rebuilding the plugin.

Troubleshooting

Symptom

Fix

NO_PLUGIN: No plugin connected

Open the plugin in Figma (Plugins → Development) so it registers with the server.

Connection refused

Start the server first, then load the plugin.

Port conflict

Set FREEMCP_PORT on the server and rebuild the plugin with the matching constant.

Text ops fail

Text nodes need a loaded font — the plugin calls figma.loadFontAsync automatically before setting text.

Development

npm install             # workspaces: contracts, server, plugin
npm test                # 32 Vitest unit tests (schemas, codec, bridge, undo, codegen)
npm run typecheck       # tsc --noEmit (strict)
npm run build:server    # esbuild bundle → packages/server/dist/index.js (npx-runnable)
npm run build:plugin    # esbuild bundle → packages/plugin/dist/main.js
npm run start:server    # tsx dev run of the MCP server + bridge

Coding agents in this repo additionally have codebase-memory MCP, an LSP provider, and obscura browser tools connected for Spec Kit workflow runs — see docs/TOOLCHAIN.md for the wiring and reproduction. See docs/DEVELOPMENT.md for the developer guide (add a tool, build pipeline, sandbox constraints) and docs/ARCHITECTURE.md for the deep technical reference.

Repository layout

packages/
├── contracts/   # Shared, types-only: DesignContext, bridge frames, Zod tool schemas (source of truth)
├── server/      # MCP server (STDIO) + HTTP long-poll bridge host + codegen + command stack
└── plugin/      # Figma plugin: outbound long-poll client + Plugin API read/write/design-system logic
specs/001-freemcp-figma-bridge/   # Spec Kit artifacts: spec, plan, research, data-model,
                                  # contracts (protocol + tools), quickstart, tasks

Docs index

Doc

What it covers

docs/ARCHITECTURE.md

Components, request lifecycle, long-poll internals, undo, codegen pipeline, security

docs/DEVELOPMENT.md

Adding a tool, build/test workflow, Figma sandbox constraints, conventions

docs/TOOLCHAIN.md

Connected agent tooling for Spec Kit runs: codebase-memory MCP, LSP provider, obscura, routing skill — setup + verification

skills.md

Production-ready Figma design workflow for the bridge MCP: audit → tokens → components → screens, Auto Layout rules, verification gates, bridge limits

specs/001-freemcp-figma-bridge/spec.md

Feature specification (FRs, user stories, success criteria)

specs/001-freemcp-figma-bridge/contracts/protocol.md

HTTP long-poll bridge protocol contract

specs/001-freemcp-figma-bridge/contracts/tools.md

MCP tool surface contract

specs/001-freemcp-figma-bridge/quickstart.md

Manual end-to-end validation scenarios

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • The Figma MCP server brings Figma design context directly into your AI workflow.

  • Connect AI coding agents to Anima Playground, Figma, and your design system.

  • Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/w4ndaja/figma-plugin-as-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server