/ Directory / Playground / cursor-talk-to-figma-mcp
● Community grab ⚡ Instant

cursor-talk-to-figma-mcp

by grab · grab/cursor-talk-to-figma-mcp

Let Cursor or Claude read and edit your live Figma document — rename layers in bulk, inject copy, build components, all via chat.

A TypeScript MCP server plus a companion Figma plugin that talk over WebSocket. Exposes 40+ tools across selection, annotations, text, auto-layout, styling, components, and export. Read-first so you can explore, then bulk-edit at agent speed.

Why use it

Key features

Live Demo

What it looks like in practice

cursor-talk-to-figma.replay ▶ ready
0/0

Install

Pick your client

~/Library/Application Support/Claude/claude_desktop_config.json  · Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "cursor-talk-to-figma": {
      "command": "npx",
      "args": [
        "-y",
        "cursor-talk-to-figma-mcp"
      ],
      "_inferred": true
    }
  }
}

Open Claude Desktop → Settings → Developer → Edit Config. Restart after saving.

~/.cursor/mcp.json · .cursor/mcp.json
{
  "mcpServers": {
    "cursor-talk-to-figma": {
      "command": "npx",
      "args": [
        "-y",
        "cursor-talk-to-figma-mcp"
      ],
      "_inferred": true
    }
  }
}

Cursor uses the same mcpServers schema as Claude Desktop. Project config wins over global.

VS Code → Cline → MCP Servers → Edit
{
  "mcpServers": {
    "cursor-talk-to-figma": {
      "command": "npx",
      "args": [
        "-y",
        "cursor-talk-to-figma-mcp"
      ],
      "_inferred": true
    }
  }
}

Click the MCP Servers icon in the Cline sidebar, then "Edit Configuration".

~/.codeium/windsurf/mcp_config.json
{
  "mcpServers": {
    "cursor-talk-to-figma": {
      "command": "npx",
      "args": [
        "-y",
        "cursor-talk-to-figma-mcp"
      ],
      "_inferred": true
    }
  }
}

Same shape as Claude Desktop. Restart Windsurf to pick up changes.

~/.continue/config.json
{
  "mcpServers": [
    {
      "name": "cursor-talk-to-figma",
      "command": "npx",
      "args": [
        "-y",
        "cursor-talk-to-figma-mcp"
      ]
    }
  ]
}

Continue uses an array of server objects rather than a map.

~/.config/zed/settings.json
{
  "context_servers": {
    "cursor-talk-to-figma": {
      "command": {
        "path": "npx",
        "args": [
          "-y",
          "cursor-talk-to-figma-mcp"
        ]
      }
    }
  }
}

Add to context_servers. Zed hot-reloads on save.

claude mcp add cursor-talk-to-figma -- npx -y cursor-talk-to-figma-mcp

One-liner. Verify with claude mcp list. Remove with claude mcp remove.

Use Cases

Real-world ways to use cursor-talk-to-figma-mcp

How to update every text layer in a Figma doc from one prompt

👤 Designers + PMs running copy reviews or localization ⏱ ~20 min intermediate

When to use: You have a spec that renames 50 strings and you do not want to click 50 times.

Prerequisites
  • Bun installed — curl -fsSL https://bun.sh/install | bash
  • Figma desktop open with the plugin linked — Plugins > Development > Link existing plugin > point to src/cursor_mcp_plugin/manifest.json
  • WebSocket bridge running — bun run start in the cloned repo
Flow
  1. Join the channel from the plugin panel
    Join Figma channel X7F2 and list all text nodes on the current page.✓ Copied
    → List of node ids with current text
  2. Map old copy to new copy
    Here is a CSV of old_string,new_string. For every text node whose content matches an old_string, replace with the new_string using set_multiple_text_contents.✓ Copied
    → Count of updates applied, diff preview
  3. Spot-check visually
    Export the three frames that had the most edits as PNGs so I can review.✓ Copied
    → PNG URLs / file paths

Outcome: A copy-reviewed file with every string updated and a before/after export to prove it.

Pitfalls
  • Plugin disconnects mid-operation — set_multiple_text_contents is idempotent — re-run with the same mapping; already-correct nodes are skipped
  • Text in components vs instances confuses updates — Use get_instance_overrides first to see which instances override the base text
Combine with: filesystem

How to annotate a Figma spec from a PRD in one shot

👤 Design-engineers pairing docs with mocks ⏱ ~25 min intermediate

When to use: Your PRD has 'the CTA should say X, include Y tooltip copy' and you want those as Figma annotations.

Flow
  1. Share the PRD
    Here is the PRD [paste]. Extract every UI annotation requirement.✓ Copied
    → Structured list of {node_hint, annotation_text}
  2. Map hints to actual nodes
    Use get_selection and scan_nodes_by_types to match each annotation to a concrete node id in the current page.✓ Copied
    → Pairs of node_id + annotation ready
  3. Apply annotations
    Apply them with set_multiple_annotations.✓ Copied
    → Annotations visible in the plugin overlay

