Back to Discover

figma-mcp-go

connector

tunglt1810

Figma MCP server with full read/write access via plugin bridge — no API token or rate limits.

View on GitHub
0 starsSynced Aug 17, 2026

Install to Claude Code

/plugin marketplace add tunglt1810/figma-mcp-go

README

figma-mcp-go

Figma MCP — Local Plugin Integration tunglt1810/figma-mcp-go server

npm version MCP Registry License: MIT GitHub stars

Open-source Figma MCP server with full read/write access via plugin. Turn text into designs and designs into real code. Works with Cursor, Claude, GitHub Copilot, and any MCP-compatible AI tool.

Highlights

  • Operates locally via the Figma Plugin API (no REST API token required)
  • Real-time execution directly on your local machine
  • Read and Write live Figma data via plugin bridge — 63 tools total
  • Full design automation — styles, variables, components, prototypes, content, and transactional batch pipelines
  • Design strategies included — read_design_strategy, design_strategy, and more prompts built in

Styles, Variables, Components, Prototypes, and Content

https://github.com/user-attachments/assets/eae41471-fc72-4574-8261-4f42c38b8c99

Text to Design, Design to Code

https://github.com/user-attachments/assets/17bda971-0e83-4f18-8758-8ac2b8dcba62


Why this exists

Most Figma MCP servers rely on the cloud-based Figma REST API.

While the REST API is excellent for server-to-server integrations, experimenting with AI tools often involves making hundreds of rapid tool calls per session. A cloud-based approach can introduce network latency and overhead.

This project takes a different approach by running as a local Figma Plugin. By bridging directly to the Figma Plugin API on your desktop, it provides instant, real-time read/write access to your active documents without relying on external cloud APIs or requiring an API token.


Installation & Setup

Install via npx — no build step required. Watch the setup video or follow the steps below.

Watch the video

1. Configure your AI tool

Claude Code CLI

claude mcp add -s project figma-mcp-go -- npx -y @tunglt1810/figma-mcp-go@latest

Codex CLI

codex mcp add figma-mcp-go -- npx -y @tunglt1810/figma-mcp-go@latest

.mcp.json (Claude and other MCP-compatible tools)

{
  "mcpServers": {
    "figma-mcp-go": {
      "command": "npx",
      "args": ["-y", "@tunglt1810/figma-mcp-go"]
    }
  }
}

.vscode/mcp.json (Cursor / VS Code / GitHub Copilot)

{
  "servers": {
    "figma-mcp-go": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@tunglt1810/figma-mcp-go"
      ]
    }
  }
}

2. Install the Figma plugin

  1. In Figma Desktop: Plugins → Development → Import plugin from manifest
  2. Select manifest.json from the plugin.zip
  3. Run the plugin inside any Figma file

3. Running more than one AI tool at once (optional)

Every MCP client starts its own copy of the server, but only one process can hold the plugin connection on a given port. There are two ways to share, and they do different things.

Same Figma file, no configuration. Leave the default config everywhere. The first process to bind port 1994 owns the WebSocket to the plugin; the others detect the port is taken and proxy their tool calls to it over HTTP. Every client drives the one file the plugin is open in. If the process holding the port exits, another takes over within a few seconds.

Different Figma files, one port each. Give each client its own port and point a separate plugin instance at it:

{
  "mcpServers": {
    "figma-mcp-go": {
      "command": "npx",
      "args": ["-y", "@tunglt1810/figma-mcp-go", "--port", "1995"]
    }
  }
}

Then open the plugin in the second Figma file and set the port to match under the settings gear. Each client now talks to its own file, with no proxying.

Note that the plugin stores host and port in figma.clientStorage, which is shared across files — changing the port makes it the default the next time you open the plugin anywhere, so expect to set it on whichever instance should use 1994.

--ip moves the listener off 127.0.0.1 (use 0.0.0.0 to accept connections from another machine).


Upgrading

Re-download the plugin when you update the server. The server updates itself through npx, but the Figma plugin is installed by hand, so the two can drift apart. A plugin older than the server will reject commands it does not know with Unknown request type.

