Skip to main content
Glama
TranHoaiHung

figma-ui-mcp

by TranHoaiHung

figma-ui-mcp

Bidirectional Figma MCP bridge — let AI assistants (Claude Code, Cursor, Windsurf, Antigravity, VS Code Copilot, or any MCP-compatible IDE) draw UI directly on Figma canvas and read existing designs back as structured data, screenshots, or code-ready tokens. No Figma API key needed — works entirely over localhost.

Requires Figma Desktop — the plugin communicates with the MCP server over localhost HTTP polling. Figma's web app does not allow localhost network access, so Figma Desktop is required.

Claude ──figma_write──▶ MCP Server ──HTTP (localhost:38451)──▶ Figma Plugin ──▶ Figma Document
Claude ◀─figma_read──── MCP Server ◀──HTTP (localhost:38451)── Figma Plugin ◀── Figma Document

How the localhost bridge works

The MCP server starts a small HTTP server bound to localhost:38451. The Figma plugin (running inside Figma Desktop) uses long polling — the server holds requests up to 8s until work arrives, flushing immediately when new ops are queued (near-realtime latency <100ms). All traffic stays on your machine — nothing is sent to any external server.

Multi-instance support (v2.3.0+): Multiple Figma files/tabs can connect simultaneously. Each plugin instance sends a sessionId, and the bridge routes operations to the correct session. Use the optional sessionId param in figma_write/figma_read to target a specific file.


Features

Direction

Tool

What it does

Write

figma_write

Draw frames, shapes, text, prototypes via JS code

Read

figma_read

Extract node trees, colors, typography, screenshots

Info

figma_status

Check plugin connection + active sessions

Docs

figma_docs

Get full API reference + examples

Rules

figma_rules

Generate design system rule sheet — tokens, typography, components

What's new in v2.5

Feature

Description

get_design_context

AI-optimized payload for a node — flex layout, token-resolved colors (var(--name)), typography with style names, component instances with variant properties. Best single call for design→React/Vue/Swift code.

get_component_map

List every component instance in a frame with componentSetName, variantLabel, properties, and suggestedImport path. Scaffold import statements in one call.

get_unmapped_components

Find component instances that have no description in Figma (no code mapping yet). Prompts AI to ask user for correct import paths.

figma_rules tool

New top-level MCP tool — aggregates color tokens, typography styles, variables (all modes), and component catalog into a single markdown rule sheet. Equivalent to official Figma MCP's create_design_system_rules. Call once at session start.

get_css operation

figma_read get_css { nodeId } → ready-to-use CSS string (flex, typography, fill, border, shadow, opacity, transform). One call, paste into code.

Resolved variables

get_node_detail now resolves boundVariables IDs → { name, resolvedType, value }. No more manual ID lookup.

Resolved style refs

fillStyleId / textStyleId now include fillStyle: { name, hex } and textStyle: { name, fontSize, fontFamily }.

Instance overrides detail

overrides: [{ id, overriddenFields: ["fills","characters",...] }] — full diff vs mainComponent, not just count.

componentSetName + variantLabel

INSTANCE nodes now expose set name ("Button") and variant label ("State=Primary, Size=Large") separately.

insertIndex for create

figma.create({ ..., insertIndex: 2 }) — insert node at exact position in parent, not always at end.

Typography tokens

setupDesignTokens({ fontSizes, fonts, textStyles }) — 1 call bootstrap full typography system with variable-bound text styles. Multi-mode (Compact/Comfortable/Large) supported.

applyTextStyle

Apply a local text style to a TEXT node by name in 1 call — auto-loads font.

STRING variables for fonts

applyVariable now binds fontFamily, fontStyle, characters (swap Inter → SF Pro via 1 variable).

Effects

effects: [{ type: "DROP_SHADOW" | "INNER_SHADOW" | "LAYER_BLUR" | "BACKGROUND_BLUR", ... }] on any node.

Gradient fills

fill: { type: "LINEAR_GRADIENT" | "RADIAL_GRADIENT", angle, stops } in create/modify.

Individual corner radii

topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius on FRAME/RECT.

8-digit hex + rgba alpha

fill: "#FFFFFF80" or "rgba(255,255,255,0.5)" — alpha auto-applied to paint opacity.

SVG arc (A) + commas

VECTOR d paths accept A arc command (auto-converted to cubic Bézier) and commas.

Icon libraries

7 free open-source libraries, iOS-filled first: Ionicons → Fluent → Bootstrap → Phosphor → Tabler Filled → Tabler Outline → Lucide.

Instance overrides

figma.instantiate({ overrides: { "LayerName": { text, fill, fontSize } } }) — override props per-layer.

Batch delete

figma.delete({ ids: [...] }) — delete multiple nodes in 1 round-trip.

Prototyping

setReactions — click/hover/press → navigate/overlay/swap with Smart Animate.