Outcome: A self-documenting Figma file engineers can read without switching tabs.

Pitfalls
  • Claude matches the wrong node when several share a name — Include parent frame names as disambiguation hints
Combine with: notion · github

How to generate component variants (dark mode, sizes) programmatically

👤 Design systems teams ⏱ ~20 min advanced

When to use: You need to clone a base button into 12 variants and tweak fills/strokes.

Flow
  1. Clone the base node
    Clone the Button/Primary frame 4 times and arrange horizontally with 16px gap.✓ Copied
    → 4 new nodes in the doc
  2. Retint fills/strokes
    For each clone, set_fill_color to the 500, 600, 700, 800 shades of #3B82F6.✓ Copied
    → Visible color progression
  3. Convert to variants
    Group them as a component set named 'Button / Intensity'.✓ Copied
    → New component set appears in assets

Outcome: A ready-to-use variant set in your design system.

Pitfalls
  • Color tokens differ from raw hex — If your system uses variables, use set_fill_color with the variable id not the raw hex

How to export every marked frame as PNG for dev handoff

👤 Design-engineers preparing a handoff doc ⏱ ~10 min beginner

When to use: Before a sprint kickoff or a client review.

Flow
  1. Find frames with a handoff tag
    Scan nodes of type FRAME on the current page whose name starts with '[HANDOFF]'.✓ Copied
    → List of target frames
  2. Export at 2x
    Export each as PNG at 2x and save to /handoff/2026-04/.✓ Copied
    → File paths returned

Outcome: A timestamped handoff folder ready to drop into Notion or Linear.

Combine with: filesystem · notion

Combinations

Pair with other MCPs for X10 leverage

cursor-talk-to-figma + notion

Sync design annotations into a Notion spec page for engineers

Extract every annotation on the current Figma page and mirror them into the Notion doc 'Checkout Spec v3' as a checklist.✓ Copied
cursor-talk-to-figma + filesystem

Export frames into a local handoff folder versioned by date

Export every [HANDOFF] frame to /design-handoff/2026-04/ as PNG 2x.✓ Copied
cursor-talk-to-figma + github

Pair a design change with a code PR reference

Add an annotation on the CTA button linking to PR #4421 in frontend repo.✓ Copied

Tools

What this MCP exposes

ToolInputsWhen to callCost
get_document_info Orient yourself in a new file free
get_selection Operate on what the user just clicked free
scan_text_nodes root_id?: str Before bulk copy changes free
set_multiple_text_contents updates: {id, text}[] Batch text replacement free
set_fill_color id: str, color: {r,g,b,a} Restyle a node free
set_layout_mode id, mode: 'HORIZONTAL'|'VERTICAL'|'NONE' Toggle auto-layout free
create_component_instance component_key: str, parent_id: str, position?: {x,y} Drop a library component onto the canvas free
set_multiple_annotations annotations: {id, text}[] Batch spec annotations free
export_node_as_image id: str, format: 'PNG'|'SVG'|'JPG', scale?: number Handoff, reviews, inline previews free
join_channel channel: str First call after launching the plugin free

Cost & Limits

What this costs to run

API quota
Figma has no published rate limit for plugin actions; practical cap is WebSocket throughput
Tokens per call
Node info: 100-1500 tokens depending on children
Monetary
Free (Figma account required; free plan works)
Tip
Always scope scans to a specific root node id; page-wide scans on big files blow up the context.

Security

Permissions, secrets, blast radius

Minimum scopes: Figma plugin running in desktop/web app; no API token needed
Credential storage: None — plugin runs in-process in Figma; MCP talks over localhost WebSocket
Data egress: Figma document nodes flow from the plugin to your local MCP and then to your chosen LLM. Sensitive designs leave your machine only through the LLM call.
Never grant: Do not expose the WebSocket port beyond localhost

Troubleshooting

Common errors and fixes

Plugin cannot connect to WebSocket

Ensure bun run start is active and the plugin channel id matches what the agent joined.

Verify: bun --version && lsof -i :3055
set_multiple_text_contents only updates some nodes

Nodes inside locked layers or components are skipped. Unlock or target the instance override.

Figma plugin shows 'manifest not found'

Re-link via Plugins > Development > Link existing plugin > pick manifest.json from src/cursor_mcp_plugin/.

Exports return empty URLs

Some nodes (mask groups, certain effects) cannot render server-side. Flatten first or export as SVG.

Alternatives

cursor-talk-to-figma-mcp vs others

AlternativeWhen to use it insteadTradeoff
Official Figma Dev Mode MCPYou have Figma paid Dev Mode seats and want official supportRead-only; no bulk editing
Framelink Figma MCPYou prefer a read-only REST-API-based serverNo mutation, no WebSocket plugin needed but cannot edit

More

Resources

📖 Read the official README on GitHub

🐙 Browse open issues

🔍 Browse all 400+ MCP servers and Skills