figma-mcp-hybrid

figma-mcp-hybrid

Enables reading Figma files via REST API and writing to the Figma canvas via a WebSocket bridge.

Category
访问服务器

README

Figma MCP (Hybrid)

A local Model Context Protocol server that gives Cursor (or any MCP client) both:

  • REST reads — read any Figma file by key (document tree, nodes, components, styles, comments, image exports), hardened against Figma's rate limits with a persistent disk cache, per-tier throttling, 429/Retry-After backoff, request coalescing, and stale-while-revalidate. Works without opening the file in Figma.
  • Canvas writes — create/edit/delete nodes, set fills, auto-layout, components, text, and more, by driving the Figma Plugin API over a local WebSocket bridge.

It is a hybrid of two approaches:

Architecture

Cursor (MCP host)
   stdio / JSON-RPC
MCP server  (src/talk_to_figma_mcp/server.ts, Node + tsx)
   REST + disk cache + throttle  ->  Figma REST API        (read any file by key)
   WebSocket client  ->  Relay (src/socket.ts) <-> Figma plugin  (read open file + write canvas)

Three independent processes connect over ws://localhost:3055:

  1. The relay (src/socket.ts) — a channel-based WebSocket broker.
  2. The MCP server — connects to the relay as a client and to Cursor over stdio.
  3. The Figma plugin (src/cursor_mcp_plugin) — its iframe UI owns the WebSocket (the plugin sandbox can't), and relays commands to the Figma scene.

The MCP server and plugin pair up by joining the same channel.

Avoiding Figma rate limits

Figma's REST API is rate-limited (leaky bucket, per-minute; e.g. Tier-1 file/image reads are 10-20/min on paid Dev/Full seats but only 6 per month on Starter). This server minimizes how often it actually calls the API using a read hierarchy:

1. Plugin bridge   -> read the open file via the Plugin API   (0 REST calls, no limit, no token)
2. Disk cache      -> serve a fresh cached response           (0 REST calls)
3. Throttled fetch -> per-tier queue + coalesce duplicates    (1 REST call, then cached)
   - on 429        -> wait Retry-After, exponential backoff
   - on failure    -> serve stale cache with a [STALE] note

Practical effect: an agent that would otherwise make hundreds of reads makes one (or zero, when the file is open in Figma). REST tool results are prefixed with [cache hit] or [STALE] ... so you can see when no API call was made. Pass forceRefresh: true to any read tool (or use figma_cache_clear) to bypass the cache.

Caching / throttling env vars (all optional)

Variable Default Purpose
FIGMA_CACHE_DIR OS cache dir (~/Library/Caches/figma-mcp, ~/.cache/figma-mcp, %LOCALAPPDATA%/figma-mcp) Where cached responses are written
FIGMA_CACHE_TTL 24h TTL for file/node/component/style/comment reads (30d, 12h, 30m, 60s, 500ms)
FIGMA_IMAGE_CACHE_TTL 1h TTL for image renders (URLs expire, so kept short)
FIGMA_RPM_TIER1 10 Max requests/min for Tier 1 (file, nodes, images)
FIGMA_RPM_TIER2 25 Max requests/min for Tier 2 (comments)
FIGMA_RPM_TIER3 50 Max requests/min for Tier 3 (components, styles)
FIGMA_MAX_RETRIES 5 Max 429 retries before giving up (then stale cache is served if available)

Raise FIGMA_CACHE_TTL (e.g. 30d) for stable/finished designs to make API calls extremely rare. Lower the FIGMA_RPM_* values to match a Starter seat's stricter limits.

Requirements

  • Node.js 18+ (developed on Node 24; uses the global fetch). No Bun required.
  • Figma Desktop (for the write/plugin path).
  • A Figma personal access token (for the REST read path): Figma → Settings → Security → Personal access tokens.

Install

npm install

Configure Cursor

Add to ~/.cursor/mcp.json (use an absolute path to this folder):

{
  "mcpServers": {
    "figma-hybrid": {
      "command": "npx",
      "args": ["tsx", "/absolute/path/to/figma-mcp/src/talk_to_figma_mcp/server.ts"],
      "env": {
        "FIGMA_TOKEN": "your-figma-personal-access-token"
      }
    }
  }
}

A project-scoped equivalent is in .mcp.json. The FIGMA_TOKEN is only needed for REST read tools; the plugin/WebSocket write tools work without it.

Run order

  1. Start the relay:
    npm run socket
    
    (Listens on ws://localhost:3055. Override with WS_PORT.)
  2. Run the Figma plugin: Figma Desktop → Plugins → Development → Import plugin from manifest → select src/cursor_mcp_plugin/manifest.json → run it. In the plugin UI, copy/generate a channel name and connect.
  3. The MCP server is started by Cursor automatically from mcp.json. To run it manually: npm run start.
  4. In Cursor, call the join_channel tool with the same channel name from step 2. Now both read and write tools are live.

Tools

REST read tools (need FIGMA_TOKEN, work on any file by key, cached)

All read tools accept forceRefresh: true to bypass the cache.

Tool Tier Purpose
get_figma_file 1 Document tree (defaults to depth=2; slimmed to name/lastModified/document)
get_figma_nodes 1 Specific nodes by comma-separated IDs
get_figma_images 1 Render nodes to PNG/JPG/SVG/PDF URLs (short cache)
get_figma_comments 2 File comments
post_figma_comment 2 Add a comment (optionally anchored to a node); not cached
get_figma_components 3 Published components
get_figma_styles 3 Color/text/effect/grid styles
figma_cache_stats - Cache location, entry count, size
figma_cache_clear - Clear cache (all, or by fileKey)

Canvas/plugin tools (need the relay + plugin running, plus join_channel)

create_frame, create_text, create_rectangle, set_fill_color, set_stroke_color, move_node, resize_node, clone_node, delete_node, auto-layout (set_layout_mode, set_padding, set_item_spacing, ...), component instances, annotations, text scanning, and more — see src/talk_to_figma_mcp/server.ts.

Verify

npm run typecheck            # tsc --noEmit
node scripts/relay-smoke.mjs # relay request/response round-trip
node scripts/mcp-smoke.mjs   # boot server over stdio, list tools
npx tsx scripts/cache-smoke.ts # cache hit, 429 backoff, coalescing, stale-while-revalidate

For a full end-to-end check, set FIGMA_TOKEN, start the relay + plugin, join_channel, then call get_figma_file on a known key and create_frame followed by set_fill_color.

Gotchas

  • stdio is sacred. The MCP server must never write to stdout except JSON-RPC. It logs to stderr via a logger. The relay is a separate process, so its stdout logging is fine.
  • WebSocket lives in the plugin UI. The Figma plugin sandbox has no WebSocket; the iframe (ui.html) owns the socket and relays to the main thread.
  • Channel mismatch = silence. If write tools hang, confirm the plugin and join_channel use the same channel and the relay is running.
  • Response size. Keep get_figma_file at low depth; use get_figma_nodes for targeted reads.

Credits

Write bridge and plugin: sonnylazuardi/cursor-talk-to-figma-mcp (MIT). REST read layer and Node port added here.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选