Scroll behavior

setScrollBehavior — HORIZONTAL / VERTICAL / BOTH overflow.

Variants & instance swap

setComponentProperties / swapComponent — variants + instance swap.

Component property definitions (v2.5.24)

addComponentProperty + bindComponentProperty — create TEXT / BOOLEAN / INSTANCE_SWAP properties on master components. Instance text overrides now actually re-measure auto-layout (button grows to fit longer label).

Multi-instance

Multiple Figma tabs connect simultaneously via sessions.

Full version history: see CHANGELOG.md.


Related MCP server: Figbridge

Quick Start

Step 1 — Add the MCP server to your AI client

Choose your platform:

# Project scope (default)
claude mcp add figma-ui-mcp -- npx figma-ui-mcp

# Global scope (all projects)
claude mcp add --scope user figma-ui-mcp -- npx figma-ui-mcp

Edit config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "figma": {
      "command": "npx",
      "args": ["-y", "figma-ui-mcp"]
    }
  }
}

Edit .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):

{
  "mcpServers": {
    "figma": {
      "command": "npx",
      "args": ["-y", "figma-ui-mcp"]
    }
  }
}

Edit .vscode/mcp.json (project) or add to settings.json (global):

{
  "mcp": {
    "servers": {
      "figma": {
        "command": "npx",
        "args": ["-y", "figma-ui-mcp"]
      }
    }
  }
}

Edit ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "figma": {
      "command": "npx",
      "args": ["-y", "figma-ui-mcp"]
    }
  }
}
  1. Open "..." dropdown at the top of the agent panel

  2. Click "Manage MCP Servers""View raw config"

  3. Add to mcp_config.json:

{
  "mcpServers": {
    "figma": {
      "command": "npx",
      "args": ["-y", "figma-ui-mcp"]
    }
  }
}
git clone https://github.com/TranHoaiHung/figma-ui-mcp
cd figma-ui-mcp
npm install
# Then point your MCP client to: node /path/to/figma-ui-mcp/server/index.js

⚠️ IMPORTANT: After adding the MCP server, you MUST restart your IDE / AI client (quit and reopen). The MCP server only loads on startup — simply saving the config file is not enough. This applies to Claude Code, Cursor, VS Code, Windsurf, and Antigravity.

Step 2 — Install the Figma plugin

⬇ Download plugin.zip — no git clone needed

  1. Download and unzip plugin.zip anywhere on your machine

  2. Open Figma Desktop (required — web app cannot access localhost)

  3. Go to Plugins → Development → Import plugin from manifest...

  4. Select manifest.json from the unzipped folder

  5. Run Plugins → Development → Figma UI MCP Bridge

The plugin UI shows a green dot when the MCP server is connected.

Updating to a newer version

# Step 1 — get the new version + plugin path
npx figma-ui-mcp@latest --version
# figma-ui-mcp v2.5.12  —  plugin: /.../.npm/_npx/.../figma-ui-mcp/plugin

# Step 2 — restart Claude / your IDE so the MCP server reloads

# Step 3 — re-link the Figma plugin (manual, one-time per update)
#   Figma Desktop → Plugins → Development → Manage plugins in development
#   Remove old "Figma UI MCP Bridge" → "+" → Import plugin from manifest...
#   Select manifest.json from the plugin path printed in Step 1

# Step 4 — verify
#   Ask your AI: "figma_status"
#   pluginVersion in the response should match the npm version above

The Figma plugin does not auto-update — re-linking (Step 3) is required whenever the plugin changes.

Step 3 — Connect AI to Figma

Tell your AI assistant to connect:

"Connect to figma-ui-mcp"

The AI will call figma_status and confirm:

✅ Connected — File: "My Project", Page: "Page 1", Plugin v2.5.5

If you see "Plugin not connected", make sure the Figma plugin is running (Step 2).

Step 4 — Start designing with prompts

Once connected, just describe what you want in natural language:

"Use figma-ui-mcp to draw a login screen for mobile"

The AI will automatically:

  1. Call figma_docs to load the API reference and design rules

  2. Call figma_read get_page_nodes to understand the current canvas

  3. Call figma_write to create the design on your Figma canvas

  4. Call figma_read screenshot to verify the result

Prompt examples

Prompt

What happens

"Draw a mobile login screen with social login buttons"

Creates a 390×844 frame with email/password inputs, Apple/Google buttons

"Read the selected frame and describe the design"

Extracts colors, typography, spacing from your selection

"Take a screenshot of the current frame"

Returns an inline image the AI can analyze

"Create a dark theme dashboard with KPI cards"

Draws a full dashboard layout with charts and stats

"Design an e-commerce product card"

Creates a product card with image, price, rating, CTA

"Draw a settings page with toggle switches"

Creates grouped settings with icons and toggles

