| name | talktofigma-desktop-mcp |
| description | Bridge Figma designs with AI assistants using TalkToFigma Desktop via Model Context Protocol |
| triggers | ["connect to figma designs","read figma file layers","modify figma components","extract design tokens from figma","sync figma with ai tools","access figma via mcp","talk to figma desktop","integrate figma with cursor"] |
TalkToFigma Desktop MCP
Skill by ara.so — Design Skills collection.
TalkToFigma Desktop is a cross-platform desktop application that bridges Figma and AI coding assistants through the Model Context Protocol (MCP). It provides 50+ MCP tools for reading and manipulating Figma designs, enabling AI agents to directly interact with design files through a WebSocket server and stdio-based MCP servers.
Architecture Overview
MCP Client (Cursor/Claude Code) → stdio MCP Server → WebSocket (port 3055) → Desktop App → Figma Plugin
The desktop app manages:
- WebSocket server on port 3055 for real-time communication
- stdio MCP servers spawned independently by each AI client
- Channel-based routing for multi-client support
- System tray interface for server management
Installation
1. Install Desktop Application
Download from GitHub Releases:
- macOS:
TalkToFigma-v*.*.*.zip (Universal binary)
- Windows:
TalkToFigma-v*.*.*.exe
First run on macOS: Right-click app → "Open" → "Open" (bypass Gatekeeper)
First run on Windows: SmartScreen → "More info" → "Run anyway"
2. Install Figma Plugin
Install the Talk to Figma MCP Plugin from Figma Community.
3. Configure MCP Client
For Cursor, Claude Code, or VS Code with Cline:
- Launch TalkToFigma Desktop
- Right-click tray icon → "Settings"
- Copy the MCP configuration path shown
- Add to your MCP client config:
macOS (~/Library/Application Support/Cursor/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json):
{
"mcpServers": {
"TalkToFigmaDesktop": {
"command": "node",
"args": [
"/Users/yourname/Library/Application Support/TalkToFigma/mcp-server.cjs"
]
}
}
}
Windows Direct Install (%APPDATA%\Cursor\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json):
{
"mcpServers": {
"TalkToFigmaDesktop": {
"command": "node",
"args": [
"%APPDATA%\\TalkToFigma\\mcp-server.cjs"
]
}
}
}
Windows Store/MSIX: Use the exact path from Settings page (usually under %LOCALAPPDATA%\Packages\...\LocalCache\Roaming\TalkToFigma\mcp-server.cjs)
Starting the Server
- Launch TalkToFigma Desktop from Applications/Start Menu
- Start WebSocket server: Right-click tray icon → "Start Server"
- Verify status: Tray icon should show green (🟢 Active)
- Open Figma: Run the Talk to Figma MCP plugin
- Connect: Plugin should show "Connected" status
MCP Tools Reference
Core Connection Tools
join_channel
Join a Figma file channel to start interacting with it.
Parameters:
channel (string): Format {file_key}:{page_id}:{view_id}
Usage:
await use_mcp_tool("TalkToFigmaDesktop", "join_channel", {
channel: "ABC123:1:2"
});
leave_channel
Leave the current Figma file channel.
await use_mcp_tool("TalkToFigmaDesktop", "leave_channel", {});
Reading Design Data
get_current_page
Get the currently active page in Figma.
const page = await use_mcp_tool("TalkToFigmaDesktop", "get_current_page", {});
get_node_by_id
Retrieve a specific node by its ID.
const node = await use_mcp_tool("TalkToFigmaDesktop", "get_node_by_id", {
nodeId: "123:456"
});
get_all_nodes
Get all nodes in the current page with optional filtering.
const allFrames = await use_mcp_tool("TalkToFigmaDesktop", "get_all_nodes", {
type: "FRAME"
});
const allComponents = await use_mcp_tool("TalkToFigmaDesktop", "get_all_nodes", {
type: "COMPONENT"
});
search_nodes
Search for nodes by name or type.
const buttons = await use_mcp_tool("TalkToFigmaDesktop", "search_nodes", {
query: "Button",
type: "COMPONENT"
});
get_selection
Get currently selected nodes in Figma.
const selection = await use_mcp_tool("TalkToFigmaDesktop", "get_selection", {});
Creating and Modifying Nodes
create_rectangle
Create a rectangle node.
await use_mcp_tool("TalkToFigmaDesktop", "create_rectangle", {
name: "Background",
x: 0,
y: 0,
width: 375,
height: 812,
fills: JSON.stringify([{
type: "SOLID",
color: { r: 0.95, g: 0.95, b: 0.95 }
}])
});
create_frame
Create a frame container.
await use_mcp_tool("TalkToFigmaDesktop", "create_frame", {
name: "Mobile Screen",
x: 100,
y: 100,
width: 375,
height: 812
});
create_text
Create a text node.
await use_mcp_tool("TalkToFigmaDesktop", "create_text", {
name: "Heading",
characters: "Welcome to TalkToFigma",
x: 20,
y: 40,
fontSize: 24,
fontName: JSON.stringify({ family: "Inter", style: "Bold" })
});
create_component
Create a reusable component.
await use_mcp_tool("TalkToFigmaDesktop", "create_component", {
name: "Button/Primary",
x: 0,
y: 0,
width: 120,
height: 44
});
set_properties
Modify properties of existing nodes.
await use_mcp_tool("TalkToFigmaDesktop", "set_properties", {
nodeId: "123:456",
properties: JSON.stringify({
name: "Updated Button",
x: 50,
y: 50,
fills: [{
type: "SOLID",
color: { r: 0.2, g: 0.4, b: 0.8 }
}]
})
});
delete_node
Delete a node by ID.
await use_mcp_tool("TalkToFigmaDesktop", "delete_node", {
nodeId: "123:456"
});
Layout and Positioning
set_auto_layout
Apply auto layout to a frame.
await use_mcp_tool("TalkToFigmaDesktop", "set_auto_layout", {
nodeId: "123:456",
mode: "VERTICAL",
padding: 16,
spacing: 12,
primaryAxisAlignItems: "MIN",
counterAxisAlignItems: "CENTER"
});
group_nodes
Group multiple nodes together.
await use_mcp_tool("TalkToFigmaDesktop", "group_nodes", {
nodeIds: JSON.stringify(["123:456", "123:457", "123:458"]),
name: "Button Group"
});
Styles and Design Tokens
get_local_paint_styles
Get all local color styles.
const colors = await use_mcp_tool("TalkToFigmaDesktop", "get_local_paint_styles", {});
get_local_text_styles
Get all local text styles.
const textStyles = await use_mcp_tool("TalkToFigmaDesktop", "get_local_text_styles", {});
create_paint_style
Create a new color style.
await use_mcp_tool("TalkToFigmaDesktop", "create_paint_style", {
name: "Brand/Primary",
paints: JSON.stringify([{
type: "SOLID",
color: { r: 0.2, g: 0.4, b: 0.8 }
}])
});
apply_paint_style
Apply a color style to a node.
await use_mcp_tool("TalkToFigmaDesktop", "apply_paint_style", {
nodeId: "123:456",
styleId: "S:abc123..."
});
Export and Assets
export_node
Export a node as an image.
const imageData = await use_mcp_tool("TalkToFigmaDesktop", "export_node", {
nodeId: "123:456",
format: "PNG",
scale: 2
});
get_image_fills
Get image fill data from nodes.
const images = await use_mcp_tool("TalkToFigmaDesktop", "get_image_fills", {
nodeId: "123:456"
});
Common Workflows
Extract Design Tokens
await use_mcp_tool("TalkToFigmaDesktop", "join_channel", {
channel: "FILE_KEY:PAGE_ID:VIEW_ID"
});
const colors = await use_mcp_tool("TalkToFigmaDesktop", "get_local_paint_styles", {});
const typography = await use_mcp_tool("TalkToFigmaDesktop", "get_local_text_styles", {});
const tokens = {
colors: colors.map(style => ({
name: style.name.replace(/\//g, '-'),
value: rgbToHex(style.paints[0].color)
})),
typography: typography.map(style => ({
name: style.name.replace(/\//g, '-'),
fontSize: style.fontSize,
fontFamily: style.fontName.family,
fontWeight: style.fontName.
}))
};
Build Component Library
const components = await use_mcp_tool("TalkToFigmaDesktop", "get_all_nodes", {
type: "COMPONENT"
});
for (const comp of components) {
const details = await use_mcp_tool("TalkToFigmaDesktop", "get_node_by_id", {
nodeId: comp.id
});
const componentCode = generateReactComponent(details);
}
Sync Design Changes to Code
const selection = await use_mcp_tool("TalkToFigmaDesktop", "get_selection", {});
for (const node of selection) {
const nodeData = await use_mcp_tool("TalkToFigmaDesktop", "get_node_by_id", {
nodeId: node.id
});
const cssProperties = {
width: `${nodeData.width}px`,
height: `${nodeData.height}px`,
backgroundColor: rgbToHex(nodeData.fills[0].color),
borderRadius: `${nodeData.cornerRadius}px`
};
}
Create UI from Specification
await use_mcp_tool("TalkToFigmaDesktop", "join_channel", {
channel: "FILE_KEY:PAGE_ID:VIEW_ID"
});
await use_mcp_tool("TalkToFigmaDesktop", "create_frame", {
name: "Mobile/Login",
x: 0,
y: 0,
width: 375,
height: 812
});
const frames = await use_mcp_tool("TalkToFigmaDesktop", "search_nodes", {
query: "Mobile/Login",
type: "FRAME"
});
const frameId = frames[0].id;
await use_mcp_tool("TalkToFigmaDesktop", "set_auto_layout", {
nodeId: frameId,
mode: "VERTICAL",
padding: 24,
spacing: 16
});
await use_mcp_tool("TalkToFigmaDesktop", "create_text", {
: ,
: ,
: ,
: .({ : , : })
});
Configuration
Environment Variables
TalkToFigma Desktop doesn't require API keys, but the stdio server path varies by platform:
TALKTOFIGMA_STDIO_PATH="$HOME/Library/Application Support/TalkToFigma/mcp-server.cjs"
TALKTOFIGMA_STDIO_PATH="%APPDATA%\TalkToFigma\mcp-server.cjs"
WebSocket Port
Default port: 3055
To verify the server is running:
lsof -i :3055
netstat -ano | findstr :3055
Multi-Client Setup
Each AI client spawns its own stdio server process. All connect to the same WebSocket server (port 3055).
Cursor config (~/.cursor/mcp.json):
{
"mcpServers": {
"TalkToFigmaDesktop": {
"command": "node",
"args": ["/path/to/mcp-server.cjs"]
}
}
}
Claude Code config (~/.claude/mcp.json):
{
"mcpServers": {
"TalkToFigmaDesktop": {
"command": "node",
"args": ["/path/to/mcp-server.cjs"]
}
}
}
Troubleshooting
Server Won't Start
Check logs:
- Right-click tray icon → "Terminal"
- Look for error messages
Common issues:
- Port 3055 already in use: Kill conflicting process or restart
- Firewall blocking: Allow TalkToFigma through firewall
macOS port check:
lsof -i :3055
kill -9 <PID>
Windows port check:
netstat -ano | findstr :3055
taskkill /PID <PID> /F
Plugin Can't Connect
Verify:
- Desktop app is running (tray icon visible)
- WebSocket server is active (green icon 🟢)
- Figma plugin is running in the same file
Reset connection:
- Right-click tray → "Stop Server"
- Wait 5 seconds
- Right-click tray → "Start Server"
- Restart Figma plugin
MCP Client Can't Find Server
Check stdio path:
macOS:
ls -la ~/Library/Application\ Support/TalkToFigma/mcp-server.cjs
Windows:
dir "%APPDATA%\TalkToFigma\mcp-server.cjs"
If missing:
- Restart TalkToFigma Desktop (installs stdio server on launch)
- Check Settings page for correct path
- Manually verify file exists
Channel Not Joined Error
Always call join_channel before any other operations:
const channel = "ABC123:1:2";
await use_mcp_tool("TalkToFigmaDesktop", "join_channel", { channel });
const page = await use_mcp_tool("TalkToFigmaDesktop", "get_current_page", {});
Node ID Format Issues
Figma node IDs use format 123:456. Extract from:
- Plugin selection:
figma.currentPage.selection[0].id
- URL parameters:
node-id=123-456 → convert to 123:456
const nodeId = urlNodeId.replace(/-/g, ':');
Building from Source
git clone https://github.com/grab/TalkToFigmaDesktop.git
cd TalkToFigmaDesktop
npm install
npm start
npm run package
npm run make
Output locations:
- Development: Electron starts with hot reload
- Package:
out/TalkToFigma-{platform}-{arch}/
- Installers:
out/make/
API Reference Summary
| Tool | Purpose | Key Parameters |
|---|
join_channel | Connect to Figma file | channel |
get_current_page | Get active page | - |
get_node_by_id | Fetch node details | nodeId |
get_all_nodes | List all nodes | type (optional) |
search_nodes | Search by name/type | query, type |
get_selection | Get selected nodes | - |
create_rectangle | Create rectangle | x, y, width, height |
create_frame | Create frame | x, y, width, height |
create_text | Create text | characters, fontSize |
create_component | Create component | name, width, height |
set_properties | Update node | nodeId, properties |
delete_node | Remove node | nodeId |
set_auto_layout | Apply auto layout | nodeId, mode, padding |
get_local_paint_styles | Get color styles | - |
get_local_text_styles | Get text styles | - |
|
Full tool list available in desktop app Terminal logs on startup.