figma-proxy-mcp
A local MCP server that gives AI agents live access to open Figma files for design handoff and UX writing without API tokens or rate limits.
README
figma-proxy-mcp
Live Figma access for AI agents via MCP. No REST API token. No rate limits. No stale exports.
An AI agent connected to this server can read design tokens, extract CSS, export assets, audit copy, and write text content — all against the file currently open in Figma Desktop.
Table of contents
- Architecture
- Prerequisites
- Installation
- Connecting an AI client
- Configuration
- Tool reference
- Recommended workflows
- Multi-file support
- CI/CD
Architecture
AI Agent (Claude, Cursor, Windsurf, …)
│
│ Streamable HTTP (MCP protocol)
▼
┌─────────────────────────────────┐
│ mcp-server :3001 │ Tool registry · RPC translation · Response processing
└─────────────┬───────────────────┘
│ HTTP POST /rpc
▼
┌─────────────────────────────────┐
│ websocket proxy :3000 │ Plugin connection manager · Multi-file routing
└─────────────┬───────────────────┘
│ WebSocket
▼
┌─────────────────────────────────┐
│ Figma Plugin │ Runs inside Figma Desktop · Executes Plugin API calls
└─────────────┬───────────────────┘
│ Plugin API
▼
Live Figma File
Prerequisites
- Node.js 22+ — for local development
- Docker + Docker Compose — for containerised deployment
- Figma Desktop — the plugin requires the desktop Plugin API (not supported in the browser)
Installation
Option A — Docker (recommended)
cp .env.example .env # set MCP_API_KEY and MCP_PUBLIC_URL if needed
docker compose up
Option B — Local
cd websocket && npm install && npm run dev
cd mcp-server && npm install && npm run dev
Figma plugin
Build once, then load into Figma Desktop:
cd plugin && npm install && npm run build
- Open Figma Desktop
- Plugins → Development → Import plugin from manifest
- Select
plugin/manifest.json - Run the plugin — the status indicator turns green when connected
The plugin reconnects automatically and persists the proxy URL across sessions.
Connecting an AI client
Claude Code
claude mcp add figma --transport http http://localhost:3001/mcp
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"figma": {
"url": "http://localhost:3001/mcp"
}
}
}
Cursor / Windsurf
Add http://localhost:3001/mcp as an MCP server in the IDE settings.
Remote or tunneled server
claude mcp add figma --transport http https://your-tunnel.example.com/mcp \
--header "Authorization: Bearer YOUR_API_KEY"
Configuration
| Variable | Default | Description |
|---|---|---|
PROXY_URL |
http://localhost:3000 |
WebSocket proxy address, consumed by the MCP server |
MCP_PORT |
3001 |
Listening port for the MCP server |
MCP_API_KEY |
— | When set, all /mcp requests must carry Authorization: Bearer <key> |
MCP_PUBLIC_URL |
http://localhost:3001 |
Public base URL of the MCP server. Used to construct downloadUrl values returned by image export tools. Must be set to your tunnel URL when the server is accessed remotely. |
Tool reference
Node IDs accept both the internal colon format (2650:516) and the hyphen format found in Figma share URLs (2650-516). All tools accept an optional fileKey to target a specific open file; omit it when only one file is connected.
Document & node inspection
| Tool | Key parameters | Description |
|---|---|---|
get_document |
depth, maxNodes |
Full node tree of the current page |
get_selection |
— | Currently selected nodes |
get_node |
nodeId, maxNodes |
Fetch a single node and its subtree. Increase maxNodes (up to 5000) for deeper trees. |
get_node_full |
nodeId |
Like get_node but auto-retries with increasing maxNodes until the complete tree is returned — no truncation |
get_slice_spec |
nodeId |
One-call slice bundle: complete node tree + layout specification + all SVG vector data |
get_design_context |
nodeIds, depth, maxNodes |
Depth-limited snapshot of one or more nodes, optimised for AI context windows |
get_metadata |
— | File name, page list, current page, file key |
CSS & layout
| Tool | Key parameters | Description |
|---|---|---|
get_css |
nodeId |
CSS properties: dimensions, flex, color, padding, border-radius |
get_layout_spec |
nodeId |
Full auto-layout spec — direction, gap, padding, alignment, sizing mode |
get_responsive_behavior |
nodeId |
Constraints, grow flags, min/max sizes |
get_corner_radii |
nodeId |
Per-corner radii and corner smoothing factor |
get_stroke_spec |
nodeId |
Per-side stroke weights, dash pattern, cap and join style |
get_effect_spec |
nodeId |
Drop shadows and blur effects with complete parameters |
get_styles |
— | All local paint, text, effect, and grid styles |
Components & design tokens
| Tool | Key parameters | Description |
|---|---|---|
get_component_properties |
nodeId |
Property definitions, variant props, dev-mode status |
get_instance_overrides |
nodeId |
Per-instance overrides and main component reference |
get_variables |
— | All variable collections, modes, and raw values |
get_variable_tokens |
— | Design tokens grouped by collection and mode |
get_node_variable_bindings |
nodeId |
Variables bound to a node with their resolved mode values |
Assets & image export
| Tool | Key parameters | Description |
|---|---|---|
get_exportable_nodes |
nodeId |
Scan a subtree for nodes that have export settings or image fills — use this to discover assets before exporting |
get_screenshot |
nodeId/nodeIds, format, scale, outputPath, outputDir |
Export nodes as PNG, JPG, PDF, or SVG. Returns downloadUrl per raster node; SVG is returned inline. |
get_svg |
nodeId/nodeIds, outputPath, outputDir |
Export nodes as inline SVG markup strings |
get_image |
nodeId |
Extract raw image fill bytes from a node. Returns downloadUrl. |
export_section_assets |
nodeId, format, scale, outputDir |
Batch-export every exportable asset in a section. Returns downloadUrl per asset, or writes files directly if outputDir is provided. |
get_colors |
— | All unique hex colors extracted from fills and strokes |
get_fonts |
— | All font families and styles used in the document |
Asset download model
get_screenshot, get_image, and export_section_assets write exported files to the MCP server's temp directory (TTL: 10 minutes) and return a downloadUrl. The agent retrieves the file with a single command:
curl -o assets/hero.png "http://localhost:3001/dl/<id>"
This pattern works uniformly across all deployment topologies — local, Docker, and tunneled remote. When the MCP server is tunneled, set MCP_PUBLIC_URL to the public URL so returned links are reachable from the agent's machine.
Alternatively, if the MCP server and the agent share a filesystem (local dev or Docker with a volume mount), pass outputPath (single node) or outputDir (batch) to write files directly without an intermediate download.
Text & copy
| Tool | Key parameters | Description |
|---|---|---|
get_text_content |
nodeId, page |
Extract all text. Scope to a subtree with nodeId, or a page with page. Omit both to dump the entire file. |
find_text_nodes |
keyword, regex |
Search text nodes by keyword or regular expression across all pages |
find_placeholders |
— | Detect lorem ipsum, {{double braces}}, [square brackets], and "your text here" patterns |
detect_text_overflow |
page |
Find text nodes whose content overflows their clipped container |
check_text_consistency |
group_by, page |
Audit text style consistency; group results by page, font size, or font family |
get_text_segments |
nodeId, fields |
Per-segment rich text data: font, size, color, weight, hyperlink |
get_typography_tokens |
— | All local text styles with complete typography properties |
set_text_content |
nodeId, text |
Replace the content of a text node. Handles mixed-font nodes. |
create_text |
text, x, y, fontSize, parentId |
Create a new text node |
Write operations
| Tool | Key parameters | Description |
|---|---|---|
set_text_content |
nodeId, text |
Replace text content. Provides a clear error if the target node is not a TEXT node, listing any text children found inside it. |
set_node_visibility |
nodeIds, visible |
Show or hide a set of nodes |
set_solid_fill |
nodeId, color, opacity |
Replace a node's fill with a solid hex color |
set_node_properties |
nodeId, name, x, y, width, height, opacity |
Update node geometry or name |
create_text |
text, x, y, fontSize, parentId |
Create a new text node |
Code generation
| Tool | Key parameters | Description |
|---|---|---|
to_html |
nodeId |
Convert a node to HTML with inline CSS |
to_html_page |
page |
Convert an entire Figma page to a standalone HTML document |
export_json |
nodeId |
Export a node as Figma REST API JSON (v1 format) |
Recommended workflows
Design-to-code handoff
1. get_design_context({ nodeId: "<section>", depth: 2 })
→ section structure, spacing, color tokens
2. get_css({ nodeId: "<component>" })
get_layout_spec({ nodeId: "<component>" })
→ implementation-ready CSS
3. get_variable_tokens({})
→ design token definitions for CSS custom properties
Full-page slice
1. get_text_content({ nodeId: "<page-frame>" })
→ all copy scoped to this frame
2. get_exportable_nodes({ nodeId: "<page-frame>" })
→ list of all image/illustration nodes
3. export_section_assets({ nodeId: "<page-frame>", format: "PNG", scale: 2 })
→ { exported: [{ name: "hero", downloadUrl: "…" }, { name: "illus-seo", downloadUrl: "…" }] }
4. curl -o assets/hero.png "<downloadUrl>"
→ asset saved, no base64, no decoding
Copy audit
1. find_placeholders({})
→ all lorem ipsum, {{tokens}}, [brackets] across every page
2. check_text_consistency({ group_by: "page" })
→ pages where heading/body styles deviate from the baseline
3. set_text_content({ nodeId: "<id>", text: "Production copy" })
→ update live in Figma
Component exploration
1. get_slice_spec({ nodeId: "<component-frame>" })
→ node tree + layout + all vector SVGs in one response
2. get_instance_overrides({ nodeId: "<instance>" })
→ which props have been overridden and their values
3. get_node_variable_bindings({ nodeId: "<instance>" })
→ every token bound to this node and its resolved value per mode
Multi-file support
When multiple Figma files are open with the plugin running in each, pass fileKey to route a call to a specific file:
{ "tool": "get_document", "arguments": { "fileKey": "abc123XYZ" } }
Omit fileKey when only one file is connected — the proxy routes to the single active session automatically.
CI/CD
.github/workflows/docker-build-push.yml builds both services and pushes to GitHub Container Registry on every push to main:
ghcr.io/<owner>/figma-proxy-mcp/mcp-server:latest
ghcr.io/<owner>/figma-proxy-mcp/mcp-server:<sha>
ghcr.io/<owner>/figma-proxy-mcp/websocket:latest
ghcr.io/<owner>/figma-proxy-mcp/websocket:<sha>
No additional secrets required — the workflow uses the built-in GITHUB_TOKEN.
推荐服务器
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 模型以安全和受控的方式获取实时的网络信息。