Tips for better results

  • Be specific about style: "dark theme", "glassmorphism", "minimal white" gives the AI clear direction

  • Mention platform: "mobile" (390×844), "tablet" (768×1024), "desktop" (1440×900)

  • Iterate: After the first draw, say "fix the spacing" or "make the buttons bigger" — the AI reads and modifies existing nodes

  • Use selection: Select a frame in Figma and ask "improve this design" — the AI reads your selection first

  • Multi-screen flows: "Now draw the signup screen next to the login screen" — the AI positions frames side by side

Workflow summary

You: "Connect to figma-ui-mcp"
AI:  ✅ Connected to Figma

You: "Draw a mobile onboarding screen with 3 steps"
AI:  [calls figma_docs → figma_write → figma_read screenshot]
AI:  ✅ Done — here's what I created: [inline screenshot]

You: "The title text is not centered"
AI:  [calls figma_read get_selection → figma_write modify → screenshot]
AI:  ✅ Fixed — text is now centered

You: "Now draw the next onboarding screen beside it"
AI:  [reads page_nodes to find position → draws at x+440]
AI:  ✅ Done — 2 screens side by side
figma_status     — check connection (always call first)
figma_docs       — load API reference (call before drawing)
figma_write      — draw / modify UI on canvas
figma_read       — extract design data, screenshots, SVG

Usage Examples

Draw a screen

Ask Claude: "Draw a dark dashboard with a sidebar, header, and 4 KPI cards"

Claude calls figma_write with code like:

await figma.createPage({ name: "Dashboard" });
await figma.setPage({ name: "Dashboard" });

const root = await figma.create({
  type: "FRAME", name: "Dashboard",
  x: 0, y: 0, width: 1440, height: 900,
  fill: "#0f172a",
});

const sidebar = await figma.create({
  type: "FRAME", name: "Sidebar",
  parentId: root.id,
  x: 0, y: 0, width: 240, height: 900,
  fill: "#1e293b", stroke: "#334155", strokeWeight: 1,
});

await figma.create({
  type: "TEXT", name: "App Name",
  parentId: sidebar.id,
  x: 20, y: 24, content: "My App",
  fontSize: 16, fontWeight: "SemiBold", fill: "#f8fafc",
});
// ... continue

Read a design

Ask Claude: "Read my selected frame and convert it to Tailwind CSS"

Claude calls figma_read with operation: "get_selection", receives the full node tree, then generates corresponding code.

Screenshot a frame

figma_read  →  operation: "screenshot"  →  nodeId: "123:456"

Returns a base64 PNG Claude can analyze and describe.


Architecture

figma-ui-mcp/
├── server/
│   ├── index.js            MCP server (stdio transport)
│   ├── bridge-server.js    HTTP bridge on localhost:38451 (long-poll, multi-session)
│   ├── code-executor.js    VM sandbox — safe JS execution + 7-lib icon fetcher
│   ├── tool-definitions.js MCP tool schemas (figma_status / _write / _read / _docs)
│   └── api-docs.js         API reference text (served to AI via figma_docs)
├── src/plugin/             Plugin source (concat-built into plugin/code.js)
│   ├── utils.js, svg-path-helpers.js, paint-and-effects.js, read-helpers.js
│   ├── handlers-write.js, handlers-read.js, handlers-read-detail.js,
│   │   handlers-library.js, handlers-tokens.js, handlers-write-ops.js
│   └── main.js
└── plugin/
    ├── manifest.json       Figma plugin manifest
    ├── code.js             Plugin main (auto-generated — 3600+ LOC)
    └── ui.html             Plugin UI — long-poll client + status dot

Security

Layer

Protection

VM sandbox

vm.runInContext() — blocks require, process, fs, fetch

Localhost only

Bridge binds localhost:38451, never exposed to network

Operation allowlist

56 predefined operations accepted (WRITE_OPS + READ_OPS)

Timeout

30s VM execution + 60-90s per plugin operation (adaptive by op type)

Body size limit

5 MB max per request

Session isolation

Multi-instance sessions scoped by Figma file ID


Available Write Operations (figma_write)

Core CRUD

Operation

Description

figma.create({ type, ... })

Create FRAME / RECTANGLE / ELLIPSE / LINE / TEXT / SVG / VECTOR / IMAGE

figma.modify({ id, ... })

Update node properties (fill, size, text, layout, etc.)

figma.delete({ id })

Remove a single node

figma.delete({ ids: [...] })

Batch delete multiple nodes in one call

figma.query({ type?, name?, id? })

Find nodes by type, name, or ID

figma.append({ parentId, childId })

Move node into parent

create / modify — advanced props available on any node:

Prop

Example

Notes

fill (solid)

"#6C5CE7" or "#6C5CE780" (8-digit hex with alpha) or "rgba(108,92,231,0.5)"

Alpha auto-extracted into paint opacity

fill (gradient)

