Figma MCP Server
Empowers AI assistants to control Figma via natural language, enabling creation and modification of designs, components, variables, and exports through a WebSocket bridge.
README
Figma MCP Server
An MCP (Model Context Protocol) server that gives AI assistants like Claude full control over Figma — create frames, components, variables, export assets, and build complete UI designs through natural language.
How It Works
Claude / Cursor
↕ stdio (JSON-RPC)
MCP Server (Node.js)
↕ WebSocket
WS Bridge (127.0.0.1:9001)
↕ Plugin API
Figma Plugin (Figma Desktop)
- You ask Claude to create or modify a design
- Claude calls an MCP tool — the MCP server validates the arguments
- The server sends a command over a local WebSocket to the bridge
- The bridge forwards it to the Figma plugin running in Figma Desktop
- The plugin executes
figma.*API calls and returns the result - Claude receives the result and continues building
Prerequisites
- Node.js v18 or later
- Figma Desktop — the web version does not support plugins with network access
- Claude Desktop or Cursor (or any MCP-compatible client)
Installation
1. Clone and install dependencies
git clone https://github.com/your-username/figma-mcp.git
cd figma-mcp
npm install
2. Build the project
npm run build
This compiles src/mcp-server/ and src/websocket-server/ to dist/. The Figma plugin (src/figma-plugin/) is plain JavaScript and needs no compilation.
3. Start the WebSocket bridge
npm run socket
For development with auto-reload:
npm run dev:socket
You should see:
{"level":"info","component":"bridge","msg":"Listening on 127.0.0.1:9001"}
4. Load the plugin in Figma Desktop
- Open Figma Desktop
- Go to Plugins → Development → Import plugin from manifest...
- Select
src/figma-plugin/manifest.json - Run it from Plugins → Development → Figma MCP Bridge
The plugin UI shows "Connected" when the bridge connection is established.
5. Connect your AI client
Claude Desktop
Add to claude_desktop_config.json (find it at ~/Library/Application Support/Claude/ on macOS or %APPDATA%\Claude\ on Windows):
{
"mcpServers": {
"figma": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/figma-mcp/dist/mcp-server/index.js"]
}
}
}
Cursor
Add to your MCP config (.cursor/mcp.json or via Cursor Settings → MCP):
{
"mcpServers": {
"figma": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/figma-mcp/dist/mcp-server/index.js"]
}
}
}
Replace /ABSOLUTE/PATH/TO/figma-mcp with the actual path to this repo.
Restart your AI client after saving the config. The Figma tools will appear automatically.
Available Tools
67 tools organized into categories:
Reading & Inspection
| Tool | Description |
|---|---|
get_document_info |
Get document structure: all pages, top-level frames, and metadata |
get_selection |
Get all currently selected nodes with their properties |
get_node |
Get detailed properties of a specific node by ID |
find_nodes |
Search for nodes by type and/or name pattern across the document |
Creating Shapes & Elements
| Tool | Description |
|---|---|
create_frame |
Create a layout frame — the primary container for UI design |
create_rectangle |
Create a rectangle (background fills, dividers, placeholder shapes) |
create_ellipse |
Create an ellipse or circle (avatars, status dots, decorative circles) |
create_text |
Create a text node with typography settings |
create_line |
Create a line (dividers, separators, strokes) |
create_polygon |
Create a regular polygon (triangle, hexagon, etc.) |
create_star |
Create a star shape with configurable point count and inner radius |
create_vector |
Create a vector node from SVG path data |
create_svg_node |
Create a node from an SVG markup string |
Modifying Nodes
| Tool | Description |
|---|---|
update_node |
Update position, size, opacity, visibility, name, or fills of any node |
update_text |
Update text content or typography of an existing text node |
set_auto_layout |
Apply auto layout to a frame for automatic spacing and alignment |
set_node_layout_properties |
Set child-level layout properties inside an auto-layout frame |
set_fill |
Set solid or gradient fills on any node |
set_stroke |
Set stroke (border/outline) with color, dash patterns, and line caps |
set_corner_radius |
Set individual corner radii for asymmetric rounding |
set_effects |
Set visual effects: drop shadow, inner shadow, blur, background blur |
add_shadow |
Add a drop shadow for depth and elevation |
set_rotation |
Set the rotation angle of a node in degrees |
set_blend_mode |
Set layer blend mode (multiply, screen, overlay, etc.) |
set_constraints |
Set responsive pinning/resize constraints |
set_layout_grids |
Add column, row, or pixel grids to a frame |
set_text_decoration |
Set underline or strikethrough on a text node |
set_text_case |
Set text case transformation (upper, title, small caps, etc.) |
set_text_list |
Apply bullet or numbered list formatting to a text node |
lock_node |
Lock or unlock a node to protect it from accidental edits |
Organizing Nodes
| Tool | Description |
|---|---|
group_nodes |
Group multiple nodes into a visual group |
ungroup_nodes |
Ungroup a group and move its children to the parent |
delete_node |
Permanently remove a node and its children |
clone_node |
Duplicate a node with all its properties and children |
reorder_node |
Move a node to a specific z-order index within its parent |
flatten_node |
Merge a node and its children into a single vector |
create_boolean_operation |
Combine shapes with union, intersect, subtract, or exclude |
Components & Instances
| Tool | Description |
|---|---|
create_component |
Convert a node into a reusable Figma component |
create_component_instance |
Place an instance of an existing component |
get_local_components |
List all components defined in the document |
combine_as_variants |
Combine multiple components into a variant set |
detach_instance |
Detach an instance from its master component |
swap_component |
Swap the component an instance references |
import_component_by_key |
Import a component from a shared library by key |
Style System
| Tool | Description |
|---|---|
create_paint_style |
Create a reusable color/paint style (design token) |
create_text_style |
Create a reusable text style (typography token) |
create_effect_style |
Create a reusable effect style (elevation/shadow token) |
get_local_styles |
List all paint, text, and effect styles in the document |
apply_style |
Apply a style to a node by style ID |
Variables & Design Tokens
| Tool | Description |
|---|---|
create_variable_collection |
Create a variable collection with support for multiple modes (e.g. Light/Dark) |
create_variable |
Create a design token variable: color, number, string, or boolean |
bind_variable |
Bind a variable to a node property for theme-aware designs |
get_variables |
List all variable collections and their variables |
Images
| Tool | Description |
|---|---|
set_image_from_url |
Fetch an image from a public URL and apply it as a fill |
set_image_from_path |
Read a local image file and apply it as a fill |
set_image_fill |
Apply an image fill using raw base64 data |
Export
| Tool | Description |
|---|---|
export_node |
Export a node as PNG, JPG, SVG, or PDF — auto-saved and returned as an image |
Pages & Sections
| Tool | Description |
|---|---|
create_page |
Create a new page in the Figma document |
create_section |
Create a section on the canvas to visually organize frames |
set_current_page |
Navigate to a specific page by ID |
Workflow & Utility
| Tool | Description |
|---|---|
zoom_to_node |
Scroll and zoom the canvas to center on a node |
set_selection |
Set the canvas selection to specific nodes |
list_available_fonts |
List all fonts available in the Figma environment |
batch_create |
Create multiple nodes in a single call |
batch_update |
Update properties of multiple nodes in a single call |
notify |
Show a toast notification in the Figma UI |
Example Prompts
Landing Page Hero Section
"Create a 1440×900 hero section frame. Add a dark navy background, a large white heading 'Build faster with AI', a subtitle below it in lighter gray, and a blue rounded CTA button. Center everything with auto layout."
Card Component
"Create a card component — 320×400 frame, 12px corner radius, subtle drop shadow, 16px padding. Include a gray image placeholder at the top, a bold title, a description, and a 'Learn more' link at the bottom."
Design System Setup
"Set up a basic design system in this document. Create color styles for Primary (#4F46E5), Background (#F9FAFB), and Text (#111827). Create text styles for Heading H1 (32px bold Inter), Body (16px regular Inter), and Caption (12px regular Inter)."
Component with Variants
"Create a button component with three variants: Primary (blue fill, white text), Secondary (white fill, blue border), and Destructive (red fill, white text). Combine them into a variant set."
Dark/Light Theme with Variables
"Create a variable collection called 'Theme' with Light and Dark modes. Add a 'Background' color variable: white (#FFFFFF) in Light, dark gray (#1A1A2E) in Dark. Add a 'Text/Primary' color variable: dark (#111827) in Light, white (#F9FAFB) in Dark."
Image-Based Layout
"Create a 1200×600 feature section. Fetch the image from https://images.unsplash.com/photo-example and apply it to the left half. On the right half, add a heading and description with auto layout."
Configuration
Environment Variables
Copy .env.example to .env to customize the defaults:
| Variable | Default | Description |
|---|---|---|
WS_HOST |
127.0.0.1 |
Host the bridge binds to — keep loopback-only |
WS_PORT |
9001 |
Port the bridge listens on |
WS_URL |
ws://127.0.0.1:9001?role=mcp-client |
WebSocket URL the MCP server connects to |
WS_TIMEOUT_MS |
30000 |
How long (ms) the MCP server waits for a plugin response |
LOG_LEVEL |
info |
trace / debug / info / warn / error / silent |
LOG_PRETTY |
false |
Set true for human-readable colored log output |
LOG_FILE |
(stderr) | Absolute path to write logs to a file instead of stderr |
Export Directory
Exported nodes are auto-saved to ./exports/ by default. Override with the FIGMA_EXPORT_DIR environment variable:
FIGMA_EXPORT_DIR=/my/designs/exports npm run socket
Development
# Build TypeScript
npm run build
# Watch mode (auto-reload bridge)
npm run dev:socket
# Run all tests
npm test
# Watch tests
npm run test:watch
# Coverage report (80% threshold)
npm run test:coverage
Project Structure
figma-mcp/
├── src/
│ ├── shared/ # Wire protocol & constants (shared between server and bridge)
│ │ ├── constants.ts # COMMAND_NAMES (single source of truth), defaults
│ │ ├── protocol.ts # Message types, error codes
│ │ ├── index.ts # Barrel re-export
│ │ └── logger/ # Structured logging (pino-based)
│ │ ├── logger.ts # createLogger() factory
│ │ ├── metrics.ts # MetricsCollector (counters, histograms)
│ │ └── redact.ts # Sensitive field redaction
│ │
│ ├── mcp-server/ # MCP server (Claude ↔ bridge)
│ │ ├── index.ts # Server setup, tool registration, server-side tools
│ │ ├── ws-client.ts # WebSocket client with reconnect logic
│ │ ├── request-tracker.ts # Promise-based request/response matching
│ │ └── tools/ # Tool schemas split by category
│ │ ├── index.ts # Merges all partial registries → TOOL_REGISTRY
│ │ ├── shared-schemas.ts # Reusable Zod schemas (RGBAColor, Fill, Typography…)
│ │ ├── read-tools.ts
│ │ ├── create-tools.ts
│ │ ├── modify-tools.ts
│ │ ├── organize-tools.ts
│ │ ├── viewport-tools.ts
│ │ ├── style-tools.ts
│ │ ├── layout-tools.ts
│ │ ├── component-tools.ts
│ │ ├── style-system-tools.ts
│ │ ├── image-tools.ts
│ │ ├── export-tools.ts
│ │ ├── typography-tools.ts
│ │ ├── constraint-tools.ts
│ │ ├── batch-tools.ts
│ │ ├── vector-tools.ts
│ │ ├── page-tools.ts
│ │ ├── traversal-tools.ts
│ │ ├── variable-tools.ts
│ │ ├── workflow-tools.ts
│ │ ├── design-system-tools.ts
│ │ ├── manipulation-tools.ts
│ │ └── extra-shape-tools.ts
│ │
│ ├── websocket-server/ # WebSocket bridge (routes commands between MCP and plugin)
│ │ ├── index.ts # FigmaBridge class and entry point
│ │ ├── config.ts # BridgeConfig + loadConfig()
│ │ └── validation.ts # Message validation, ProtocolError
│ │
│ └── figma-plugin/ # Figma plugin (plain JS, no build step)
│ ├── manifest.json # Plugin manifest
│ ├── code.js # Plugin sandbox — handles all figma.* API calls
│ └── ui.html # Hidden iframe — holds the WebSocket connection
│
├── tests/
│ ├── mcp-server/
│ │ ├── tools.test.ts # Zod schema validation for all tools
│ │ └── request-tracker.test.ts
│ ├── websocket-server/
│ │ └── bridge.test.ts # Bridge routing and client management
│ ├── integration/
│ │ └── roundtrip.test.ts # Full MCP → bridge → mock plugin round-trips
│ └── shared/
│ ├── logger.test.ts
│ └── metrics.test.ts
│
├── exports/ # Auto-created when export_node is used
├── logs/ # Optional log output directory
├── .env.example # Environment variable reference
├── package.json
├── tsconfig.json
└── vitest.config.ts
Troubleshooting
Plugin shows "Disconnected" or never connects
- Make sure
npm run socketis running and shows "Listening on 127.0.0.1:9001" - Confirm the plugin is active in Plugins → Development → Figma MCP Bridge
- If port 9001 is in use by another process, change the port:
Then updateWS_PORT=9002 npm run socketWS_URLin.envto match.
Commands time out
- Confirm the plugin shows "Connected" — commands cannot reach Figma without an active connection
- Font operations (text nodes) load fonts asynchronously — the default 30s timeout handles most cases
- For slow operations, increase the timeout:
WS_TIMEOUT_MS=60000 - Check that Figma Desktop is responsive and not showing any error dialogs
Bridge port already in use (EADDRINUSE)
A previous bridge process is still running. On macOS/Linux:
lsof -i :9001
kill <PID>
On Windows (PowerShell):
Get-Process -Id (Get-NetTCPConnection -LocalPort 9001).OwningProcess | Stop-Process
MCP tools do not appear in Claude / Cursor
- Make sure
npm run buildcompleted without TypeScript errors - Verify the absolute path in your MCP config points to
dist/mcp-server/index.js - Restart your AI client after every config change
- Check your client's MCP logs for connection errors
Images not loading (set_image_from_url)
- The URL must be publicly accessible (no auth, no paywalls)
- Supported formats: PNG, JPEG, GIF, WebP, SVG
- Maximum file size: 5 MB (oversized images are auto-optimized before being sent)
Architecture Notes
- Security: The bridge binds to
127.0.0.1only — it is never exposed to the network. The plugin'snetworkAccess.allowedDomainsis set tononein production. - Message size: Maximum WebSocket message is 8 MB to support high-resolution image fills.
- Reconnection: The plugin auto-reconnects with exponential backoff (1s base, 2× multiplier, 30s max) if the bridge restarts.
- Server-side tools:
set_image_from_urlandset_image_from_pathrun entirely in Node.js (fetch + encode) and forward toset_image_fill— they never require extra plugin code. - Logging: All Node.js logs go to stderr to avoid corrupting MCP's JSON-RPC on stdout. Set
LOG_PRETTY=truefor readable development output.
Contributing
- Add the command name to
COMMAND_NAMESinsrc/shared/constants.ts - Create the tool schema in the appropriate file under
src/mcp-server/tools/ - Add the handler in
src/figma-plugin/code.js - Add the command to
ALLOWED_COMMANDSin bothcode.jsandui.html - Add tests in
tests/mcp-server/tools.test.ts
See CLAUDE.md for the full contributor guide.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。