Figma Vector MCP

Registre officiel Données et bases de données

Let Claude create and edit fully editable vector nodes on the Figma canvas.

Installation

Ajoutez ceci à la configuration MCP de votre client (Claude Desktop : claude_desktop_config.json ; Cursor : .cursor/mcp.json ; VS Code et les autres utilisent la même forme « mcpServers »).

NPM package figma-vector-mcp
Claude Code
claude mcp add figma-vector-mcp -e 'FVMCP_CHANNEL=<FVMCP_CHANNEL>' -e 'FVMCP_PORT=<FVMCP_PORT>' -- npx -y figma-vector-mcp@0.3.3
Configuration JSON (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "figma-vector-mcp": {
            "command": "npx",
            "args": [
                "-y",
                "figma-vector-mcp@0.3.3"
            ],
            "env": {
                "FVMCP_CHANNEL": "<FVMCP_CHANNEL>",
                "FVMCP_PORT": "<FVMCP_PORT>"
            }
        }
    }
}

Variables d'environnement

  • FVMCP_CHANNEL Channel name the Figma plugin joins on the local socket relay (default: figma-vector-mcp)
  • FVMCP_PORT Port of the local socket relay (default: 3055)

Documentation

Tirée du README du projet sur GitHub, actualisée chaque semaine. Les liens ouvrent GitHub.

Sommaire
  1. Figma Vector MCP
  2. Why This Exists
  3. Architecture
  4. AI Agent Quickstart
  5. Setup
  6. Environment Variables
  7. Tool Reference
  8. Sandbox Compatibility
  9. Development
  10. Credits
  11. License

Figma Vector MCP

A Figma plugin + MCP server that lets Claude (or any MCP client) create and manipulate fully-editable vector nodes on the Figma canvas — paths, shapes, gradients, text, effects, image fills, and more — via a local WebSocket relay.

Developed by Working Model Inc

Version 0.3.3 — 58 tools across creation, styling, layout, components, effects, pages, and export.

Why This Exists

cursor-talk-to-figma-mcp is great for reading Figma state and creating basic primitives, but it has no vector path creation, gradient, effects, or compositing tools. This plugin fills that gap:

Capabilitycursor-talk-to-figma-mcpfigma-vector-mcp
Create rectangle / ellipse / frame / text✅✅
Create from SVG string❌✅
Create from path d string❌✅
Create polyline / polygon❌✅
Gradient fills (linear, radial, angular, diamond)❌✅
Image fills (base64 → canvas)❌✅
Effects (shadow, blur)❌✅
Blend modes❌✅
Boolean operations (union, subtract, etc.)❌✅
Auto-layout❌✅
Components + instances❌✅
Font discovery❌✅
Node search❌✅
Multi-page management❌✅
Named node registry❌✅
Batch commands (single round-trip)❌✅
Auto-reconnect + command queue❌✅
Export SVG + PNG❌✅

Architecture

Claude (MCP client)
  ↕ stdio (MCP protocol)
