Documentation
Everything you need to get started with Figma Unified MCP and the Unified Design CLI. From setup to tool reference to real-world recipes.
What is Figma Unified MCP
Figma Unified MCP is an open-source MCP (Model Context Protocol) server that connects AI agents directly to your Figma files. It exposes 100+ tools that let you read designs, create nodes, modify styles, manage variables, build prototypes, and generate production code, all through natural language.
Instead of manually clicking through Figma menus or learning the Figma API, you simply describe what you want. The MCP server translates your words into Figma actions.
How it connects
Your MCP client (Claude Desktop, VS Code, Cursor) connects to the MCP server via stdio. The server then communicates with Figma through two channels:
- Figma REST API for reading files, styles, components, variables, comments, and team libraries. No plugin needed.
- WebSocket + companion plugin for writing to the canvas: creating frames, shapes, text, prototyping, code generation, and more.
Think of it as giving your AI assistant a set of hands inside Figma. You talk, it designs. You describe, it builds. You ask questions, it inspects your files and answers.
What can it do?
- Read & inspect files, styles, components, variables, comments, team libraries, version history
- Create & build frames, shapes, text, components, instances, pages
- Modify & style fills, strokes, effects, auto-layout, constraints, typography
- Manage design tokens with variable collections, multi-mode values (light/dark), binding
- Build prototypes with interactions, flows, transitions, overlays, scroll behaviors
- Generate code as React, SwiftUI, HTML, CSS, Tailwind config, and developer handoff specs
What is Unified Design CLI
The Unified Design CLI (unified-design) is a standalone command-line tool that lets you interact with Figma directly from your terminal. It ships alongside the MCP server but works independently. No AI agent needed. Just you and your Figma files.
Setup
cd figma-unified-mcp
npm install
npm run build
npm link # makes 'unified-design' available globally
macOS / Linux: If unified-design isn't found after npm link, make sure npm's global bin is in your PATH:
export PATH="$(npm prefix -g)/bin:$PATH" # add to ~/.zshrc or ~/.bashrc
Windows (PowerShell 5.1): Use ; instead of && to chain commands. If blocked by execution policy, run unified-design.cmd or node dist/cli.js directly.
Authentication
# Option 1: Environment variable
export FIGMA_ACCESS_TOKEN=figd_xxx
# Option 2: Config file (~/.figmarc)
unified-design config set accessToken figd_xxx
# Option 3: Auto-discovery
# Reads from Claude Desktop / Cursor MCP config — no extra setup needed
Plugin Bridge — Coexisting with MCP Server
Canvas write commands (e.g. create-frame, set-fill) require the Figma plugin. The CLI automatically detects how to connect:
- MCP server running? → CLI connects as a client to the existing bridge (no port conflict)
- No server running? → CLI starts its own bridge and waits for the plugin
This means you can use the CLI alongside Claude Desktop / Cursor without stopping the MCP server.
Interactive REPL
Run unified-design with no arguments and you drop into an interactive shell. It shows your auth status, plugin connection, and default file at a glance. Tab completion and short aliases make it fast to navigate.
40+ commands across 10 categories
- Files — get-file, get-node, get-nodes, search, get-file-versions
- Styles & Variables — get-styles, get-components, get-variables, get-library-items-used
- Create — create-frame, create-rectangle, create-ellipse, create-text, create-component
- Modify — move-node, resize-node, set-fill, set-text, rename-node, delete-node, clone-node, set-opacity, set-visible, group-nodes, reparent-node
- Codegen — generate-css, generate-react, generate-html, generate-tokens
- Prototype — create-interaction, get-flows
- Variables (REST) — create-variable-collection, create-variable, set-variable-value, update-variable, delete-variable
- Export — get-images, screenshot, export-svg
- Audit — full design quality report (colors, fonts, spacing, naming, hidden layers, empty groups)
- Teams — get-team-components, get-team-styles, get-team-projects, get-project-files
Config management
Use unified-design config set accessToken figd_xxx to store your token in ~/.figmarc. Set a default file key so you never have to type --file-key again. The CLI also auto-discovers tokens from Claude Desktop, VS Code, and Cursor configs.
The MCP server is for AI agents. The CLI is for you. Same Figma access, same capabilities, but you're typing the commands instead of an AI. Useful for scripting, quick inspections, design audits, or just exploring your files without opening Figma.
Why I Built This
I'm a designer. I've never taken a computer science class. My entire career has been spent inside Figma, not inside a code editor.
Then AI happened. And something clicked.
I started using AI as a coding partner, and within weeks I had built five Figma plugins from scratch, including one that adds audio to Figma files. I built an Instagram DM agent and deployed it on a real server. None of this should have been possible for someone with my background. But it was.
So I kept going. I built a full MCP server that connects AI directly to Figma. It reads files, creates nodes, updates variables and styles, draws elements from prompts, generates code. 100+ tools. It runs on Mac and Windows. It works with Claude Desktop, Claude Code, and Cursor. I built all of it with AI as my partner.
People keep asking me: why build your own when other Figma MCPs exist?
Because I don't just want to use AI. I want to understand it. I want tools shaped around how designers actually think, not adapted from someone else's engineering workflow. Tools I can break apart, rebuild, and make my own.
That's what this project is. A designer's tool, built by a designer, for the way designers work.
No engineering team. No CS degree. Just AI and curiosity. If a designer with zero coding background can build an MCP server with 100+ tools, a CLI with 40+ commands, and a Figma plugin, you can absolutely use one. This project is MIT licensed and open source. Fork it, break it, make it yours.
Requirements
- Node.js 18+ to run the MCP server
- Figma Personal Access Token with read/write scopes
- MCP client such as Claude Desktop, VS Code + Copilot, Cursor, or any MCP-compatible client
- Figma companion plugin (optional) for canvas write operations
Installation
Auto setup (recommended)
The setup script installs dependencies, builds the server, and configures your MCP client automatically.
The script will prompt you for your Figma access token and preferred tool profile. It detects which clients are installed (Claude Desktop, VS Code, Cursor) and writes the config files automatically.
Manual setup
Then add the server to your MCP client config (see Configuration).
When is the plugin needed?
The companion plugin is required for canvas write operations (creating frames, shapes, text, prototyping, code generation, etc.). Read operations and variable CRUD work without it via the REST API.
Import the plugin
- Open Figma Desktop (the plugin requires the desktop app, not the browser)
- Go to Plugins → Development → Import plugin from manifest…
- Navigate to your cloned repo and select
figma-unified-mcp/figma-plugin/manifest.json - The plugin "Figma Unified MCP Bridge" will appear under Plugins → Development
Connect the plugin
- Make sure the MCP server is running first (it opens the WebSocket)
- Open the Figma file you want to work with
- Go to Plugins → Development → Figma Unified MCP Bridge
- Click Connect (default:
localhost:18211, channelfigma) - Status should show "Connected" ✅
The plugin connects per-file. If you switch to a different Figma file, you need to run the plugin again in that file. The server handles reconnection automatically.
Use figma_status to check if the plugin is connected. If it shows "disconnected", re-run the plugin in your active Figma file.
Build & link
The Unified Design CLI (unified-design) lets you interact with Figma from your terminal — no AI agent needed. First clone and build, then link globally:
macOS / Linux: If unified-design isn't found after npm link, add npm's global bin to your PATH:
export PATH="$(npm prefix -g)/bin:$PATH" # add to ~/.zshrc or ~/.bashrc
Windows: Use ; instead of && in PowerShell 5.1. If blocked by execution policy, run unified-design.cmd or node dist/cli.js directly.
Authentication
Quick start
See What is Unified Design CLI for the full command reference, REPL, and plugin bridge details.
Configuration
MCP client config
Add the following to your MCP client's config file:
Use an absolute path for the args value. Relative paths will fail because the client may not resolve them from the repo directory.
Environment variables
| Variable | Required | Description |
|---|---|---|
| FIGMA_ACCESS_TOKEN | Yes | Your Figma personal access token. Generate one at Figma → Settings → Personal access tokens. Needs read + write file scopes. |
| TOOL_PROFILE | No | Which set of tools to expose. Options: minimal, standard (default), full. See Tool Profiles. |
| FIGMA_WS_PORT | No | WebSocket port for the plugin bridge. Default: 18211. |
| FIGMA_WS_HOST | No | WebSocket host for the plugin bridge. Default: localhost. |
Tool Profiles
Profiles control how many tools are exposed to the AI. Fewer tools = fewer tokens per message = lower cost and less confusion for the model. Every profile includes figma_run as an escape hatch to call any tool on demand.
| Profile | Tools | ~Tokens/msg | Use case |
|---|---|---|---|
| minimal | 40 | 3,500 | Day-to-day design work — read, inspect, basic create/modify, screenshot, export |
| standard | 68 | 6,100 | Prototyping, variable management, auto-layout, effects. Recommended for most users. |
| full | 100+ | 9,400 | Everything including code generation, accessibility checks, boolean operations |
All profiles include figma_run, which lets you call any tool by name even if it's not in your profile. Example: "Use figma_run to call generate_react on this frame."
Read & Inspect
Tools for reading files, querying styles, browsing components, and inspecting designs. All use the REST API — no plugin required.
| Tool | Description | Key Parameters | Path |
|---|---|---|---|
| get_file | Get file metadata, pages, and top-level structure | fileKey |
REST |
| get_node | Get a specific node and its children by ID | fileKey, nodeId |
REST |
| get_nodes | Get multiple nodes in a single call | fileKey, nodeIds[] |
REST |
| get_styles | List all published styles in a file (text, color, effect, grid) | fileKey |
REST |
| get_style | Get details for a specific style by key | styleKey |
REST |
| get_components | List all components in a file | fileKey |
REST |
| get_component | Get a specific component by key | componentKey |
REST |
| get_team_components | Browse all components published to a team library | teamId |
REST |
| get_team_styles | Browse all styles published to a team library | teamId |
REST |
| get_team_projects | List projects within a team | teamId |
REST |
| get_project_files | List files within a project | projectId |
REST |
| get_variables | List all local variables and collections in a file | fileKey |
REST |
| get_library_variables | List variables from published team libraries | fileKey |
REST |
| get_library_collections | List variable collections from team libraries | fileKey |
REST |
| get_library_items_used | List which library components/styles are used in a file | fileKey |
REST |
| get_comments | Get all comments on a file | fileKey |
REST |
| post_comment | Add a comment to a file or specific node | fileKey, message, nodeId? |
REST |
| get_images | Export nodes as PNG, SVG, JPG, or PDF | fileKey, nodeIds[], format |
REST |
| get_file_versions | List version history for a file | fileKey |
REST |
| search | Search for nodes by name or type within a file | fileKey, query |
REST |
| screenshot | Capture a screenshot of a node or the full page | fileKey, nodeId? |
PLUGIN |
| get_selection | Get the user's current selection in Figma | — | PLUGIN |
| get_flows | List all prototype flows in a file | fileKey |
REST |
| get_interactions | Get prototype interactions attached to a node | nodeId |
PLUGIN |
| get_instance_overrides | Get property overrides on a component instance | nodeId |
PLUGIN |
| get_annotations | Get annotations (dev mode) on nodes | nodeId |
PLUGIN |
| get_viewport | Get the current viewport position and zoom | — | PLUGIN |
| scan_nodes_by_types | Find all nodes of specific types (FRAME, TEXT, etc.) | types[] |
PLUGIN |
| scan_text_nodes | Find all text nodes, optionally matching content | query? |
PLUGIN |
| export_svg | Export a node as inline SVG markup | nodeId |
PLUGIN |
| export_png | Export a node as PNG (base64 or URL) | nodeId, scale? |
PLUGIN |
| check_accessibility | Run contrast and touch-target accessibility checks | nodeId |
PLUGIN |
| validate_layout | Check spacing consistency, alignment, and overflow issues | nodeId |
PLUGIN |
| get_code_connect_map | Get code connect mappings between Figma components and codebase components | fileKey |
REST |
| get_design_system_rules | Extract design system rules and conventions from the current file | — | PLUGIN |
Create & Build
Tools for creating new nodes on the canvas. All require the companion plugin.
| Tool | Description | Key Parameters |
|---|---|---|
| create_frame | Create a frame (artboard) with optional size, fill, auto-layout | name, width, height, parentId? |
| create_rectangle | Create a rectangle shape | x, y, width, height, parentId? |
| create_ellipse | Create a circle or ellipse | x, y, width, height, parentId? |
| create_line | Create a line between two points | startX, startY, endX, endY, parentId? |
| create_text | Create a text node with font, size, and content | content, fontSize?, fontFamily?, parentId? |
| create_component | Create a new component from scratch or convert a frame | name, nodeId? |
| create_instance | Create an instance of an existing component | componentId, parentId? |
| import_component_by_key | Import a published component from a team library | componentKey |
| import_style_by_key | Import a published style from a team library | styleKey |
| create_page | Add a new page to the file | name |
| switch_page | Navigate to a different page | pageId |
| clone_node | Duplicate an existing node | nodeId |
| group_nodes | Group multiple nodes together | nodeIds[] |
| boolean_operation | Union, subtract, intersect, or exclude shapes | nodeIds[], operation |
| delete_node | Remove a node from the canvas | nodeId |
| batch | Execute multiple tool calls in a single round trip | operations[] |
Modify & Style
Tools for changing properties on existing nodes. All require the companion plugin.
| Tool | Description | Key Parameters |
|---|---|---|
| set_fill | Set solid or gradient fill colors | nodeId, color |
| set_stroke | Set stroke color, weight, alignment | nodeId, color, weight? |
| set_opacity | Set node opacity (0–1) | nodeId, opacity |
| set_corner_radius | Set corner radius (uniform or per-corner) | nodeId, radius |
| set_effects | Add shadows, blurs, and other effects | nodeId, effects[] |
| set_auto_layout | Enable and configure auto-layout | nodeId, direction, spacing?, padding? |
| set_constraints | Set horizontal/vertical constraints | nodeId, horizontal, vertical |
| set_text_content | Update text node content | nodeId, text |
| set_text_style | Set font, size, weight, line height, etc. | nodeId, fontSize?, fontFamily?, fontWeight? |
| resize_node | Change width and/or height | nodeId, width?, height? |
| move_node | Change x/y position | nodeId, x, y |
| rename_node | Change a node's name | nodeId, name |
| reparent_node | Move a node to a different parent | nodeId, newParentId |
| set_visible | Show or hide a node | nodeId, visible |
| set_focus | Zoom viewport to a specific node | nodeId |
| set_selections | Select specific nodes in the canvas | nodeIds[] |
| set_instance_overrides | Override properties on a component instance | nodeId, overrides |
| set_annotation | Add or update a dev-mode annotation | nodeId, text |
| apply_style | Apply a published style to a node | nodeId, styleId |
Code Generation
Export designs as production-ready code. Available in the full profile (or via figma_run escape hatch).
| Tool | Description | Output |
|---|---|---|
| generate_react | Generate React component with props and JSX | JSX / TSX |
| generate_html | Generate semantic HTML markup | HTML |
| generate_css | Generate CSS with classes matching the design | CSS |
| generate_swiftui | Generate SwiftUI view code | Swift |
| generate_tailwind_config | Generate Tailwind CSS config from design tokens | JS config |
| generate_tokens | Export design tokens as JSON (colors, spacing, typography) | JSON |
| generate_handoff_spec | Generate a full developer handoff spec | Markdown |
| codegen_bundle | Generate a complete code bundle (HTML + CSS + JS) | Bundle |
| analyze_for_codegen | Analyze a node's structure to determine the best code generation approach | Analysis |
Design Tokens
Variable and style CRUD via the REST API. No plugin required for most operations.
| Tool | Description | Path |
|---|---|---|
| create_variable_collection | Create a new variable collection (e.g., "Colors") | REST WRITE |
| create_variable | Create a variable inside a collection | REST WRITE |
| set_variable_value | Set a variable's value for a specific mode | REST WRITE |
| update_variable | Update variable name, description, or scopes | REST WRITE |
| delete_variable | Remove a variable | REST WRITE |
| delete_variable_collection | Remove an entire variable collection | REST WRITE |
| bind_variable | Bind a variable to a node property (fill, stroke, etc.) | PLUGIN |
| create_style | Create a new named style (text, fill, effect, grid) | PLUGIN |
| import_style_by_key | Import a style from a team library | PLUGIN |
| apply_style | Apply a style to a node | PLUGIN |
Prototyping
Build interactive prototypes. All require the companion plugin.
| Tool | Description | Key Parameters |
|---|---|---|
| create_interaction | Add a prototype interaction (tap, hover, etc.) | nodeId, trigger, action, destination |
| remove_interactions | Remove all interactions from a node | nodeId |
| create_flow | Create a new prototype flow starting point | nodeId, name |
| remove_flow | Remove a prototype flow | flowId |
| set_default_transition | Set the default page transition animation | type, duration? |
| setup_overlay | Configure a frame as an overlay (modal, dropdown) | nodeId, position |
| set_scroll_behavior | Configure scrolling (horizontal, vertical, fixed) | nodeId, behavior |
| present_prototype | Open the prototype in presentation mode | flowId? |
| get_flows | List all prototype flows | — |
| get_interactions | Get interactions on a node | nodeId |
Utility Tools
Available in all profiles.
| Tool | Description |
|---|---|
| figma_run | Call any tool by name, even if it's not in your active profile. Acts as an escape hatch. |
| figma_batch | Execute multiple tool calls in a single round trip for performance. |
| figma_status | Check the connection status of the server, REST API, and plugin bridge. |
| figma_connect_plugin | Manually trigger plugin connection (usually automatic). |
| figma_send_command | Send a raw command to the Figma plugin for advanced use cases. |
| figma_cache | Manage the library cache for faster repeated lookups. |
| figma_skill | Run a named agent skill (e.g., audit_design_system, build_page) with parameters. |
Recipes
Common multi-step workflows you can accomplish in a single conversation.
Design a card component
Create a reusable card with image, title, description, and action button.
- Ask: "Create a card component, 320×400, with an image placeholder at the top, a title, a description, and a primary button."
- The agent calls
create_frame,create_rectangle(image placeholder),create_text(×2), andcreate_component - It applies
set_auto_layoutfor vertical spacing,set_corner_radius, andset_fill - Ask: "Now create 3 instances in a row with different content"
Set up a light/dark color system
Create design tokens that switch between light and dark mode.
- Ask: "Create a variable collection called 'Colors' with Light and Dark modes"
- The agent calls
create_variable_collectionwith two modes - Ask: "Add variables for background, surface, text-primary, and text-secondary with appropriate values for each mode"
- The agent calls
create_variableandset_variable_valuefor each - Ask: "Bind these variables to the card component"
Prototype a multi-screen flow
Create a login → dashboard navigation flow with transitions.
- Ask: "Create a login screen and a dashboard screen"
- Ask: "Add a tap interaction on the Sign In button that navigates to the dashboard with a slide-left transition"
- The agent calls
create_interactionto wire it up - Ask: "Set the login screen as the flow starting point and present the prototype"
- The agent calls
create_flowthenpresent_prototype
Generate code from a design
Export a frame as React + Tailwind + design tokens.
- Ask: "Generate React code for this card component"
- The agent calls
generate_reacton the frame - Ask: "Also generate the Tailwind config and design tokens as JSON"
- The agent calls
generate_tailwind_configandgenerate_tokens - Ask: "Create a handoff spec for the developer"
Audit and fix accessibility
Check contrast ratios and touch targets across a page.
- Ask: "Run an accessibility check on the login screen"
- The agent calls
check_accessibilityand reports issues - Ask: "Fix the contrast issues by adjusting the text colors"
- The agent calls
set_fillon the affected text nodes
Figma Plugin
The companion plugin runs inside Figma and bridges WebSocket commands from the MCP server to the Figma Plugin API. For install and setup steps, see the Installation → Figma Plugin tab.
How it works
When you start the MCP server, it opens a WebSocket on port 18211 (configurable via FIGMA_WS_PORT). The plugin connects to this WebSocket when you run it in Figma. Commands from the MCP server are relayed through this bridge to the Figma Plugin API.
What requires the plugin
- Not needed: Reading files, styles, components, variables (REST API), posting comments, exporting images via REST
- Needed: Creating/modifying nodes, prototyping, screenshots, code generation, auto-layout, style application
Multiple files
The plugin connects per-file. If you switch to a different Figma file, you need to run the plugin again in that file. The server handles reconnection automatically.
Troubleshooting
"Plugin not connected" errors
- Make sure the plugin is running in your active Figma file
- Check that the MCP server is running and the WebSocket port isn't blocked
- Try
figma_connect_pluginto manually reconnect - Ensure no firewall is blocking
localhost:18211
"Invalid access token"
- Verify your token at Figma → Settings → Personal access tokens
- Ensure the token has File content (Read) and File content (Write) scopes
- Check that you're using the full token string (starts with
figd_)
"Tool not found" in minimal/standard profile
- Some tools are only in the full profile (e.g., code generation, boolean operations)
- Use
figma_runto access any tool regardless of profile: "Use figma_run to call generate_react" - Or switch to the full profile via
TOOL_PROFILE=full
Server won't start
- Ensure Node.js 18+ is installed:
node --version - Run
npm run buildafter pulling updates - Check that the path in your MCP config is an absolute path
- Look at the MCP client logs for specific error messages
Batch operations timing out
- Large batches (20+ operations) may take time — the plugin executes them sequentially
- Split very large batches into smaller groups of 10–15 operations
- Complex code generation tools may take 10–30 seconds per call
Getting help
Open an issue on GitHub with:
- Your MCP client (Claude Desktop, VS Code, Cursor)
- Node.js version
- The full error message
- Whether the plugin was running when the error occurred