Breaking changes in 0.1.0

Eight single-purpose tools were replaced by one. Each took nodeIds plus a single property, and they are now combinations of set_node_properties:

RemovedReplacement
set_visibleset_node_properties({ nodeIds, visible })
lock_nodes / unlock_nodesset_node_properties({ nodeIds, locked })
set_opacityset_node_properties({ nodeIds, opacity })
rotate_nodesset_node_properties({ nodeIds, rotation })
set_blend_modeset_node_properties({ nodeIds, blendMode })
set_constraintsset_node_properties({ nodeIds, constraints: { horizontal, vertical } })
reorder_nodesset_node_properties({ nodeIds, order })

Properties can be combined, so what used to take several calls and several undo entries now takes one of each.

Eighteen more tools were merged into four, each selecting between the old tools with one argument. An argument belonging to a different variant is rejected with a message naming it, rather than being ignored:

RemovedReplacement
create_framecreate_node({ type: "FRAME", … })
create_rectanglecreate_node({ type: "RECTANGLE", … })
create_ellipsecreate_node({ type: "ELLIPSE", … })
create_starcreate_node({ type: "STAR", … })
create_polygoncreate_node({ type: "POLYGON", … })
create_linecreate_node({ type: "LINE", … })
create_sectioncreate_node({ type: "SECTION", … })
set_fillsset_paint({ type: "SOLID", color })
set_strokesset_paint({ type: "SOLID", target: "stroke", color, strokeWeight })
set_gradient_fillsset_paint({ type: "GRADIENT_LINEAR" | "GRADIENT_RADIAL", stops, geometry })
create_paint_stylecreate_style({ type: "PAINT", name, color })
create_text_stylecreate_style({ type: "TEXT", name, … })
create_effect_stylecreate_style({ type: "EFFECT", name, effectType, … })
create_grid_stylecreate_style({ type: "GRID", name, … })
add_pagemanage_page({ action: "add", name, index })
delete_pagemanage_page({ action: "delete", pageId | pageName })
rename_pagemanage_page({ action: "rename", pageId | pageName, newName })
navigate_to_pagemanage_page({ action: "navigate", pageId | pageName })

Two things changed behaviour rather than just name. create_node({type:"ELLIPSE"}) honours startAngle, endAngle and innerRadiusRatio, which create_ellipse declared but ignored — arcs and rings came out as plain ellipses. And name now works on stars, polygons and lines, which read it but never declared it.

create_effect_style's type argument is effectType under create_style, because type names the kind of style. Gradients can only target a fill; set_paint says so rather than accepting target: "stroke" and doing nothing.


Available Tools

Write — Batch & Transactions

ToolDescription
batch_execute_pipelineExecute a transactional batch pipeline of mutation steps in Figma with stateful variable binding and rollback

Write — Create

ToolDescription
create_nodeCreate a FRAME, RECTANGLE, ELLIPSE, STAR, POLYGON, LINE, or SECTION
create_textCreate a text node (font loaded automatically)
import_imageDecode base64 image and place it as a rectangle fill
create_componentConvert an existing FRAME node into a reusable component
create_component_instanceCreate an instance of a component (local or library)
create_connectorCreate a Connector line between nodes (FigJam only)

Write — Modify

ToolDescription
set_textUpdate text content of an existing TEXT node
set_paintPaint a node's fill or stroke — solid, linear gradient, or radial gradient
set_corner_radiusSet corner radius — uniform or per-corner
set_auto_layoutSet or update auto-layout (flex) properties on a frame
set_node_propertiesSet any combination of visibility, lock, opacity, rotation, blend mode, constraints, and z-order on one or more nodes
set_instance_overridesUpdate Component Properties (variants, booleans, text) on a component instance
set_annotationsSet Dev Mode Annotations on a node (requires paid Dev Mode seat)
move_nodesMove nodes to an absolute x/y position
resize_nodesResize nodes by width and/or height
rename_nodeRename a node
clone_nodeClone a node, optionally repositioning or reparenting
reparent_nodesMove nodes to a different parent frame, group, or section
batch_rename_nodesBulk rename nodes via find/replace, regex, or prefix/suffix
find_replace_textFind and replace text across all TEXT nodes in a subtree or page; supports regex