{ type: "LINEAR_GRADIENT", angle: 135, stops: [{ pos: 0, color: "#7C3AED" }, { pos: 1, color: "#EC4899" }] }

Also RADIAL_GRADIENT

stroke, strokeWeight, strokeOpacity

Same hex/rgba rules

cornerRadius uniform

12

All 4 corners

Individual corners

topLeftRadius: 20, topRightRadius: 20, bottomLeftRadius: 0, bottomRightRadius: 0

Rounded top sheet pattern

effects array

[{ type: "DROP_SHADOW", color: "#00000026", offset: {x:0,y:8}, radius: 24, spread: 0 }]

Types: DROP_SHADOW, INNER_SHADOW, LAYER_BLUR, BACKGROUND_BLUR

TEXT center

textAlign: "CENTER" with explicit width

Auto-infers textAutoResize: "NONE" so centering works

VECTOR path

d: "M 150 7 A 143 143 0 1 1 29.26 226.62"

SVG A arc auto-converted to cubic Bézier; commas accepted

Page Management

Operation

Description

figma.status()

Current Figma context info

figma.listPages()

List all pages

figma.setPage({ name })

Switch active page

figma.createPage({ name })

Add a new page

Node Operations

Operation

Description

figma.clone({ id, x?, y?, parentId? })

Duplicate a node with optional repositioning

figma.group({ nodeIds, name? })

Group multiple nodes

figma.ungroup({ id })

Ungroup a GROUP/FRAME

figma.flatten({ id })

Flatten/merge vectors into single path

figma.resize({ id, width, height })

Resize any node

figma.set_selection({ ids })

Programmatically select nodes

figma.set_viewport({ nodeId?, x?, y?, zoom? })

Navigate viewport

figma.batch({ operations })

Execute up to 50 ops in one call (10-25x faster)

Components

Operation

Description

figma.listComponents()

List all components in document

figma.createComponent({ nodeId, name? })

Convert FRAME/GROUP → reusable Component

figma.instantiate({ componentId/Name, parentId, x, y })

Create component instance

figma.instantiate({ ..., overrides: { "LayerName": { text, fill, fontSize, visible, ... } } })

Instantiate with per-layer overrides

Design Tokens & Styles

Operation

Description

figma.setupDesignTokens({ colors, numbers, fontSizes, fonts, textStyles, modes })

Bootstrap complete token system (idempotent) — colors + spacing + typography + text styles + multi-mode in 1 call

figma.createVariableCollection({ name })

Create variable collection ("Colors", "Spacing")

figma.createVariable({ name, collectionId, resolvedType, value })

Create COLOR/FLOAT/STRING/BOOLEAN variable

figma.addVariableMode({ collectionId, modeName })

Add mode (e.g. "dark", "compact")

figma.renameVariableMode({ collectionId, modeId, newName })

Rename a mode

figma.removeVariableMode({ collectionId, modeId })

Remove a mode

figma.setVariableValue({ variableId/Name, modeId/Name, value })

Set per-mode value

figma.modifyVariable({ variableName, value })

Change variable value — all bound nodes update

figma.applyVariable({ nodeId, field, variableId/Name })

Bind variable to a node property

figma.applyTextStyle({ nodeId, styleName })

Apply a local text style to a TEXT node by name (auto-loads font)

figma.setFrameVariableMode({ nodeId, collectionId, modeName })

Pin frame to a variable mode (Light/Dark, Compact/Large)

figma.clearFrameVariableMode({ nodeId, collectionId })

Reset frame to document default mode

figma.createPaintStyle({ name, color })

Create reusable paint style

figma.createTextStyle({ name, fontFamily, fontSize, ... })

Create reusable text style (manual — prefer setupDesignTokens.textStyles)

figma.ensure_library()

Create/get Design Library frame

figma.get_library_tokens()

Read library color + text tokens

applyVariable supported fields — bind FLOAT/COLOR/STRING/BOOLEAN variables to:

  • Color: fill, stroke

  • Geometry: opacity, width, height, strokeWeight

  • Corner radius: cornerRadius + individual topLeftRadius / topRightRadius / bottomLeftRadius / bottomRightRadius

  • Spacing (auto-layout): paddingTop, paddingBottom, paddingLeft, paddingRight, itemSpacing, counterAxisSpacing

  • Typography (TEXT nodes): fontSize, letterSpacing, lineHeight, paragraphSpacing, paragraphIndent

  • Font swap (STRING): fontFamily, fontStyle, characters — swap Inter → SF Pro via 1 variable

  • Visibility (BOOLEAN): visible

Image & Icon Helpers (server-side)

Operation

Description

figma.loadImage(url, opts)

Download image → place on canvas

figma.loadIcon(name, opts)

Fetch SVG icon with 7-library fallback (iOS-filled first)

figma.loadIconIn(name, opts)

Icon inside centered circle background

