Back to Browse

Wm Figma Vector MCP Server

DesignUse Caution4.8MCP RegistryLocal
Free

Server data from the Official MCP Registry

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

About

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

Security Report

4.8
Use Caution4.8High Risk

The figma-vector-mcp server is a local WebSocket relay between an MCP client and a Figma plugin, with tool schemas that are well-validated via Zod and permissions (local network, Figma canvas manipulation) that match its stated design purpose. No data exfiltration, shell execution, or hardcoded credentials were observed in the reviewed portions; the main concerns are the absence of any authentication on the local relay channel and that the output is truncated, so the review is incomplete. Supply chain analysis found 10 known vulnerabilities in dependencies (0 critical, 5 high severity). Package verification found 1 issue.

3 files analyzed · 15 issues found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Required

This plugin requests these system permissions. Most are normal for its category.

network_websocket

Check that this permission is expected for this type of plugin.

process_spawn

Check that this permission is expected for this type of plugin.

env_vars

Check that this permission is expected for this type of plugin.

file_system

Check that this permission is expected for this type of plugin.

What You'll Need

Set these up before or after installing:

Channel name the Figma plugin joins on the local socket relay (default: figma-vector-mcp)Optional

Environment variable: FVMCP_CHANNEL

Port of the local socket relay (default: 3055)Optional

Environment variable: FVMCP_PORT

How to Install

Add this to your MCP configuration file:

{
  "mcpServers": {
    "io-github-workingmodel-figma-vector-mcp": {
      "env": {
        "FVMCP_PORT": "your-fvmcp-port-here",
        "FVMCP_CHANNEL": "your-fvmcp-channel-here"
      },
      "args": [
        "-y",
        "figma-vector-mcp"
      ],
      "command": "npx"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

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

npm version npm downloads

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

Reviews

No reviews yet

Be the first to review this server!