Claude conectado directamente a Figma. Diseña, crea componentes, gestiona tokens y audita tu design system usando lenguaje natural — sin copiar JSON, sin pasos manuales.
Design Agent es un MCP server local que abre un canal bidireccional entre Claude y Figma Desktop. Claude puede leer y escribir en cualquier archivo de Figma que tengas abierto, en tiempo real.
Claude → Figma
- Crear frames, componentes, textos, formas
- Mover, renombrar, eliminar nodos
- Crear y actualizar design tokens (variables)
- Instanciar componentes de librerias
- Aplicar estilos, colores, tipografia, radios
- Ejecutar cualquier operacion del Plugin API
Figma → Claude
- Leer variables, componentes y estilos del archivo
- Tomar screenshots de cualquier nodo
- Ver la seleccion activa del usuario
- Capturar logs y errores del plugin en tiempo real
- Detectar cambios en el documento
Figma tiene dos APIs completamente separadas:
| REST API (token) | Plugin API (plugin) |
|---|---|
| Leer archivos, metadata, comentarios | Crear y editar nodos |
| Leer componentes publicados | Leer/escribir variables |
| Exportar imagenes | Acceso a seleccion activa |
| Escribir comentarios | Screenshots internos |
| No puede crear nodos | Requiere plugin corriendo |
No existe endpoint REST para crear un frame. Es una decision de diseno de Figma. Por eso el plugin es irremplazable — es la unica puerta de entrada al canvas.
El MCP server actua como puente: recibe comandos de Claude via stdio (protocolo MCP), los traduce a mensajes WebSocket, y el plugin los ejecuta dentro de Figma usando su Plugin API.
Claude Desktop
│ stdio (MCP protocol)
▼
MCP Server (Node.js) ← mcp-server/
│ WebSocket ws://localhost:9223
▼
Plugin UI (iframe) ← plugin/ui.html
│ postMessage
▼
Plugin Sandbox (QuickJS) ← plugin/src/code.js
│ Figma Plugin API
▼
Figma Desktop (canvas)
- macOS con Figma Desktop instalado
- Node.js 18+
- Claude Desktop
- Token de Figma (plan gratuito es suficiente)
git clone [repo] ~/development/design-agent
cd ~/development/design-agentcd mcp-server
npm installCrear mcp-server/.env:
FIGMA_ACCESS_TOKEN=figd_tu_token_aqui
Obtener el token en: figma.com → Settings → Security → Personal access tokens
Permisos necesarios:
- Files: Read contents, Read metadata, Read/write comments
- Design systems: Read components and styles
- Abre Figma Desktop
- Menu → Plugins → Development → Import plugin from manifest
- Selecciona:
plugin/manifest.json
Copia el contenido de mcp-config/settings.json en:
~/Library/Application Support/Claude/claude_desktop_config.json
Si ya tienes otros MCP servers configurados, solo agrega la entrada design-agent dentro de mcpServers.
Antes de empezar, corre el plugin en Figma y arranca la sesion en Claude:
/start
Claude verificara la conexion, cargara el contexto del archivo activo y estara listo.
/start
→ Diseña un hero section con headline, subheadline y CTA button
→ Agrega una seccion de features con 3 cards
→ /tokens setup — sistema de colores para una app fintech, tonos azules y grises
→ /component Button — primary, secondary, destructive con tamaños SM/MD/LG
→ /audit — revisa el design system y dime que esta mal
| Comando | Descripcion |
|---|---|
/start |
Verifica conexion, carga contexto del archivo activo |
/design [descripcion] |
Crea o modifica elementos visuales |
/component [nombre] |
Crea componente con variantes y auto-layout |
/tokens [list/setup/create/update] |
Gestiona design tokens/variables |
/audit |
Audita design system: tokens, accesibilidad, estructura |
/debug |
Diagnostica problemas de conexion o errores |
/help |
Muestra ayuda y ejemplos de uso |
design-agent/
├── README.md
├── CLAUDE.md ← Instrucciones de comportamiento para Claude
├── start.sh ← Script de inicio (auto-build + carga .env)
├── .gitignore
│
├── plugin/ ← Plugin de Figma
│ ├── manifest.json ← Definicion del plugin (id: design-agent-bridge)
│ ├── src/code.js ← Logica del plugin (Plugin API sandbox QuickJS)
│ └── ui.html ← Bridge UI + cliente WebSocket
│
├── mcp-server/ ← MCP Server local
│ ├── .env ← Token de Figma (no incluido en repo)
│ ├── package.json
│ ├── tsconfig.json
│ └── src/
│ ├── local.ts ← Entry point — 60+ tools registrados
│ ├── browser/ ← Puppeteer (fallback CDP)
│ └── core/
│ ├── websocket-server.ts ← Bridge WebSocket multi-cliente
│ ├── websocket-connector.ts ← Implementacion IFigmaConnector via WS
│ ├── figma-connector.ts ← Interfaz IFigmaConnector
│ ├── console-monitor.ts ← Captura de logs via Puppeteer (CDP)
│ ├── figma-tools.ts ← Tools de lectura REST API
│ ├── write-tools.ts ← Tools de escritura via plugin
│ ├── design-system-tools.ts ← Analisis de design system
│ ├── design-code-tools.ts ← Paridad diseño-codigo
│ ├── comment-tools.ts ← Lectura/escritura de comentarios
│ └── figma-api.ts ← Cliente REST API de Figma
│
└── mcp-config/
├── settings.json ← Config Claude Desktop (no incluido en repo)
└── settings.example.json ← Template de configuracion
| Tool | Descripcion |
|---|---|
figma_get_console_logs |
Recupera logs del plugin |
figma_watch_console |
Stream de logs en tiempo real (max 5 min) |
figma_clear_console |
Limpia el buffer de consola |
figma_reload_plugin |
Recarga el plugin para testing |
| Tool | Descripcion |
|---|---|
figma_get_context |
Estado actual: archivo, pagina, variables, seleccion |
figma_get_status |
Health check de conexion WebSocket/CDP |
figma_reconnect |
Fuerza reconexion al plugin |
figma_navigate |
Abre una URL de Figma e inicia monitoring |
figma_take_screenshot |
Exporta imagen de un nodo via REST API |
| Tool | Descripcion |
|---|---|
figma_get_selection |
Nodos seleccionados actualmente + sus propiedades |
figma_get_design_changes |
Eventos de cambio de documento (buffer de 200) |
figma_list_open_files |
Lista todos los archivos Figma conectados |
| Tool | Descripcion |
|---|---|
figma_execute |
Ejecuta JavaScript arbitrario en el sandbox del plugin |
| Tool | Descripcion |
|---|---|
figma_create_variable |
Crea una variable |
figma_update_variable |
Actualiza el valor de una variable |
figma_delete_variable |
Elimina una variable |
figma_rename_variable |
Renombra una variable |
figma_create_variable_collection |
Crea una coleccion vacia |
figma_delete_variable_collection |
Elimina coleccion y sus variables |
figma_add_mode |
Agrega un modo a una coleccion |
figma_rename_mode |
Renombra un modo |
| Tool | Descripcion |
|---|---|
figma_batch_create_variables |
Crea hasta 100 variables en una sola llamada |
figma_batch_update_variables |
Actualiza hasta 100 variables en una sola llamada |
figma_setup_design_tokens |
Crea coleccion + modos + variables atomicamente |
| Tool | Descripcion |
|---|---|
figma_get_design_system_summary |
Resumen compacto de componentes y tokens |
figma_search_components |
Busca componentes por nombre |
figma_get_component_details |
Metadata completa + variantes de un componente |
figma_get_component_image |
Renderiza un componente como imagen |
figma_instantiate_component |
Crea una instancia de un componente |
figma_add_component_property |
Agrega propiedad a un componente |
figma_edit_component_property |
Actualiza propiedad de un componente |
figma_delete_component_property |
Elimina propiedad de un componente |
figma_set_description |
Establece descripcion de un componente |
figma_get_variables |
Variables con exportacion CSS/Tailwind/TS |
figma_get_styles |
Estilos de texto, color y efectos |
figma_get_design_system_kit |
Tokens + componentes + estilos completos |
figma_get_file_data |
Estructura completa del archivo |
| Tool | Descripcion |
|---|---|
figma_create_child |
Crea un nodo hijo en un contenedor |
figma_resize_node |
Redimensiona a medidas especificas |
figma_move_node |
Mueve a posicion x,y |
figma_clone_node |
Duplica un nodo |
figma_delete_node |
Elimina un nodo |
figma_rename_node |
Cambia el nombre de un nodo |
figma_set_fills |
Aplica colores de relleno |
figma_set_strokes |
Aplica bordes/stroke |
figma_set_image_fill |
Aplica imagen como relleno |
figma_set_text |
Establece contenido de texto + tamaño de fuente |
figma_set_instance_properties |
Actualiza propiedades de una instancia |
figma_lint_design |
Verifica WCAG y calidad del diseño |
| Tool | Descripcion |
|---|---|
figma_get_comments |
Lee comentarios del archivo |
figma_post_comment |
Publica un comentario |
figma_delete_comment |
Elimina un comentario |
El MCP server y el plugin se comunican via WebSocket en ws://localhost:{port} (default 9223, descubrimiento automatico hasta 9232).
{ "type": "EXECUTE_CODE", "requestId": "req_123", "code": "...", "timeout": 5000 }
{ "type": "CREATE_VARIABLE", "requestId": "req_124", "name": "color/primary", "collectionId": "..." }
{ "type": "UPDATE_VARIABLE", "requestId": "req_125", "variableId": "...", "modeId": "...", "value": "..." }{ "type": "FILE_INFO", "data": { "fileKey": "...", "fileName": "...", "currentPage": "Page 1" } }
{ "type": "SELECTION_CHANGE", "data": { "nodes": [...], "count": 1, "timestamp": 1234567890 } }
{ "type": "DOCUMENT_CHANGE", "data": { "hasNodeChanges": true, "changedNodeIds": [...], "timestamp": ... } }
{ "type": "CONSOLE_CAPTURE", "data": { "level": "log", "message": "...", "timestamp": ... } }
{ "type": "PAGE_CHANGE", "data": { "pageName": "...", "pageId": "...", "timestamp": ... } }{ "id": "req_123", "result": { ... } }
{ "id": "req_124", "error": "message" }El server mantiene estado aislado por cada archivo conectado:
- Seleccion actual
- Buffer de cambios de documento (ultimo 200 eventos)
- Logs de consola (ultimas 1000 entradas)
- Metadata del archivo (nombre, key, pagina activa)
Ejemplo de figma_create_variable:
1. Claude llama al tool via MCP stdio
↓
2. Server envia mensaje WebSocket al plugin UI:
{ type: "CREATE_VARIABLE", name: "color/primary", collectionId: "..." }
↓
3. Plugin UI reenvia via postMessage al sandbox code.js
↓
4. code.js ejecuta en Figma Plugin API:
const variable = figma.variables.createVariable(name, collection, type)
↓
5. code.js responde via postMessage al UI:
{ type: "CREATE_VARIABLE_RESULT", success: true, variable: { id, name, ... } }
↓
6. Plugin UI responde via WebSocket al server:
{ id: "req_123", result: { variable: { ... } } }
↓
7. Server retorna respuesta MCP a Claude
El server intenta WebSocket primero; si no hay conexion, cae a CDP via Puppeteer:
private async getDesktopConnector(): Promise<IFigmaConnector> {
if (this.wsServer?.isClientConnected()) {
return new WebSocketConnector(this.wsServer); // WebSocket (primario)
}
// CDP via Puppeteer (fallback legacy)
const page = await this.browserManager.getPage();
return new FigmaDesktopConnector(page);
}Respuestas mayores a 100KB se comprimen automaticamente para no saturar el contexto de Claude:
standard→ resumen → inventario → modo de emergencia- Cada respuesta incluye metadata de compresion si aplica
// Ejecucion de codigo: max 30 segundos
await connector.executeCodeViaUI(code, Math.min(timeout, 30000));
// WebSocket: +2 segundos para roundtrip y procesamiento del plugin
await wsServer.sendCommand(method, params, timeout + 2000);
// Batch variables: escala con el volumen
const timeout = Math.max(5000, variables.length * 200);Los colores en hex se convierten a RGBA normalizado antes de enviarse a Figma:
"#FF0000" → { r: 1, g: 0, b: 0, a: 1 }
| Variable | Descripcion | Default |
|---|---|---|
FIGMA_ACCESS_TOKEN |
Token de Figma | requerido |
FIGMA_WS_PORT |
Puerto WebSocket | 9223 |
FIGMA_WS_HOST |
Host WebSocket | localhost |
| Paquete | Uso |
|---|---|
@modelcontextprotocol/sdk |
Protocolo MCP |
ws |
WebSocket server |
zod |
Validacion de parametros de tools |
puppeteer-core |
CDP fallback para consola |
chrome-remote-interface |
Protocolo CDP |
pino / pino-pretty |
Logging estructurado |
uuid |
Request IDs |
cd mcp-server
npm run build # Compila TypeScript → dist/
npm run dev # Modo desarrollo con tsx (live reload)
npm start # Produccion: node dist/local.jsO usa el script raiz que auto-buildea si hay cambios:
./start.shTypeScript config: target es2021, module es2022, strict mode, ESM resolution, output a /dist/.
El plugin NO necesita compilacion — code.js y ui.html son archivos directos.
- El plugin siempre es necesario para escribir en el canvas. No existe alternativa via REST API.
- Variables via REST API requiere plan Enterprise de Figma. Con plugin funciona en todos los planes.
- Un archivo activo a la vez para operaciones, aunque multiples archivos pueden estar conectados simultaneamente (hasta 10).
- NodeIds cambian entre sesiones — no hardcodear IDs entre conversaciones, siempre buscar con
figma_search_components. - Sandbox QuickJS del plugin no tiene acceso a APIs del browser; el bridge postMessage en
ui.htmles el unico canal.
El MCP server y el plugin estan basados en figma-console-mcp por Southleft, adaptado y extendido para este proyecto.
MIT License
Copyright (c) 2026 Angel
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.