loadIcon fallback priority (filled-first, iOS style preferred): Ionicons (iOS filled) → Fluent UI (Win11 filled) → Bootstrap (filled) → Phosphor (filled) → Tabler Filled (4,500+) → Tabler OutlineLucide (outline fallback)

Free replacement for paid Icons8 ios-filled. Ionicons naming quirks: Bell→notifications, Back→chevron-back, Clock→time, Fire→flame, Lightning→flash, Lock→lock-closed.

Prototyping & Interactions

Operation

Description

figma.setReactions({ id, reactions })

Add prototype interactions (ON_CLICK/ON_HOVER/ON_PRESS → NAVIGATE/OVERLAY/SWAP)

figma.getReactions({ id })

Read all prototype interactions from a node

figma.removeReactions({ id })

Clear all interactions from a node

Supported transitions: SMART_ANIMATE, DISSOLVE, MOVE_IN, MOVE_OUT, PUSH, SLIDE_IN, SLIDE_OUT, INSTANT Supported easings: LINEAR, EASE_IN, EASE_OUT, EASE_IN_AND_OUT, CUSTOM_BEZIER

Scroll Behavior

Operation

Description

figma.setScrollBehavior({ id, overflowDirection })

Set overflow scrolling: NONE / HORIZONTAL / VERTICAL / BOTH

Variant & Component Swapping

Operation

Description

figma.setComponentProperties({ id, properties })

Set variant, boolean, text, or instance swap properties on an INSTANCE

figma.swapComponent({ id, componentId })

Swap the main component of an instance

figma.getComponentProperties({ id })

Read all properties + definitions from component/instance

Available Read Operations (figma_read)

Operation

Description

get_selection

Full design tree of selected node(s) + design tokens

get_design

Full node tree for a frame/page (depth param: default 10, or "full")

get_page_nodes

Top-level frames on the current page

screenshot

Export node as PNG — displays inline in Claude Code

export_svg

Export node as SVG markup

export_image

Export node as base64 PNG/JPG — for saving to disk (format, scale params)

get_design_context

AI-optimized design→code payload — flex layout, token-resolved fills as var(--name), typography with style names, component instances with variant properties + componentsUsed / tokensUsed summaries. Best single call for generating React/Vue/Swift code.

get_component_map

Component instance map — every INSTANCE in a frame with componentSetName, variantLabel, properties, and suggestedImport path. Deduplicates into uniqueComponents[] with usage counts.

get_unmapped_components

Code-mapping audit — lists instances with no description in Figma (unmapped[]). Use to prompt user for correct import paths before code generation.

get_node_detail

Structured properties for single node — fills, layout, typography, effects, bound variables (resolved to name+value), style refs (resolved to name+hex), instance overrides (full field list), componentSetName + variantLabel

get_css

Ready-to-use CSS string for a node — background, flex, border, radius, shadow, typography, opacity, transform. Best for design-to-code.

get_styles

All local paint, text, effect, grid styles

get_local_components

Component listing with descriptions + variant properties

get_viewport

Current viewport position, zoom, bounds

get_variables

Local variables (Design Tokens) — collections, modes, values

search_nodes

Find nodes by type, name, fill color, font, size — supports includeHidden

scan_design

Progressive scan for large files — all text, colors, fonts, images, icons

includeHidden param (boolean, default false) — available on get_selection, get_design, search_nodes, scan_design. When false (default), nodes with visible: false are skipped. Pass true to include hidden layers.


Working with an Existing Project

When opening a Figma file that already has a design system, always read before drawing.

Step 1 — Read what exists

figma_read get_variables      → load variable IDs (Design Tokens)
figma_read get_styles         → load paint/text style IDs and hex values
figma_read get_local_components → load component IDs
figma_read get_page_nodes     → load top-level frame IDs

Step 2 — Build lookup maps in figma_write

// Load variables → build varMap: name → id
var vars = await figma.get_variables();
var varMap = {};
for (var ci = 0; ci < vars.collections.length; ci++) {
  var col = vars.collections[ci];
  for (var vi = 0; vi < col.variables.length; vi++) {
    var v = col.variables[vi];
    varMap[v.name] = v.id;
  }
}

// Load styles → build colorMap: name → hex, textMap: name → {fontSize, fontWeight}
var styles = await figma.get_styles();
var colorMap = {}, textMap = {};
styles.paintStyles.forEach(function(s) { colorMap[s.name] = s.hex; });
styles.textStyles.forEach(function(s)  { textMap[s.name]  = s; });

// Load components → build compMap: name → id
var comps = await figma.get_local_components();
var compMap = {};
comps.components.forEach(function(c) { compMap[c.name] = c.id; });

Step 3 — Create nodes using discovered values

