This guide covers setting up Talk to Figma MCP for local development, allowing you to modify the source code, test changes, and contribute to the project.
Prerequisites
Before you begin, ensure you have:
Bun runtime installed
Git installed
A code editor (VS Code, Cursor, or similar)
Node.js knowledge (TypeScript)
Figma account with editor access
Initial Setup
Clone the repository
git clone https://github.com/grab/cursor-talk-to-figma-mcp.git
cd talk-to-figma-mcp
Install dependencies
This installs all required packages:
@modelcontextprotocol/sdk - MCP protocol implementation
ws - WebSocket client
uuid - Unique ID generation
zod - Schema validation
TypeScript and build tools
Review project structure
talk-to-figma-mcp/
├── src/
│ ├── talk_to_figma_mcp/
│ │ ├── server.ts # Main MCP server
│ │ └── package.json # Server package config
│ ├── cursor_mcp_plugin/
│ │ ├── code.js # Figma plugin main thread
│ │ ├── ui.html # Plugin UI
│ │ └── manifest.json # Plugin metadata
│ └── socket.ts # WebSocket relay server
├── scripts/
│ └── setup.sh # Automated setup script
├── package.json # Root package config
└── tsup.config.ts # Build configuration
Development Configuration
For local development, you need to point the MCP configuration to your local source files instead of the published package.
Cursor Configuration
Create or edit .cursor/mcp.json in your project root:
{
"mcpServers" : {
"TalkToFigma" : {
"command" : "bun" ,
"args" : [ "/absolute/path/to/talk-to-figma-mcp/src/talk_to_figma_mcp/server.ts" ]
}
}
}
Use the absolute path to your local server.ts file, not a relative path.
Claude Code Configuration
Create or edit .mcp.json in your project root:
{
"mcpServers" : {
"TalkToFigma" : {
"command" : "bun" ,
"args" : [ "/absolute/path/to/talk-to-figma-mcp/src/talk_to_figma_mcp/server.ts" ]
}
}
}
Finding your absolute path
cd /path/to/talk-to-figma-mcp
pwd
# Copy the output and append /src/talk_to_figma_mcp/server.ts
Example absolute paths:
macOS/Linux: /home/username/projects/talk-to-figma-mcp/src/talk_to_figma_mcp/server.ts
Windows: C:/Users/username/projects/talk-to-figma-mcp/src/talk_to_figma_mcp/server.ts
Development Workflow
Running the WebSocket Server
The WebSocket relay server requires no build step:
For development with auto-reload, use:
bun --watch src/socket.ts
Building the MCP Server
The MCP server is written in TypeScript and needs to be built:
One-time build
Watch mode (recommended)
Manual watch
Watch mode automatically rebuilds when you save changes to TypeScript files.
Running the MCP Server
After building:
For testing, you can run the server directly:
bun src/talk_to_figma_mcp/server.ts
Figma Plugin Development
The Figma plugin requires no build step - it uses vanilla JavaScript:
Link the plugin
In Figma Desktop:
Go to Plugins → Development → New Plugin
Choose “Link existing plugin”
Select src/cursor_mcp_plugin/manifest.json
Make changes
Edit code.js or ui.html in src/cursor_mcp_plugin/
Reload
Close and reopen the plugin in Figma to see your changes.
The plugin files are loaded directly by Figma - no transpilation or bundling needed.
Development Commands
All available commands from package.json:
{
"scripts" : {
"start" : "bun run dist/server.js" ,
"socket" : "bun run src/socket.ts" ,
"setup" : "./scripts/setup.sh" ,
"build" : "tsup" ,
"build:watch" : "tsup --watch" ,
"dev" : "bun run build:watch" ,
"pub:release" : "bun run build && npm publish"
}
}
Testing Your Changes
Start the WebSocket server
Build and run the MCP server (in watch mode)
Run the Figma plugin
In Figma: Plugins → Development → Cursor MCP Plugin
Test via Cursor or Claude Code
Use your AI agent to send commands and verify the behavior.
Architecture Deep Dive
MCP Server (src/talk_to_figma_mcp/server.ts)
The MCP server:
Implements the Model Context Protocol
Exposes 50+ tools for Figma manipulation
Manages WebSocket communication
Handles request/response correlation with UUIDs
Implements 30-second timeouts with progress resets
Validates all parameters with Zod schemas
Key patterns:
// Request tracking
const pendingRequests = new Map < string , {
resolve : ( value : any ) => void ;
reject : ( error : any ) => void ;
timeoutId : NodeJS . Timeout ;
lastActivity : number ;
}>();
// Logging (stderr only, stdout is for MCP protocol)
console . error ( '[MCP] Starting server...' );
// Color conversion (Figma uses 0-1, display uses hex)
function rgbToHex ( r : number , g : number , b : number ) : string {
const toHex = ( n : number ) => Math . round ( n * 255 ). toString ( 16 ). padStart ( 2 , '0' );
return `# ${ toHex ( r ) }${ toHex ( g ) }${ toHex ( b ) } ` ;
}
WebSocket Relay (src/socket.ts)
The WebSocket relay:
Lightweight Bun WebSocket server
Channel-based message routing
Runs on port 3055 (configurable via PORT env)
Handles connection management
CORS-enabled for browser plugin
Key features:
// Channel isolation
const channels = new Map < string , Set < ServerWebSocket < any >>>();
// Configurable binding
const server = Bun . serve ({
port: 3055 ,
hostname: "0.0.0.0" , // For Windows WSL
// ...
});
Figma Plugin (src/cursor_mcp_plugin/)
The plugin:
Vanilla JavaScript (no build process)
Command dispatcher for 30+ operations
Chunking for large operations (prevents UI freezing)
WebSocket client for MCP communication
Progress reporting for long-running tasks
Key components:
// Command dispatcher
const commandHandlers = {
get_document_info : async () => { /* ... */ },
create_rectangle : async ( params ) => { /* ... */ },
// 30+ more handlers
};
// Chunking pattern
for ( let i = 0 ; i < nodes . length ; i += chunkSize ) {
const chunk = nodes . slice ( i , i + chunkSize );
// Process chunk
sendProgress ( i , total );
}
Common Development Tasks
Adding a new MCP tool
Define the tool schema
In server.ts, add a new tool definition: server . setRequestHandler ( ListToolsRequestSchema , async () => ({
tools: [
// ... existing tools
{
name: "my_new_tool" ,
description: "Description of what it does" ,
inputSchema: {
type: "object" ,
properties: {
param1: {
type: "string" ,
description: "First parameter"
}
},
required: [ "param1" ]
}
}
]
}));
Implement the tool handler
Add the handler in the CallToolRequestSchema handler: case "my_new_tool" : {
const params = request . params . arguments ;
// Send command to plugin
const result = await sendCommandToPlugin ({
command: "my_new_tool" ,
params: params
});
return { content : [{ type: "text" , text: JSON . stringify ( result ) }] };
}
Add plugin handler
In code.js, add the command handler: async function handleMyNewTool ( params ) {
// Implement Figma API operations
const node = figma . getNodeById ( params . nodeId );
// ...
return { success: true , result: data };
}
Test the new tool
Rebuild, restart, and test via your AI agent.
Modifying WebSocket communication
The WebSocket protocol uses this message format:
{
type : "join" | "message" ,
channel : string ,
message ?: {
command: string ,
params: any
},
id ?: string
}
Modifications should maintain backward compatibility with this structure.
Debugging
MCP Server
WebSocket Server
Figma Plugin
// All logs must go to stderr
console . error ( '[DEBUG] Variable value:' , value );
// Never log to stdout (breaks MCP protocol)
// console.log('...') // DON'T DO THIS
Build Configuration
The project uses tsup for building. Configuration in tsup.config.ts:
import { defineConfig } from 'tsup'
export default defineConfig ({
entry: [ 'src/talk_to_figma_mcp/server.ts' ] ,
format: [ 'esm' ] ,
dts: false ,
shims: true ,
outDir: 'dist' ,
clean: true ,
})
This:
Compiles TypeScript to JavaScript
Outputs to dist/ directory
Uses ES modules format
Cleans output directory on each build
Contributing Guidelines
When contributing:
Code Style : Follow existing patterns
Logging : Use stderr for MCP server logs
Error Handling : All errors should return structured responses
Validation : Use Zod for parameter validation
Documentation : Update relevant docs for new features
Testing : Test with both Cursor and Claude Code
Chunking : Use chunking for operations on 100+ nodes
Publishing Changes
For maintainers:
Update version
Edit package.json and bump the version number.
Build and publish
This builds the project and publishes to npm.
Update Figma plugin
If plugin changes are made, update the plugin on Figma Community separately.
Next Steps
Architecture Understand the system architecture
API Reference Explore all available MCP tools
Troubleshooting Development Issues
Build errors
Ensure all dependencies are installed: bun install
Clear the build cache: rm -rf dist && bun run build
Check TypeScript version compatibility
MCP server not reloading
You must restart your AI agent after making MCP server changes
Verify the absolute path in your MCP configuration is correct
Check stderr logs for error messages
Plugin changes not appearing
Close and reopen the plugin in Figma
For major changes, try unlinking and relinking the plugin
Check the Figma plugin console for JavaScript errors
WebSocket connection issues
Ensure the WebSocket server is running
Check port 3055 isn’t in use by another process
On Windows, verify hostname: "0.0.0.0" is set