Write — Delete

ToolDescription
delete_nodesDelete one or more nodes permanently
clear_annotationsClear all Dev Mode Annotations from one or more nodes

Write — Prototype

ToolDescription
set_reactionsSet prototype reactions (triggers + actions) on a node; mode replace or append
remove_reactionsRemove all or specific reactions by zero-based index from a node

Write — Styles

ToolDescription
set_effectsApply drop shadow / blur effects directly on a node (no style required)
create_styleCreate a named PAINT, TEXT, EFFECT, or GRID style
update_paint_styleRename or recolor an existing paint style
apply_style_to_nodeApply an existing local style to a node, linking it to that style
delete_styleDelete any style (paint, text, effect, or grid) by ID

Write — Variables

ToolDescription
create_variable_collectionCreate a new local variable collection with an optional initial mode
add_variable_modeAdd a new mode to an existing collection (e.g. Light/Dark)
create_variableCreate a variable (COLOR/FLOAT/STRING/BOOLEAN) in a collection
set_variable_valueSet a variable's value for a specific mode
bind_variable_to_nodeBind a variable to a node property — supports fillColor, strokeColor, visible, opacity, rotation, width, height, corner radii, spacing, and more
delete_variableDelete a variable or an entire collection

Write — Pages

ToolDescription
manage_pageAdd, delete, rename, or navigate to a page (action selects which)

Write — Components & Navigation

ToolDescription
group_nodesGroup two or more nodes into a GROUP
ungroup_nodesUngroup GROUP nodes, moving children to the parent
swap_componentSwap the main component of an INSTANCE node
detach_instanceDetach component instances, converting them to plain frames

Read — Document & Selection

ToolDescription
get_documentFull current page tree
get_metadataFile name, pages, current page
get_pagesAll pages (IDs + names) — lightweight, no tree loading
get_selectionCurrently selected nodes
get_nodeSingle node by ID
get_nodes_infoMultiple nodes by ID
get_design_contextDepth-limited tree with detail level (minimal/compact/full)
search_nodesFind nodes by name substring and/or type within a subtree
scan_text_nodesAll text nodes in a subtree
scan_nodes_by_typesNodes matching given type list
get_viewportCurrent viewport center, zoom, and visible bounds

Read — Styles & Variables

ToolDescription
get_stylesPaint, text, effect, and grid styles
get_variable_defsVariable collections and values
get_local_componentsAll components + component sets with variant properties
get_instance_overridesGet component properties and current values of an instance
get_annotationsDev-mode annotations
get_fontsAll fonts used on the current page, sorted by frequency
get_reactionsPrototype/interaction reactions on a node

Export

ToolDescription
get_screenshotBase64 image export of any node
save_screenshotsExport images to disk (server-side, no API call)
export_frames_to_pdfExport multiple frames as a single multi-page PDF file saved to disk
export_tokensExport design tokens (variables + paint styles) as JSON or CSS

MCP Prompts

PromptDescription
read_design_strategyBest practices for reading Figma designs
design_strategyBest practices for creating and modifying designs
text_replacement_strategyChunked approach for replacing text across a design
annotation_conversion_strategyConvert manual annotations to native Figma annotations
swap_overrides_instancesTransfer overrides between component instances
reaction_to_connector_strategyMap prototype reactions into interaction flow diagrams

Contributing

Issues and PRs are welcome.

Star History

Star History Chart

Rendered live from tunglt1810/figma-mcp-go's GitHub README — not stored, always reflects the source repo.

1 Install Method

NameDescriptionCategorySource
npm packageInstall via npm (stdio transport)mcp-server@tunglt1810/figma-mcp-go

0 Comments

Login required
Log in to post a comment or update on this repo.

No comments yet — be the first to share an update.