// Use colorMap for fill (hex from existing styles)
var card = await figma.create({
  type: "FRAME", name: "Card",
  fill: colorMap["color/bg-surface"] || "#FFFFFF",
  width: 360, height: 200,
  layoutMode: "VERTICAL", paddingTop: 16, paddingLeft: 16,
  paddingBottom: 16, paddingRight: 16, itemSpacing: 12,
});

// Then bind variables so light/dark mode switches propagate
if (varMap["bg-surface"])
  await figma.applyVariable({ nodeId: card.id, field: "fill",        variableId: varMap["bg-surface"] });
if (varMap["radius-md"])
  await figma.applyVariable({ nodeId: card.id, field: "cornerRadius",variableId: varMap["radius-md"] });
if (varMap["spacing-md"])
  await figma.applyVariable({ nodeId: card.id, field: "paddingTop",  variableId: varMap["spacing-md"] });

Step 4 — Instantiate components with overrides

// Prefer existing components over drawing from scratch
if (compMap["btn/primary"]) {
  await figma.instantiate({
    componentId: compMap["btn/primary"],
    parentId: card.id,
    overrides: { "Label": { text: "Confirm", fill: "#FFFFFF" } }
  });
}

Step 5 — Pin frames to Light / Dark mode

var collection = vars.collections.find(function(c) { return c.name === "Design Tokens"; });

// Duplicate frame and preview both modes side by side
var frames = await figma.get_page_nodes();
var homeId  = frames.find(function(f) { return f.name === "Home"; }).id;
var light   = await figma.clone({ id: homeId, x: 0,    name: "Preview/Light" });
var dark    = await figma.clone({ id: homeId, x: 1540, name: "Preview/Dark"  });
await figma.setFrameVariableMode({ nodeId: light.id, collectionId: collection.id, modeName: "light" });
await figma.setFrameVariableMode({ nodeId: dark.id,  collectionId: collection.id, modeName: "dark"  });

Full API reference and all design rules: run figma_docs in your AI client.


Star History

If figma-ui-mcp helps you, please give it a star — it helps others discover the project!

GitHub stars

Star History Chart


License

License: MIT

MIT © TranHoaiHung — free to use, modify, and distribute. See LICENSE for details.


Keywords

figma mcp, claude code to figma, cursor to figma, ai to figma, figma ai plugin, figma mcp bridge, figma mcp server, figma design to code, code to figma design, ai ui design, figma automation, figma plugin ai, model context protocol figma, claude figma, windsurf figma, vs code figma, antigravity figma, ai design tool, figma api alternative, figma localhost plugin, draw ui with ai, ai generate figma design, figma design system ai, mcp server figma, figma read design, figma write design, bidirectional figma, figma desktop plugin, npx figma-ui-mcp

Available Tools

5 tools
figma_docsA

Get the API reference and design rules for figma_write. Call with no args first — returns quick-start guide + critical rules. Then load specific sections as needed: section='rules' (design principles, token rules, layer order, component-first), section='layout' (auto-layout, button/card/badge/progress/mobile rules), section='api' (create/modify/delete/clone/batch/read operations + workflow), section='tokens' (variables, multi-mode, paint styles, text styles), section='icons' (loadImage, loadIcon, loadIconIn, icon libraries, coloring, sizing). Always call figma_docs BEFORE any figma_write code.

ParametersJSON Schema
NameRequiredDescriptionDefault
sectionNoWhich section to load. Omit (or null) for quick-start + critical rules. Load layout before any auto-layout work. Load api for full operation reference. Load tokens for variable/multi-mode work. Load icons for image/icon placement.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations; description covers tool behavior (returns docs, read-only nature assumed). Missing explicit statement of no side effects, but clear for a documentation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with main purpose, structured with bullet-like list. Slightly long but well-organized and clear.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a docs retrieval tool: explains purpose, usage, parameter options, and integrates guidance. No output schema needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema has 100% coverage with enum and description; description adds rich context for each section value, e.g., what 'rules' contains.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states it returns API reference and design rules for figma_write, distinguishes from sibling tools (figma_read, figma_write) by being a documentation tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs to call before any figma_write code, advises to call with no args first, then specific sections, and provides context for each section's usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

figma_readA

READ design data from Figma — extract node trees, colors, typography, spacing, and screenshots. Use to understand an existing design before generating code, or to inspect what's on the canvas.