server.ts (MCP server)
  ↕ WebSocket (ws://localhost:3055)
socket.ts (relay — channel-based routing)
  ↕ WebSocket
Figma plugin (ui.html ↔ code.js)
  ↕ postMessage
Figma Plugin API → canvas

The socket relay runs locally. The Figma plugin connects and joins a named channel. The MCP server joins the same channel and sends commands. Results flow back the same path.


AI Agent Quickstart

For AI agents (Claude Code, Cursor, etc.) — the recommended call sequence to start any session:

1. health_check                    → confirm plugin is connected
2. get_document_info               → get page IDs, current page, top-level nodes
3. get_available_fonts             → discover loadable fonts before create_text
4. get_styles                      → load brand colours/text styles if available

Color convention: All RGB values are 0–1 throughout (matching Figma's internal format). r: 1, g: 0, b: 0 = red. Never use 0–255.

Gradient workflow:

1. create_frame({ width, height })          → get frameId
2. set_gradient_fill({ nodeId: frameId, type: "LINEAR", angle: 135,
     stops: [{ color: { r:0.2, g:0.1, b:0.9 }, position: 0 },
             { color: { r:0.9, g:0.2, b:0.4 }, position: 1 }] })

Image fill workflow (with generative AI):

1. Generate image via Replicate/fal.ai → get base64 PNG
2. create_frame({ width: 512, height: 512 })
3. set_image_fill({ nodeId, base64, scaleMode: "FILL" })

Batch compositions — use $prev.id to chain commands without extra round-trips:

{ "commands": [
    { "command": "create_frame", "params": { "width": 400, "height": 300, "name": "Card" } },
    { "command": "set_gradient_fill", "params": { "nodeId": "$prev.id", "type": "LINEAR",
        "stops": [{"color":{"r":0.1,"g":0.1,"b":0.9},"position":0},
                  {"color":{"r":0.8,"g":0.2,"b":0.5},"position":1}] } },
    { "command": "create_text", "params": { "parentId": "$results.0.id",
        "text": "Hello", "fontSize": 32, "x": 24, "y": 24 } }
]}

Known SVG limits: figma.createNodeFromSvg() strips <defs>, gradients, filters, masks, and animations. Use set_gradient_fill for gradients instead of SVG <linearGradient>.

Reconnection: If the plugin disconnects, it auto-reconnects with exponential backoff (1s→30s max) and replays queued commands (up to 30s old). No manual intervention needed for short interruptions.


Setup

1 — Install the plugin
  1. Clone this repo or download the source
  2. In Figma desktop: Plugins → Development → Import plugin from manifest
  3. Select src/figma-plugin/manifest.json
2 — Install the MCP server
npm install -g figma-vector-mcp
# or use without installing via npx / bunx (see MCP config below)
3 — Start the socket relay
bun run socket

Listens on ws://localhost:3055. Auto-start on login (macOS):

./scripts/setup.sh --launchd
4 — Configure the MCP server
# Auto-detect Claude Code / Cursor and write config:
./scripts/setup.sh

# Local build:
./scripts/setup.sh --local

# Install git pre-commit sandbox lint hook:
./scripts/setup.sh --hooks

Manual config (~/.claude/settings.json or ~/.cursor/mcp.json):

{
  "mcpServers": {
    "FigmaVectorMCP": {
      "command": "bunx",
      "args": ["figma-vector-mcp@latest"],
      "env": { "FVMCP_CHANNEL": "figma-vector-mcp" }
    }
  }
}
5 — Connect the plugin
  1. Open your Figma file
  2. Plugins → Development → Figma Vector MCP
  3. Enter server URL (ws://localhost:3055) → Connect
  4. Enter channel name (figma-vector-mcp) → Join

The plugin saves your last URL and channel — pre-filled on next open. Keep the plugin panel open during your session — closing it terminates the WebSocket connection.

6 — Verify
health_check → { "status": "ok", "version": "0.3.3", "currentPage": { ... } }

Environment Variables

VariableDefaultDescription
FVMCP_PORT3055Socket relay port
FVMCP_CHANNELfigma-vector-mcpChannel name — must match the plugin
FVMCP_TIMEOUT_MS10000Default command timeout (ms)

Per-tool timeout overrides: health_check → 3s, export_node_as_png → 30s, export_node_as_svg → 15s, create_batch → 60s.


Tool Reference

Connection & Health
ToolDescriptionKey Params
health_checkPing plugin; confirm connectivity—
join_channelJoin a named channelchannel
Vector Creation
ToolDescriptionKey Params
create_vector_from_svgPlace editable vector from SVG stringsvg, x, y, name, parentId
create_pathVector from SVG d path stringd, x, y, fillColor, strokeColor, strokeWeight
create_polylineVector from [x,y][] point pairspoints, closed, strokeColor, strokeWeight
Primitives
ToolDescriptionKey Params
create_frameContainer framewidth, height, x, y, fillColor
create_rectangleRectanglewidth, height, x, y, fillColor
create_ellipseEllipse / circlewidth, height, x, y, fillColor
create_textText node with optional fixed-width columntext, fontSize, fontFamily, fontStyle, fillColor, width, height, textAutoResize
Fills & Colour
ToolDescriptionKey Params
set_fill_colorSolid RGBA fill (0–1)nodeId, r, g, b, a
set_gradient_fillGradient fill — LINEAR, RADIAL, ANGULAR, DIAMONDnodeId, type, stops, angle, center, gradientTransform
set_image_fillBase64 image as fillnodeId, base64, scaleMode, opacity
Stroke
ToolDescriptionKey Params
set_strokeFull stroke controlnodeId, color, weight, position, dashPattern, lineCap, lineJoin
set_stroke_colorQuick stroke colour + weightnodeId, r, g, b, a, weight
Effects & Compositing
ToolDescriptionKey Params
set_effectDrop shadow, inner shadow, blur, background blurnodeId, effects[] (type, color, offset, blur, spread), mode (REPLACE \APPEND)
set_blend_modeLayer blend modenodeId, mode (NORMAL, MULTIPLY, SCREEN, OVERLAY…)
Node Manipulation
ToolDescriptionKey Params
set_corner_radiusCorner radius — uniform or per-cornernodeId, radius or topLeft, topRight, bottomLeft, bottomRight
set_opacityOpacity 0–1nodeId, opacity
set_text_styleModify text properties + text box sizenodeId, fontSize, fontFamily, fontStyle, letterSpacing, lineHeight, textAlign, fillColor, width, height, textAutoResize
rename_nodeRename a nodenodeId, name
set_visibilityShow or hide a nodenodeId, visible
reorder_nodeChange Z-order within parentnodeId, action (BRING_TO_FRONT / SEND_TO_BACK / BRING_FORWARD / SEND_BACKWARD) or index
move_nodeRepositionnodeId, x, y
resize_nodeResizenodeId, width, height
delete_nodeRemove from canvasnodeId
clone_nodeDuplicate, optionally repositionnodeId, x, y, parentId
group_nodesGroup nodesnodeIds[], name, parentId
ungroup_nodesUngroupnodeId
boolean_operationUnion, subtract, intersect, excludenodeIds[], operation, name
create_maskClip mask — maskNode clips targetNodemaskNodeId, targetNodeId, name
Layout
ToolDescriptionKey Params
set_auto_layoutEnable / configure auto-layoutnodeId, direction, spacing, padding, primaryAxisAlign, counterAxisAlign, primaryAxisSizingMode, counterAxisSizingMode, wrap
set_layout_gridColumn / row / grid guides on a framenodeId, grids[] (pattern, count, gutterSize, sectionSize, alignment, color)
batch_set_propertiesBulk update fill/stroke/opacity/position/sizeoperations[] (nodeId + any subset of properties)
Components
ToolDescriptionKey Params
create_componentConvert frame/group to componentnodeId, name
create_instancePlace component instancecomponentId, x, y, parentId
get_componentsList all local components—
get_library_componentsSearch local components by namequery
Document & Pages
ToolDescriptionKey Params
get_document_infoDocument name, pages, current page children—
get_selectionCurrently selected nodes—
get_node_infoFull node detail: fills, strokes, layout, text, constraintsnodeId
set_focusScroll viewport to node and select itnodeId
find_nodesSearch by name and/or typequery, type, pageId, recursive
get_page_listAll pages—
switch_pageActivate a pagepageId or pageName
create_pageCreate a new pagename
duplicate_frame_to_pageCopy node to another pagenodeId, targetPageId, x, y
Node Registry
ToolDescriptionKey Params
register_nodeSave named alias for a node ID (persists in document)alias, nodeId
resolve_nodeLook up node ID by aliasalias
Color Registry
ToolDescriptionKey Params
register_colorSave a named color to the document palette (0–1)alias, r, g, b, a
resolve_colorLook up a color by aliasalias
list_colorsList all registered colors in the document—
Styles & Fonts
ToolDescriptionKey Params
get_stylesAll local paint and text styles—
apply_styleApply document style to nodenodeId, styleId, styleType
get_available_fontsList loadable fonts; filter by namequery
Export
ToolDescriptionKey Params
export_node_as_svgExport node as SVG stringnodeId
export_node_as_pngExport as base64 PNGnodeId, scale (default 2)
screenshot_current_pageExport full page as base64 PNGscale
Batch
ToolDescriptionKey Params
create_batchRun multiple commands in one round-trip. Supports $prev.id and $results.N.field tokens for chaining.commands[] (command, params)

Sandbox Compatibility

The plugin main thread (code.js) runs in Figma's restricted QuickJS sandbox. The UI (ui.html) is a normal browser context and is not affected.

Run bun run lint:plugin to check code.src.js for violations before building. A pre-commit hook can be installed via ./scripts/install-hooks.sh.

Banned in code.js
API / SyntaxSafe replacement
import / exportInline all deps
x ?? y(x != null) ? x : y
obj?.propobj && obj.prop
{ ...obj } / [ ...arr ]Object.assign({}, obj) / Array.from(arr)
localStoragefigma.clientStorage
TextDecoderChunked String.fromCharCode
fetch()Not available in main thread
figma.getNodeById() (sync)await figma.getNodeByIdAsync()
figma.currentPage = x (sync assign)await figma.setCurrentPageAsync(x)
figma.getLocalPaintStyles() (sync)await figma.getLocalPaintStylesAsync()
figma.getLocalTextStyles() (sync)await figma.getLocalTextStylesAsync()
figma.root.findAllWithCriteria() without page loadawait figma.loadAllPagesAsync() first
SVG compatibility (create_vector_from_svg)
FeatureStatus
<rect>, <polygon>, <polyline>, <path>, <circle>, <ellipse>✅
fill, stroke, stroke-width, stroke-linecap, stroke-linejoin✅
viewBox, width, height✅
<linearGradient> / <radialGradient> in <defs>❌ Stripped — use set_gradient_fill
<filter>, <mask>, <pattern>❌ Stripped
<animate>, <animateTransform>❌ Stripped
<script>, <foreignObject>❌ Stripped
fill="url(#...)" references❌ Replaced with fill="none"

Development

bun install              # install deps
bun run socket           # start relay on :3055
bun run build            # build MCP server → dist/server.js
bun run build:plugin     # build plugin: code.src.js → code.js
bun run lint:plugin      # check code.src.js for sandbox violations
./scripts/install-hooks.sh  # install pre-commit lint hook
Plugin workflow
  1. Edit src/figma-plugin/code.src.js
  2. bun run lint:plugin — catch sandbox violations before building
  3. bun run build:plugin — esbuild outputs code.js (ES2017)
  4. Close and reopen the plugin panel in Figma to load the new code.js

Credits

  • Socket relay (src/socket.ts) adapted from cursor-talk-to-figma-mcp — Copyright (c) 2025 sonnylazuardi, MIT License
  • setCharacters helpers in code.src.js adapted from the same project — Copyright (c) 2025 sonnylazuardi, MIT License

License

MIT © Working Model — see LICENSE and THIRD_PARTY_NOTICES.md.


Developed by Working Model Inc

Questions fréquentes

Qu'est-ce que Figma Vector MCP ?

Let Claude create and edit fully editable vector nodes on the Figma canvas.

Comment installer Figma Vector MCP ?

Il s'exécute sur votre machine. Dans Claude Code : claude mcp add figma-vector-mcp -e 'FVMCP_CHANNEL=<FVMCP_CHANNEL>' -e 'FVMCP_PORT=<FVMCP_PORT>' -- npx -y figma-vector-mcp@0.3.3. Pour les autres clients, collez la configuration JSON de cette page dans leurs réglages MCP.

Faut-il une clé API pour Figma Vector MCP ?

Son entrée au registre n'indique aucune clé ni secret obligatoire. Certaines fonctions peuvent tout de même demander un compte auprès du service auquel il se connecte.

Figma Vector MCP est-il open source ?

Oui. Son code est sur GitHub sous licence MIT.

Qui maintient Figma Vector MCP ?

Il est publié par workingmodel. AI.tn le référence sans le maintenir ni le recommander.

Issu du registre MCP officiel. Être listé n'est pas une recommandation : vérifiez le code et les permissions d'un serveur avant de lui donner accès à vos données.