pholly-figma-mcp
Provides a local-first MCP bridge for live Figma documents, enabling document inspection (selection, styles, variables, design tokens), node editing (fills, strokes, effects, visibility), component/instance authoring, variable creation/binding, tree rendering with reconciliation, asset export, and search/find operations.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pholly-figma-mcpInspect the current selection and describe the UI design."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
pholly-figma-mcp
Local-first MCP bridge for live Figma documents. A Figma plugin and a local WebSocket server connect your MCP client to your design files without using the Figma REST API.
See CHANGELOG.md for release history.
Status
0.3.0. This is the first source release after the security fix pass. npm still serves 0.2.1; that published package sends the raw bridge token on the WebSocket and follows an unproven local port. Do not install from npm until a release matching this source is published. The changelog calls out the breaking changes.
The source supports MCP stdio, the live plugin bridge, multi-file routing, document/style/variable inspection, common node editing, image creation, component and instance authoring, variable creation and binding, batch edits, declarative tree rendering, gradients, effects, strokes, visibility, search, screenshots, and design-token extraction.
Related MCP server: FigmaExporterMcp
Build and run
npm install
npm run build # compiles the packages and copies the plugin into apps/server/plugin
npm run setup # creates ./pholly-figma-plugin with the bridge token and port stamped inImport pholly-figma-plugin/manifest.json into Figma through Plugins → Development → Import plugin from manifest, then run it in a design file. setup is required: it stamps the machine's bridge token and the bridge port into the plugin.
If the token or port changes, run setup again, delete the old entry under Plugins → Development, and re-import. Figma caches a development plugin by id, and the id changes when the token changes.
{
"pholly-figma": {
"type": "local",
"command": ["node", "/absolute/path/to/pholly-figma-mcp/apps/server/dist/index.js"],
"enabled": true
}
}For clients that use command/args (for example Codex-style JSON):
{
"pholly-figma": {
"command": "node",
"args": ["/absolute/path/to/pholly-figma-mcp/apps/server/dist/index.js"]
}
}Codex itself normally uses TOML. Use the same command and arguments in whichever shape your client documents. Claude Code, Claude Desktop, Cursor, VS Code, Gemini CLI, and Warp are not shipped with a config file; they need the same node <abs>/apps/server/dist/index.js stdio entry.
Your MCP client starts the server automatically. For bridge-only debugging you may run npm start; do not also launch a second manual copy unless you are testing follower behavior. The default port is 1995. /ping is open; the other endpoints require the bearer token or the plugin handshake. Check the default with curl http://127.0.0.1:1995/ping.
Architecture
MCP client ──stdio──> Node server ──WebSocket──> Figma plugin ──> Figma Plugin APIThe project is MIT licensed. See SECURITY.md for how to report a vulnerability and CONTRIBUTING.md for the development and release process.
Notable tools
inspect_selectionreturns a detailed textual UI specification and an optional native screenshot.export_selection_assetsextracts raster fills and vector candidates into a project-relative directory, without overwriting different existing files.render_designcreates or reconciles a nested design tree. Use stablekeyvalues withmode: "reconcile". Reconcile deletes keyed children that are present in the parent but absent from a suppliedchildrenarray only whenconfirmDelete: true; otherwise it refuses before changing anything. Omittingchildrendeletes nothing.create_component,create_instance,set_instance_properties,swap_instance_component, anddetach_instancecover the common component workflow.create_variable_collection,create_variable,set_variable_values, andbind_variablecover local tokens. COLOR variables accept a hex string or an{r,g,b,a}object.batchruns non-destructive operations in sequence. It rejectsdelete_nodes, nestedbatch,undo,commit_undo,clear_changes,create_image,export_selection_assets,save_screenshots, andlist_files. A failed operation still leaves earlier operations applied, so keep batches small and idempotent where it matters.validate_designchecks a tree before rendering it.commitUndo: falseonrender_designskips the undo snapshot; the default commits one step.Editing:
set_gradient_fill,set_effects,set_stroke_properties,set_node_visibility,set_solid_fill(hex or rgba), andset_text_properties(font, size, alignment, color, and bounds). Mixed-font text is loaded per range rather than through a singlefontName.Search:
find_nodesandfind_textmatch by substring or/regex/, with an optional type filter and page. Patterns are capped at 80 characters.Session:
get_path,undo,redo(always reports that the Plugin API has no redo),get_changes, andclear_changes.undotriggers the editor undo; it is not scoped to the bridge, so it can undo the user's last edit.Export and analysis:
save_screenshotswrites explicit node lists topublic/figma-screenshots/, andextract_design_tokenssummarizes a page's typography, colors, radii, spacing, and opacities.Inspection values:
get_stylesincludes the paint, font, effect, and grid payloads.get_design_contexterrors on an unknown node id instead of silently returning the page.
First-use checklist
Run
npm install && npm run build && npm run setup.Import
pholly-figma-plugin/manifest.jsoninto Figma.Run the plugin in every file the agent should access.
Restart the MCP client after adding the configuration.
Ask the agent to call
list_files; pass the returnedfileKeyfor multi-file work.
The plugin must be running in Figma's Design editor for write operations. Dev Mode is not an editor target in the manifest, so the plugin is not available there.
Security
The bridge is local-first and locked down by default:
The HTTP server and WebSocket bridge bind to
127.0.0.1and::1only. The IPv6 listener is best effort, so the plugin keeps working on IPv4-only machines.A per-machine bearer token guards
/files,/rpc, and/mcp. The token lives at$XDG_CONFIG_HOME/pholly-figma-mcp/token(falling back to~/.config/pholly-figma-mcp/token) and can be overridden withPHOLLY_TOKEN.The plugin proves it knows the token with an HMAC challenge. The raw token is not sent on the WebSocket.
The server also proves it knows the token:
readycarries a MAC over both the plugin's challenge nonce and a server nonce that the plugin sent. Until that MAC verifies, the plugin drops any frame with amethod. A process that merely acceptsws://localhost:1995cannot make the plugin read or edit a document.Setup stamps
ws://localhost:<port>and the matchingnetworkAccessallowlist into the plugin, so a non-defaultPHOLLY_PORTstill matches. The host name islocalhostbecause Figma's manifest validator rejects IP literals inallowedDomains; the server binds both loopback addresses so the name cannot split across IPv4 and IPv6.MAC domains are separate for
prove,hello, andready. A/proveMAC cannot register a plugin, and the file keyleaderis reserved and rejected.HTTP requests with a missing or non-local
Hostheader are refused (blocks DNS rebinding), and WebSocket upgrades from non-localOrigins are rejected.A connected file key can only be claimed by the plugin that currently owns it. A second window is told the file is busy.
create_imagefetches http(s) images in the bridge and blocks loopback, private, link-local, and metadata addresses on the first request and on every redirect, with a 15 MB cap. SetPHOLLY_ALLOW_PRIVATE_IMAGE_HOSTS=1only if you deliberately need a local image server.Exported assets and screenshots must stay inside the server process working directory after resolving symlinks. Identical bytes are deduplicated; different bytes are never overwritten.
On Windows,
0600is not an ACL.setupand the token file additionally restrict access to the current user withicacls(/inheritance:r, one full-control entry). This is best effort; check the ACL if the machine is shared.On Unix, the config directory is mode
0700and the token is mode0600. On Windows, treat that as advisory and rely on the ACL.
A process that binds port 1995 before the bridge still receives the plugin connection for as long as it holds the port, but it cannot pass the ready MAC, so the plugin will not run a command for it. A follower process re-proves the leader before every send and stops if the proof fails.
Privacy
This bridge does not send telemetry. When an agent calls an inspection or export tool, the node tree, text, and images from the open Figma file are returned to the MCP client over stdio. Whatever model or service that client uses receives that data. Review your client's data handling before running this on confidential files. The bridge does not call Figma's REST API and does not send design data to Figma.
Requirements
Node.js >= 20. The compiled server runs on Node 20; tests use
tsxso they do not require Node's experimental type stripping.The Figma desktop app with the plugin running for write operations. Figma web may block a
ws://localhostconnection under its own network policy; this was not verified.
WSL
If the MCP client and the bridge run inside WSL and Figma runs on Windows, Windows 127.0.0.1 is not automatically the WSL loopback. Either run the server on the Windows side, or enable WSL localhost forwarding/mirrored networking and verify curl http://127.0.0.1:1995/ping from Windows before importing the plugin. The plugin is stamped with the port it should dial, not with a host, so the forwarding must make that port reachable.
Troubleshooting
Plugin loops between "Connecting…" and "Disconnected · retrying": the imported plugin is stale or was stamped with another token. Delete it under Plugins → Development, run
setup, and re-import the generatedpholly-figma-plugin/manifest.json.list_filesreturns[]: the plugin is not connected. Make sure it is running in a design file and the status chip shows "Connected".Bridge rejected this token: the imported plugin was stamped for a different token, or the plugin was imported from an unstamped
dist/build. Re-runsetupon the same machine the bridge runs on, then re-import.create_imagerejects a local URL: that is intentional. Use a public URL, inline the bytes as a data URI, or setPHOLLY_ALLOW_PRIVATE_IMAGE_HOSTS=1for a trusted local server.render_designrefuses to delete: passconfirmDelete: trueonly when the reconcile tree is intentional. Omittingchildrennever deletes anything.
Packaging
The server package is @mubizzu/pholly-figma-mcp. npm run pack produces a tarball for 0.3.0 containing:
dist/— the compiled MCP server with thepholly-figma-mcpbinaryplugin/— the bundled Figma plugin (code.js,ui.html,manifest.json)LICENSE— the MIT text
The setup subcommand copies the bundled plugin into a project, stamps the machine bridge token and port into it, and prints the Figma import path:
pholly-figma-mcp setup [target-dir] # default target: ./pholly-figma-pluginA published package is configured exactly like any npx server:
{
"pholly-figma": {
"type": "local",
"command": ["npx", "-y", "@mubizzu/pholly-figma-mcp"],
"enabled": true
}
}The bridge remains local-first: the plugin in Figma connects to ws://localhost:<port> on the same machine. Multiple MCP clients on one machine share the bridge; later starters become followers that proxy to the leader. A follower refuses to send the bearer token to a process that cannot prove it knows it, and re-checks that proof.
This server cannot be deployed
Maintenance
Related MCP Connectors
The Figma MCP server brings Figma design context directly into your AI workflow.
Access and maintain design system docs, tokens, components, skills, and contexts across any project.
Official Fibery MCP server: query and update your workspace from any AI client via OAuth.
Edit and publish your FramerToNextJS sites (converted Framer or AI-built) from Claude, Cursor or Codex. 19 tools: read pages, rewrite copy, restyle elements, add sections and pages, design Studio sites, manage CMS collections and items, then publish to your own host. OAuth with a read-only option, and MCP runs no model on FNJ's side. Requires an FNJ plan (Lifetime or any AI builder plan).
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceUnofficial local MCP bridge for reading the currently open Figma file through a Figma plugin. Provides tools to inspect selection, file info, and export selected nodes as SVG/PNG.MIT
- FlicenseBqualityCmaintenanceA local bridge that lets MCP clients inspect, export, and modify Figma files through a development Figma plugin.65-
- AlicenseBqualityCmaintenanceLocal MCP server connecting AI clients to the Figma desktop app for inspecting and editing Figma documents via the Plugin API.1616 npm1MIT
- AlicenseAqualityDmaintenanceLocal-first Figma MCP server providing unlimited read access via Personal Access Token, HTML replica generation with parity verification, and write-to-canvas through a companion plugin bridge.1511 npm1MIT