ParametersJSON Schema
NameRequiredDescriptionDefault
depthNoTree depth for get_design/get_selection. Number (default 10) or 'full' for unlimited. Higher = more detail but larger output.
scaleNoExport scale for screenshot (default 1).
detailNoDetail level for get_design/get_selection: 'minimal' (~5% tokens), 'compact' (~30%), 'full' (default, 100%). Use minimal for large files.
formatNoImage format for export_image: 'png' (default) or 'jpg'.
nodeIdNoTarget node ID (optional — omit to use current selection).
nodeNameNoTarget node name (alternative to nodeId).
operationYes── Design-to-code (use these for code generation) ── get_design_context: AI-optimized payload for a node — flex layout, token-resolved colors, typography with style names, component instances with variant properties. Best single call for design→React/Vue/Swift code. get_css: ready-to-use CSS string for a single node — background, flex, border, radius, shadow, typography, opacity, transform. get_component_map: list every component instance in a frame with componentSetName, variantLabel, properties, and suggestedImport path. Use to scaffold import statements. get_unmapped_components: find component instances that have no description in Figma (likely no code mapping yet). Prompts AI to ask user for correct import paths. ── Inspect ── get_node_detail: structured properties for a single node — fills, bound variables (resolved to name+value), style refs (resolved to name+hex), instance overrides (full field list), componentSetName/variantLabel. get_selection: full design tree of selected node(s) + design tokens summary. get_design: full node tree for a frame/page (depth param: number or 'full'). get_page_nodes: top-level frames on the current page. ── Styles & tokens ── get_styles: all local paint, text, effect, grid styles. get_variables: all local Design Token variables — collections, modes, resolved values. get_local_components: component listing with descriptions + variant property definitions. ── Export ── screenshot: PNG of a node — displays inline in Claude Code. export_svg: SVG markup string. export_image: base64 PNG/JPG for saving to disk (scale param for resolution). ── Search ── search_nodes: filter by type, namePattern (wildcard *), fill color, fontFamily, fontSize, hasImage, hasIcon. scan_design: structured summary of large frames — all text, colors, fonts, images, icons, sections. ── Viewport ── get_viewport: current viewport center, zoom, bounds.
sessionIdNoTarget a specific Figma file/tab when multiple are connected. Omit to auto-select.
includeHiddenNoInclude invisible nodes (visible:false) in results. Default false — hidden layers are skipped to reduce noise.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry full burden. It states it reads data but does not disclose specific behaviors such as rate limits, authentication requirements, or side effects. The operation parameter's enum descriptions provide some behavioral context per sub-operation, but the main description is insufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise with two sentences, no wasted words. Front-loads the action ('READ design data'). Could benefit from bullet points or structure, but remains efficient and readable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (9 parameters, 17 operations, no output schema), the description is incomplete. It doesn't explain return values or output format. The operation enum fills some gaps, but the main description could provide a high-level overview of what to expect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3. The main description does not add meaning beyond the schema descriptions. The operation parameter has extensive inline descriptions, but that is part of the schema. The description adds marginal value over structured fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reads design data from Figma and lists specific extractable elements (node trees, colors, etc.). It distinguishes itself from sibling tools like figma_write (write operations) and figma_docs (documentation).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear usage context: 'understand an existing design before generating code, or to inspect what's on the canvas.' It doesn't explicitly state when not to use, but the sibling tools cover other cases, making the intent clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

figma_rulesA

Generate a design system rule sheet from the current Figma file — aggregates color tokens, typography styles, variables (all modes), and component catalog into a single markdown block. Equivalent to official Figma MCP's create_design_system_rules. Call once at the start of a design-to-code session to give the AI full context: what tokens to use, what text styles exist, which components are available. Re-run when the design system changes.

ParametersJSON Schema
NameRequiredDescriptionDefault
sessionIdNoTarget a specific Figma file/tab. Omit to auto-select.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It clearly describes the tool as aggregating multiple design elements into a markdown block without side effects, implying read-only. It could add details about authentication or performance, but the behavior is well communicated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is roughly 80 words, front-loaded with the primary action, then content details and usage guidance. Every sentence adds value with no fluff, achieving excellent conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description fully explains the output format (single markdown block) and contents (tokens, styles, variables, components). It provides complete context for when and why to use the tool, making it self-sufficient for an AI agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Input schema has 100% description coverage with a single optional sessionId parameter. The description does not add any additional meaning beyond what the schema already provides, maintaining baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool generates a design system rule sheet aggregating color tokens, typography styles, variables, and component catalog into markdown. It uses specific verb 'generate' and resource, and distinguishes indirectly by mentioning equivalence to official MCP and usage context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to call: 'once at the start of a design-to-code session' and 're-run when the design system changes.' It also explains what context it provides. However, it does not explicitly exclude use cases where sibling tools like figma_read might be more appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

figma_statusA

Check whether the Figma plugin bridge is connected. Always call this first to confirm the plugin is running before any other tool.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description clearly states the tool's function (checking connection) and its prerequisite role, with no hidden side effects or ambiguity. No annotations are present, so the description fully bears the transparency burden and meets it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short, front-loaded sentences that convey the entire purpose and usage without any wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has zero parameters, no output schema, and a simple checking function, the description completely informs the agent about when and how to use the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has no parameters, so there is nothing to describe. The description correctly omits any unnecessary parameter information, achieving 100% coverage by default.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the tool checks the Figma plugin bridge connection, distinguishing it from sibling tools (read, write, docs, rules) which perform different operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear guidance: 'Always call this first to confirm the plugin is running before any other tool,' indicating the exact context and order of use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

figma_writeA

Execute JavaScript code to CREATE or MODIFY designs in Figma. ⚠️ MANDATORY: Call figma_docs BEFORE writing any design code. Skipping figma_docs causes hardcoded colors, wrong sizing, broken layouts, and low-quality UI. Use the figma proxy object — all methods return Promises, use async/await. Operations: create, modify, delete, clone, group, ungroup, flatten, resize, set_selection, set_viewport, batch (multiple ops in one call). Design Tokens: createVariableCollection, createVariable, setVariableValue, addVariableMode, renameVariableMode, removeVariableMode, applyVariable, setFrameVariableMode, clearFrameVariableMode, createPaintStyle, createTextStyle, createComponent. Prototyping: setReactions, getReactions, removeReactions (click/hover/press → navigate/overlay/swap with Smart Animate transitions). Scroll: setScrollBehavior (overflowDirection: NONE/HORIZONTAL/VERTICAL/BOTH). Variants: setComponentProperties, swapComponent, getComponentProperties. Component property definitions (master-side, required for instance text overrides to recalc auto-layout): addComponentProperty (TEXT/BOOLEAN/INSTANCE_SWAP), bindComponentPropertyToText, removeComponentProperty. The code runs in a sandboxed VM: no access to require, process, fs, fetch, or network.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesJavaScript using figma.create(), figma.modify(), figma.setPage(), etc.
sessionIdNoTarget a specific Figma file/tab when multiple are connected. Omit to auto-select.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It details sandbox restrictions (no require, process, fs, fetch, network), async/await usage, and a wide range of supported operations (create, modify, delete, etc.). However, it does not explicitly state that the tool modifies files (though implied), nor does it mention authentication or rate limits, but the transparency is high.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is lengthy but well-structured with sections (operations, design tokens, prototyping, etc.) and bullet points. The most critical information (purpose and mandatory figma_docs call) is front-loaded. Every sentence adds value, though it could be slightly more concise without losing clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity and the absence of an output schema, the description provides extensive context about capabilities, sandboxing, and prerequisites. It covers a wide range of operations. However, it does not explain return values or error handling, but for a mutation tool with no output schema, the description is sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The description adds valuable context beyond the schema, such as explaining the use of the 'figma' proxy object, async/await, and the mandatory figma_docs call. This helps agents understand how to use the parameters effectively.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Execute JavaScript code to CREATE or MODIFY designs in Figma,' providing a specific verb and resource. It distinguishes itself from sibling tools (figma_docs, figma_read, etc.) by emphasizing that this tool performs write operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description includes an explicit mandatory instruction: 'Call figma_docs BEFORE writing any design code' and explains consequences of skipping that step. This provides clear when-to-use and when-not-to-use guidance, and implies that figma_docs is a prerequisite.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 5 tool updatesv2.5.26
    • First observedfigma_docs
    • First observedfigma_read
    • First observedfigma_rules
    • First observedfigma_status
    • First observedfigma_write

TDQS

A4.4/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: documentation retrieval, reading design data, generating rule sheets, checking connection status, and executing write operations. The slight overlap between figma_docs and figma_rules is mitigated by their different scopes (general reference vs. file-specific aggregation), so no ambiguity exists.

Naming Consistency5/5

All tools follow a consistent 'figma_verb' pattern (docs, read, rules, status, write). The verbs are clear and indicative of each tool's function, making the set predictable and easy to understand.

Tool Count5/5

With 5 tools, the server covers the essential operations for Figma interaction (status, read, write, documentation, rule generation) without unnecessary bloat. The count is well-scoped and each tool earns its place.

Completeness4/5

The tool set covers the primary use cases: reading design data, writing/modifying designs via code, generating design rules, checking connection, and accessing documentation. While the write tool is extremely versatile, dedicated tools for specific operations like deleting or listing components are missing, but the JavaScript execution fills that gap. Minor gaps remain for very specialized tasks.

Maintenance

ActivityInactive
ResponsivenessWithin a week

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Bridges Figma and code for AI agents, enabling reading design data, importing live URLs into Figma, auditing designs, and generating source patches via 48 MCP tools.
    11
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to read and write Figma designs through a local WebSocket relay, turning Figma selections into framework-aware code and building/editing designs directly on the canvas. Provides 112 MCP tools for bidirectional design-code workflows with support for any MCP client.
    MIT
  • A
    license
    B
    quality
    A
    maintenance
    A local MCP server that lets AI assistants inspect, create, and update designs in Figma Desktop through a development plugin, requiring no Figma Personal Access Token or cloud services.
    12
    376
    1
    MIT

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/TranHoaiHung/figma-ui-mcp'

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