figma-bridge-mcp
figma-bridge-mcp
Un servidor MCP local que permite a los asistentes de IA inspeccionar, crear y actualizar diseños en Figma Desktop. Se conecta a través de un pequeño plugin de desarrollo de Figma y expone herramientas enfocadas para capturas de pantalla, especificaciones de diseño, renderizado JSX, tokens, activos, componentes, FigJam y Figma Slides.
Todo se ejecuta en 127.0.0.1. No se requiere un token de acceso personal de Figma. Sin nube. Sin parcheo binario de la aplicación Figma.
Un complemento REST opcional añade historial de versiones, comentarios y metadatos de bibliotecas publicadas. Su token de Figma permanece en su máquina y nunca se coloca en la configuración de su cliente MCP ni en el chat.
Requisitos: Node.js 18 o superior, Figma Desktop y un cliente MCP que pueda iniciar servidores stdio locales.
Codex, Claude Code y Cursor: MCP y habilidades en un solo paquete
Figma Bridge incluye tres habilidades compartidas enfocadas más adaptadores de plugin ligeros para los tres clientes:
figma-bridge-design-to-code— implementación exacta de Figma en la pila objetivo;figma-bridge-code-to-figma— pantallas semánticas y componentizadas desde el código;figma-bridge-component-library— tokens, estilos, componentes, variantes y propiedades.
Cliente | Formato del plugin | Ruta de instalación completa |
Codex / ChatGPT |
| Mercado de Codex de este repositorio |
Claude Code |
| Mercado de Claude de este repositorio |
Cursor | Agent Plugins 1.0 ( | Mercado de equipo respaldado por GitHub o clon local |
Los adaptadores descubren todos el mismo directorio skills/ e inician el mismo paquete MCP local. Los usuarios no descargan ni mantienen las habilidades por separado.
Para Codex, añada este repositorio como mercado e instale el paquete:
codex plugin marketplace add KaiUweHella/figma-bridge-mcp
codex plugin add figma-bridge-mcp@figma-bridgeEste es un mercado de repositorios alojado en GitHub, no un envío al directorio universal de plugins de OpenAI. El catálogo sigue al repositorio, mientras que cada entrada de plugin publicada fija una etiqueta Git exacta v<version> e inicia la versión de tiempo de ejecución npm correspondiente. Por lo tanto, main y @latest no pueden mover silenciosamente un paquete de habilidades instalado a un contrato de servidor diferente.
Para Claude Code, añada este repositorio como mercado e instale el paquete:
claude plugin marketplace add KaiUweHella/figma-bridge-mcp
claude plugin install figma-bridge-mcp@figma-bridgeEl mercado de Claude utiliza la misma versión fijada de GitHub y el árbol de habilidades compartido. El paquete npm correspondiente debe publicarse antes de que los usuarios instalen esa versión, porque el plugin inicia su servidor stdio local a través de npx.
Para Cursor Teams o Enterprise, importe este repositorio de GitHub en un mercado de equipo e instale Figma Bridge desde Customize. Los usuarios individuales y contribuidores pueden usar la misma fuente de GitHub sin una lista central de Cursor: clone la versión etiquetada, enlace ese clon en Cursor y recargue la ventana:
mkdir -p ~/.cursor/plugins/local
ln -s /absolute/path/to/figma-bridge-mcp ~/.cursor/plugins/local/figma-bridge-mcpCursor detecta el manifiesto raíz de Agent Plugin y carga tanto la habilidad como el servidor MCP.
Los clientes sin soporte de plugin o Agent Skill siguen usando la configuración de servidor normal a continuación. Aún reciben el flujo de trabajo obligatorio compacto a través de las instrucciones MCP, los comandos invocados por el usuario design-to-code, code-to-figma y create-figma-component.
Inicio rápido
1. Añadir el servidor MCP (alternativa solo MCP)
Use esto cuando la instalación completa del plugin no esté disponible o solo quiera las herramientas MCP sin la habilidad incluida. La configuración con npx no necesita clonación ni paso de compilación. Para Claude Code:
claude mcp add figma-bridge -- npx -y figma-bridge-mcp@latestPara otro cliente MCP, añada la configuración de servidor equivalente:
{
"mcpServers": {
"figma-bridge": {
"command": "npx",
"args": ["-y", "figma-bridge-mcp@latest"]
}
}
}Reinicie el cliente MCP si no descubre el servidor inmediatamente. No hay intencionalmente un bloque env: el puente crea sus credenciales locales durante el emparejamiento.
git clone https://github.com/KaiUweHella/figma-bridge-mcp.git
cd figma-bridge-mcp
npm install{
"mcpServers": {
"figma-bridge": {
"command": "node",
"args": ["/absolute/path/to/figma-bridge-mcp/src/server.js"]
}
}
}2. Emparejar Figma Desktop una vez
Pida a su asistente de IA que se conecte a Figma, o llame a
figma_connectdirectamente. Inicia el puente local y devuelve una clave de acceso más una ruta de manifiesto del plugin.En Figma Desktop:
Plugins → Development → Import plugin from manifest…y elija~/.figma-bridge-mcp/plugin/manifest.json(la ruta devuelta porfigma_connect).Abra
Plugins → Development → Figma Bridge, pegue la clave de acceso y haga clic en Save & connect.Cuando el plugin muestre Connected (authenticated), el asistente puede trabajar con ese archivo de Figma. El emparejamiento se recuerda; en sesiones posteriores, solo vuelva a abrir el plugin en el archivo que desee usar.
Figma Dev Mode necesita adaptadores separados porque Figma no admite combinar el objetivo del editor FigJam existente con dev en un solo manifiesto:
Importe
~/.figma-bridge-mcp/plugin/manifest.dev.jsonpara Figma Bridge Dev Mode. Mantiene el puente MCP autenticado conectado para selección, inspección, especificaciones y exportaciones. Dev Mode es de solo lectura, por lo que el renderizado y las ediciones del lienzo aún requieren cambiar el archivo al modo Design y abrir el plugin normal Figma Bridge allí.
3. Usarlo con Figma
Seleccione un marco o capa en Figma y describa el resultado que desea. Por ejemplo:
"Inspecciona mi selección actual y explica su diseño."
"Crea una tarjeta de configuración junto al marco seleccionado."
"Exporta los tokens y activos de la pantalla seleccionada a este proyecto."
"Implementa el marco seleccionado y luego compara el resultado con Figma."
El asistente puede leer la selección actual, capturar capturas de pantalla y especificaciones, renderizar JSX, exportar activos o aplicar ediciones específicas. Mantenga el plugin Figma Bridge abierto en cada documento al que el asistente deba acceder. Si hay más de un documento conectado, pase una URL de Figma o clave de archivo para que el objetivo sea inequívoco.
Related MCP server: tellfigma
Cómo funciona
MCP client ──stdio──▶ figma-bridge-mcp (src/)
│
MCP tool adapters ─▶ Capability Catalog ─▶ CommandPlan
│
┌───────────────────────┴──────────┐
Command Application Modules generic CLI adapter
│ │
Design Capture │
Asset Policy │
└──────┬─────┘
Daemon Client Module
│ HTTP: signed requests
▼
local daemon :3456–3460
│ WS: challenge/response
▼
Figma Bridge plugin in Figma DesktopEl motor se encuentra en
engine/. Comenzó como un fork defigma-ds-cliv2.1.0 y ha divergido mucho más allá (ver atribución). El "modo Yolo" de Chrome-DevTools — que parchea el binario de la aplicación Figma — se eliminó por completo; no hay ninguna ruta de código hacia él.Las lecturas MCP especializadas (
figma_spec,figma_inspect,figma_screenshot) se ejecutan directamente a través de Módulos de Aplicación de Comandos que devuelven valores. MCP y CLI son adaptadores ligeros sobre las mismas implementaciones; el genéricofigma_runsigue siendo el adaptador CLI de procesos hijo deliberadamente amplio. Un Módulo de Cliente Daemon gestiona la firma, los tiempos de espera y los errores de transporte para ambas rutas.El Módulo de Captura de Diseño recorre un nodo explícito una vez y proyecta localmente la estructura, el estilo y los formatos de salida sin pérdida a partir de esos mismos hechos. Una Captura se reutiliza solo después de que una sonda de revisión económica demuestre que la conexión del plugin autenticado y la revisión del documento de Figma no han cambiado. La falta o inestabilidad de los metadatos de revisión deshabilita la reutilización; las llamadas de selección y sección nombrada permanecen sin caché en este primer Slice. Las Capturas distinguen entre Auto Layout/Grid de Figma creado por el autor, la heurística
inferredAutoLayoutmarcada por Figma y el fallback geométrico. También preservan los metadatos semánticos/fallback de Código a Figma por separado de las anotaciones nativas posteriores de Figma, además de los contratos completos de componentes y modos de variables.El Registro de Enlaces de Diseño otorga a un componente, pantalla o marco un id de Entidad de Diseño duradero y propiedad del repositorio.
figma-bridge.jsoncontiene enlaces portátiles de código/Storybook/Figma; los datos del plugin de Figma contienen solo el mismo id y tipo. Este anclaje dual permite que futuros agentes resuelvan el componente existente exacto desde cualquier lado sin poner rutas de repositorio en un documento de Figma.El Planificador de Ida y Vuelta (solo informe) compara el código actual y el subárbol de Figma normalizado actual con una Línea Base de Diseño Aceptada explícita. El Contexto de Diseño del Proyecto proyecta ese estado, los enlaces de entidad y las siguientes lecturas exactas a través de una Aplicación de Comandos en proceso. Cuando existen rutas semánticas, los subárboles modificados se informan con sus ids de nodo actuales; los marcadores de plugin en sí mismos nunca cuentan como cambios visuales.
Un Contrato de Diseño convierte la Captura de Diseño completa de una Entidad de Diseño vinculada en una puerta de repositorio determinista. Ejecute
figma_run ["contract", "capture","ui.button"]una vez y revise el JSON; luegofigma_run ["contract","check","ui.button"]informa de la deriva canónica y aplica por separado matrices de variantes, pisos de vinculación de tokens, tolerancias geométricas y transiciones de prototipo. Los identificadores volátiles de Figma se ignoran y las capturas con profundidad limitada se rechazan.Un Catálogo de Capacidades resuelve cada Comando de Figma que ingresa a través de MCP en un plan inmutable antes de que cualquiera de los adaptadores de ejecución lo ejecute. Ese plan es la única fuente para exposición, efectos de Figma/espacio de trabajo/estado compartido, necesidad de objetivo, confirmación, rutas normalizadas, reintento, tiempo de espera, códigos de salida aceptados e identidad de trabajo en segundo plano. Los comandos desconocidos son rechazados.
Herramienta | Propósito |
| Iniciar modo seguro, generar/mostrar la clave de acceso, imprimir pasos de configuración del plugin. |
| Informar inmediatamente del estado del daemon local, plugin, archivo y clave; |
| Mostrar la clave de acceso; |
| Ejecutar un comando de motor aprobado por el Catálogo de Capacidades; descúbralos con |
| Renderizar JSX dentro del diseño de Figma abierto. |
| Inspeccionar un nodo por id: geometría, rellenos/trazos/efectos, clip, opacidad (YAML). |
| Guardar un PNG de un nodo/selección en un archivo temporal (se devuelve la ruta + dimensiones + escala aplicada). |
| Especificación de diseño a código de un nodo: contenido real, nombres de componentes, tokens, referencias de arte vectorial, clip/abs — en fases. |
| Referencia offline de la API del Plugin de Figma ( |
| Historial de cambios locales del registro de auditoría — filtrar por |
| La selección actual del usuario en Figma (ids, nombres, tipos, tamaños) — enviada en vivo por el plugin. Las instancias resuelven a su |
| Complemento REST: leer comentarios de revisión de diseño ( |
Los ids de nodo se aceptan en cualquier forma que el usuario tenga a mano: 12:34, la forma de URL 12-34, o una URL completa de Figma (cuya clave de archivo se comprueba con los archivos que realmente tiene abiertos — consulte Varios archivos a la vez).
Los comandos de escritura se pueden bloquear detrás de un confirm:true explícito estableciendo FIGMA_WRITE_CONFIRM=1 en el entorno del servidor. El bloqueo funciona a nivel de subcomando: las lecturas como node tree o component list pasan libremente, las mutaciones como node delete, combos o tokens spacing requieren confirmación.
Las instancias nativas de JSX requieren identidad de Registro duradera (entity más una key publicada o id local). Sus anulaciones editables utilizan la estructura real de Figma del componente:
<Instance entity="ui.card" key="..."
prop:Selected="true"
text:Title="New title"
fill:StatusDot="var:status/healthy|#22c55e"
swap:LeadingIcon="ui.icon.leaf" />prop: resuelve una definición de propiedad de componente; text: y fill: resuelven un descendiente nombrado. Los valores de swap: y los valores de propiedad INSTANCE_SWAP son ids de Entidad de Diseño, resueltos desde figma-bridge.json; los nombres de visualización de los componentes no se aceptan intencionadamente como identidad de intercambio. Los destinos faltantes, ambiguos o no vinculados detienen la verificación previa antes de que se cree el primer nodo de lienzo.
Las dimensiones y la tipografía aceptan la misma forma var:nombre|fallback. El ejecutor nativo vincula ancho, alto y restricciones min/max, además de familia/estilo de fuente, peso, tamaño, altura de línea, espaciado entre letras, espaciado entre párrafos y sangría de párrafo. Familia/estilo utilizan variables STRING; los otros campos de tipografía y dimensión utilizan variables FLOAT. Una fuente vinculada faltante detiene la verificación previa con un mensaje de instalar-o-elegir-otra en lugar de sustituirla silenciosamente. Los Estilos de Texto nombrados también se reconcilian antes de la creación del lienzo: un style="Typography/Eyebrow" explícito se reutiliza solo cuando su tipografía completa coincide; un estilo del mismo nombre conflictivo se detiene, y de lo contrario la tipografía exacta se reutiliza o se crea bajo un nombre determinista Typography/Generated/.... La lectura de la métrica float32 de Figma se normaliza para una comparación estable, y las caras específicas de familia como DM Sans/Manrope SemiBold y ExtraBold se prueban antes que cualquier familia de respaldo. Los renderizados nativos exitosos devuelven recuentos de textStyleReport y variableReport para referencias, variables reutilizadas únicas, variables creadas y propiedades vinculadas. Los errores de verificación previa ambiguos o no compatibles incluyen los recuentos cero/no cero correspondientes y no dejan variables recién creadas o nodos de lienzo atrás.
<Text> también conserva el Texto Enriquecido en línea editable. El marcado anidado <strong>/<b>, <em>/<i>, <u>, <Span ...> y <a href="..."> se convierte en rangos nativos de Figma; las entidades HTML se decodifican antes de calcular los desplazamientos de rango UTF-16. Los tramos Span admiten font, fontStyle, weight, italic, size, color, letterSpacing, underline/decoration y enlaces seguros:
<Text font="Inter" size="14">
Hello <strong>bold <em>and italic</em></strong>
<Span color="#ef4444" size="18">red</Span>
<a href="https://example.com">link</a>
</Text>Ventana del plugin
La ventana del plugin Figma Bridge es más que el estado de la conexión:
Actividad — cada comando que ejecuta el agente, en vivo, con duración y ok/error; las escrituras se resaltan. La fila colapsada lleva el recuento (
12 ok · 1 falló); el puerto conectado y la latencia de ida y vuelta están en la barra de título.Pausar agente — un interruptor de apagado: mientras está en pausa, el plugin rechaza cada comando entrante del agente con un error explícito.
Guardar versión — escribe una entrada etiquetada en el historial de versiones propio de Figma (
Figma Bridge — <timestamp>) como un punto de restauración manual antes de dejar libre al agente. No hay API de restauración para plugins: se retrocede a través del panel de historial de versiones de Figma.Lectura de selección — lo que sea que el usuario seleccione se envía al agente automáticamente (con debounce) y se muestra como "El agente ve: …", de modo que el usuario siempre ve lo que devolverá
figma_selection. Seleccione un marco, diga "construye esto" — sin copiar ids de nodo.Configuración — clave de acceso y el token REST opcional, siempre accesible independientemente de si el puente está conectado.
Flujo de trabajo de diseño a código
El diseño es la especificación completa — las herramientas facilitan copiarlo en lugar de interpretarlo. Construya una pantalla desde Figma en seis pasos:
Mantenga el framework y el sistema de estilos del proyecto destino. No agregue Tailwind, un kit de UI o una biblioteca de iconos únicamente para la pantalla, y nunca reemplace el arte de Figma exportado con una aproximación conveniente. Reutilice un componente del proyecto solo cuando su diseño renderizado y sus estados realmente coincidan.
figma_screenshoten el frame objetivo, luego lee el PNG guardado — la verdad visual de referencia. Nunca construyas solo a partir del árbol de nodos.figma_specconphase: "structure"— construye el esqueleto del marcado: caracteres de texto reales, nombres de iconos/componentes resueltos (se desciende a las instancias, por lo que aparecen las sobrescrituras y los nombres reales del componente principal), jerarquía y dirección flex. Copia textos e iconos textualmente. Un marcadorlayout:inferred (Figma heuristic — verify)no es Auto Layout creado; verifica la jerarquía antes de tratarlo como el contrato del componente.Exporta tokens (
figma_runcon["export","css"]o["export","dtcg"]) y conéctalos como variables CSS / tema. La salida nombra su archivo Figma de origen — verifica que es el archivo que estás construyendo.Exporta assets (
figma_runcon["export","assets","<nodeId>","-o","/abs/path/src/assets"]) — cada referencia→ assets/…en la especificación apunta a un archivo que esto escribe. Pasa una ruta absoluta; las exportaciones grandes siguen ejecutándose en segundo plano ("still RUNNING") — vuelve a ejecutar la misma llamada para sondear.assets.jsonse fusiona entre ejecuciones y los activos byte-idénticos se deduplican. Cada entrada lleva datos de colocación (desplazamientosx/y, ruta de nombre delparent,parentId,absolutePosition,overhang), por lo que el manifiesto por sí solo posiciona una superposición — no se necesita referencia cruzada de la especificación. El resumen de exportación lista explícitamente los archivos posicionados absolutamente y con voladizo: esos son los que las compilaciones pierden. Los PNG sobredimensionados se reducen por defecto a 2× su uso más grande en Figma (densidad retina), sin escalado ascendente y solo cuando el archivo codificado se vuelve más pequeño. La relación de aspecto, la colocación en el manifiesto y el comportamiento de recorte CSS permanecen sin cambios; pasa--raster-scale 0para conservar los bytes PNG originales.figma_specconphase: "style"— aplica tamaños, espacios, relleno, alineación, dimensionamiento fill/hug, pinturas incl. degradados (→ var(name)marca un enlace a token de diseño), radios, sombras, tipografía,opacity,clip(overflow hidden) y posicionamientoabs. Los vectores decorativos aparecen como líneasvector art → assets/…con colocación — coloca los SVGs exportados, nunca los aproximes en CSS.El YAML/JSON estructurado además conserva las definiciones y valores exactos de las propiedades del componente (incluyendo INSTANCE_SWAP y SLOT), referencias a propiedades, valores preferidos, sobrescrituras directas, instancias expuestas y violaciones de slot. Los enlaces de variables incluyen identidad de colección, ámbitos creados, modos explícitos/resueltos,
codeSyntax.WEBy el valor resuelto;inferredVariablesse emite por separado como evidencia solo de sugerencia.Para una sección grande, solicita primero
depth:0. Este es un contrato completo para el contenedor de la sección en sí (incluyendo fondo, borde, radio y diseño) sin descendientes. Luego solicita los ids de nodos hijos en llamadas acotadas. Usadedup:truepara tarjetas/listas repetidas; las referencias compartidasS<n>permanecen sin pérdida y evitan que los estilos de instancias idénticas agoten el presupuesto de resultados.Verifica — captura la pantalla de tu compilación y compárala con el PNG del paso 1, luego ejecuta la comprobación mecánica:
figma_run ["verify-build", "/abs/path/to/project"]Busca en el proyecto contra
assets.jsony lista cada archivo exportado que no está referenciado en la compilación — con tamaño, desplazamientos y padre, por lo que colocarlo es un paso — más un lint deborder-image(CSSborder-imageignoraborder-radius; los trazos degradados en cajas redondeadas necesitan el patrón de envoltorio o máscara). Código de salida 1 cuando faltan archivos, por lo que también funciona como puerta de CI.Con una captura de pantalla de la compilación también ejecuta la pasada visual:
figma_run ["verify-build", "/abs/path/to/project", "--compare", "/abs/build.png"]El render de referencia se obtiene en vivo de Figma (
--node <id>, por defecto: la raíz de exportación del manifiesto) o se suministra sin conexión mediante--design <png>. Ambas imágenes se normalizan a un ancho común y se comparan píxel a píxel (tolerante al antialiasing); la salida informa el porcentaje de diferencia general, un hallazgo de desajuste de altura (compilación demasiado alta/baja = bloque insertado o eliminado), las peores regiones de diferencia en coordenadas de píxeles del nodo — el mismo espacio que usan la especificación yassets.json— y escribe un PNG de diferencias (rojo = diferente, sobre el diseño atenuado). Informativo por defecto;--max-diff <pct>controla el código de salida.
Para pantallas grandes, los agentes a nivel de sección son una optimización opcional del tiempo transcurrido después de que la captura de pantalla, el mapa de estructura, los tokens y los activos estén fijos. Úsalos solo para secciones sustanciales con archivos de componentes/estilos disjuntos; el coordinador mantiene la propiedad del shell compartido, los tokens, assets.json, la integración y la diferencia de píxeles final. Los agentes paralelos suelen consumir más tokens totales porque cada uno necesita contexto del proyecto, por lo que usa trabajo secuencial cuando el costo de tokens importa más que el tiempo de reloj.
Usa una herramienta de navegador existente o un arnés de proyecto para la captura de pantalla de la compilación. No instales Playwright (u otra dependencia de navegador) únicamente para la captura sin la aprobación del usuario; si ya está presente, es un mecanismo de captura válido en lugar de una dependencia de Figma Bridge.
La misma especificación está disponible como figma_run ["export", "code-spec", "<nodeId>"]. Su valor predeterminado es el árbol legible; pasa -f yaml o -f json para el modelo canónico.
Lossless structured spec formats
figma_spec y export code-spec tienen por defecto format:"tree", la vista de agente concisa y orientada a líneas cuyos pies llevan las acciones requeridas de activos y fidelidad. Usa yaml o json formateado explícitamente cuando un consumidor necesite el modelo canónico versionado. Ambos formatos estructurados serializan el mismo modelo; solo difiere la sintaxis. Las pruebas de ida y vuelta requieren que cada campo — texto, ids, procedencia del diseño, pintura, tipografía, variables sensibles al modo, activos, contratos de componentes, intención de Bridge, anotaciones nativas, integridad de captura y comprobaciones de fidelidad — sobreviva exactamente. No se ofrece JSON minimizado: pruebas reales con agentes mostraron que una sola línea enorme era materialmente más difícil de procesar a pesar de llevar los mismos campos sin procesar.
El campo capture del modelo informa explícitamente la profundidad solicitada/real, la integridad de la carga útil, la política de nodos ocultos y si la profundidad solicitada cortó descendientes. No hay truncamiento silencioso del resultado de la herramienta: si una especificación excede el presupuesto de salida configurado, la llamada devuelve complete:false con una receta de reintento sección por sección y devuelve ningún diseño parcial engañoso. depth:0 intencionalmente significa “solo el nodo solicitado” y es completo, no un árbol truncado en profundidad.
Los nombres de archivo de relleno IMAGE se indexan por el hash de imagen estable de Figma, no por el nombre/ruta de la capa local. Esto mantiene figma_spec, llamadas aisladas a hijos, exportación de activos y assets.json en el mismo nombre de archivo incluso cuando capas genéricas como “Frame 64” se alcanzan a través de diferentes raíces.
Para llamadas MCP de diseño a código, dedup:false es el valor predeterminado: cada capa visible mantiene su propio id, css{…} nativo de Figma Inspect, hechos de diseño/pintura/token y texto completo. Las capas de texto enriquecido mixto llevan sus rangos con estilo individuales. El pie de página concilia el recuento de capas visibles en vivo con filas explícitas, internos SVG, internos de componentes y ayudantes no renderizables. Se rechaza una proyección de estilo cuando los límites de profundidad o una capa no contabilizada forzarían la adivinación; divídela por los ids de nodo del mapa de estructura. Establece dedup:true solo para una vista general compacta usando referencias de estilo y repetición compartidas S<n>.
Para llamadas repetidas a nodos explícitos, phase, format y la deduplicación no desencadenan otra caminata completa de Figma. La caché en memoria de Design Capture está limitada a 8 entradas / 8 MiB por defecto (DESIGN_CAPTURE_CACHE_ENTRIES y DESIGN_CAPTURE_CACHE_BYTES). Cada acierto aún sondea la revisión del documento en vivo; no hay TTL ni ruta stale-while-revalidate.
Code ↔ Figma design memory
Asigna a cada componente, pantalla o frame importante un id de Entidad de Diseño duradero. El id describe el concepto, no su ubicación actual: usa nombres como ui.button, ui.account-card o screen.settings.
Después de seleccionar o identificar un nodo de Figma, un agente puede crear el enlace con:
figma_run {args:["link","set","9:9","screen.settings","--kind","screen","--source","src/routes/settings.tsx","--export","SettingsScreen","--story","screens-settings--default"], confirm:true}Esto converge dos pequeños adaptadores:
figma-bridge.jsones el Registro confirmado y revisable con rutas de código relativas al repositorio más manejadores opcionales de Storybook y Figma.Figma almacena solo
{version,id,kind}como datos de plugin en el nodo. No contiene ruta local, credencial ni estado específico de la máquina.
Usa figma_run ["link","inspect","9:9"] para resolver un nodo y figma_run ["link","list"] para inspeccionar la memoria del repositorio sin leer Figma. Una vez vinculado, figma_selection y figma_spec exponen automáticamente el mismo id y los objetivos de código/Storybook del Registro. Los agentes deben reutilizar o editar ese componente de código en lugar de crear uno similar. Repetir el mismo comando set es seguro y repara cualquiera de los lados después de una escritura interrumpida.
Después de verificar visualmente que el código y Figma corresponden, registra explícitamente sus huellas actuales. Las entidades de pantalla requieren una captura de pantalla real del navegador y un umbral de píxeles aprobado:
figma_run ["link","accept","screen.settings","--compare","/abs/build.png","--max-diff","5"]El código fuente nunca se almacena en el Registro. El Adaptador de código inicial hashea el archivo vinculado completo más su identidad de exportación; por lo tanto, una edición no relacionada en un archivo compartido puede informar conservadoramente un cambio de código, pero un cambio real nunca se oculta. El Adaptador de Figma hashea el subárbol vinculado normalizado. Para nodos de Código a Figma también almacena cada figmaBridge.semanticPath único con el hash del subárbol de ese nodo. Un link status posterior puede por lo tanto listar las rutas semánticas exactas añadidas, eliminadas o cambiadas y recomendar especificaciones con ámbito de nodo. Cambiar solo un marcador semántico no cambia la huella visual; las rutas duplicadas se informan como ambiguas en lugar de adivinadas.
figma_run ["link","status","screen.settings"]
figma_run ["link","context","screen.settings"]Estado | Significado |
| Ningún lado se movió de la línea base aceptada. |
| Solo se movió el archivo de código vinculado. |
| Solo se movió el subárbol de Figma vinculado. |
| Ambos se movieron; ningún lado se sobrescribe. |
| Aún no se ha aceptado explícitamente ninguna línea base. |
link context es el punto de entrada preferido del agente después de que existe un enlace. Devuelve la proyección relevante más pequeña: entidad, código/exportación, raíz de Figma, historia de Storybook, Plan de Ida y Vuelta actual, archivos DESIGN.md/tokens descubiertos y próximas lecturas exactas. Se genera bajo demanda, no se persiste como otro archivo de memoria. link accept escribe solo figma-bridge.json; nunca cambia Figma ni el código. Para pantallas también almacena la diferencia medida y los hashes SHA-256 de ambas imágenes de comparación, por lo que una huella estructural no puede certificar una línea base visiblemente incorrecta.
Las ubicaciones convencionales de DESIGN.md, design/DESIGN.md, tokens.json y design/tokens.json se descubren automáticamente. Configura ubicaciones personalizadas relativas al repositorio una vez cuando sea necesario:
figma_run ["link","configure","--design-doc","docs/product-design.md","--tokens","src/theme/tokens.json"]Haz commit de figma-bridge.json. No pongas secretos, rutas absolutas ni credenciales generadas en él. El esquema y las reglas de conflicto están documentados en docs/adr/0007-dual-anchor-design-entities.md, con decisiones de línea base y contexto en ADR-0008 y ADR-0009.
Reviewed CSS ↔ Figma boundary strategies
El Código Semántico a Figma usa ids de política estables en lugar de sustituciones visuales silenciosas: minmax.native-grid, space-around.equal-slots, border.single-paint-native, sticky.metadata-only, filters.layer-stack, masks.vector-mask, font.named-faces, y figma-effects.native. La matriz completa y sus paradas duras restantes están en docs/css-figma-semantic-matrix.md.
Las políticas revisadas que pierden cobertura pueden optar por una anotación nativa automática en Figma sobre el nodo semántico afectado exacto. La anotación explica el hecho CSS no compatible, enlaza las propiedades relevantes de Figma y se refleja como datos de plugin figmaBridge.fallbackAnnotations versionados para agentes futuros. Las conversiones nativas equivalentes permanecen sin anotar para evitar ruido en la revisión. La primera política activa es border.single-paint-native: Figma recibe el primer lado CSS pintado explícitamente como el trazo nativo compartido, conserva los cuatro pesos laterales y marca strokes más strokeWeight. Los renders nativos informan cuántas anotaciones de respaldo se agregaron, se deduplicaron o no fueron compatibles.
El texto DOM intrínseco de una sola línea se asigna al tamaño HUG de Figma. El texto posicionado y multilínea mantiene la geometría de caja medida; el puente no añade un margen porcentual arbitrario de ancho para evitar el ajuste de línea.
Los ejes de fuentes variables se capturan, pero la puerta estructural pregunta si la fuente requerida debe instalarse o si se debe usar un rostro con nombre disponible antes de renderizar. El Glass nativo de Figma sigue siendo un efecto nativo editable con todos los parámetros de efecto conservados; no se trata silenciosamente como CSS backdrop-filter, porque la exportación CSS de Figma no expone esos parámetros de Glass.
Espejo de Storybook
Los componentes de Figma llevan una clave de publicación estable (sobrevive a la publicación de la biblioteca; los ids de nodo son locales al archivo). La clave ahora fluye a través de figma_spec (modelo estructurado canónico + el tráiler de árbol "Conjuntos de componentes utilizados"), figma_selection, component list, figma_inspect y DESIGN.md.
Para vincularlos con su espejo de código:
figma_run ["map", "storybook", "http://localhost:6006"]Esto compara los componentes del archivo con el índice de Storybook por nombre normalizado y escribe figma-map.json en tu proyecto: clave de Figma ↔ id de historia / ruta de importación, con una confidence por coincidencia más ambas listas no coincidentes. Edita las entradas a mano y establece "matchedBy": "manual" para fijarlas; las entradas fijadas sobreviven a las re-ejecuciones. Cuando el archivo existe, figma_selection y figma_spec anotan los componentes con ↔ story <id> (<importPath>) automáticamente.
figma-map.json sigue siendo un adaptador de lectura heredado, por lo que las asignaciones existentes continúan funcionando. Los nuevos enlaces duraderos pertenecen a figma-bridge.json; link set nunca copia filas heredadas en él. Migra un componente la próxima vez que lo toques asignándole su id real de Entidad de Diseño y pasando su historia mediante --story. Elimina el archivo heredado solo después de que link list muestre todas las asignaciones que aún necesitas.
Trae tu propio sistema de diseño
Este proyecto no incluye ningún sistema de diseño — ni shadcn, ni preset de Tailwind, ni paquete de iconos. Eso es deliberado: un sistema empaquetado es la opinión de alguien más renderizada en tu archivo. Lo que incluye en su lugar es una forma de hacer legible tu sistema para un agente en un solo comando:
figma_run ["kit", "init", "./my-app", "--storybook", "http://localhost:6006"]Cuatro lecturas, un informe:
Paso | Resultado |
|
|
|
|
| inventario con claves de publicación estables |
|
|
Termina nombrando lo que aún falta — un Storybook no mapeado, componentes sin historia, el comando tokens sync que mantiene ambos sincronizados — porque una configuración que silenciosamente carece del mapeo parece terminada hasta que un agente la necesita.
DESIGN.md es lo que un agente debería leer primero; tokens.json es a lo que se vincula.
Varios archivos a la vez
El puente mantiene una conexión por ventana de Figma en la que iniciaste el plugin. Ese es el modelo de consentimiento: un archivo es accesible porque tú lo abriste e iniciaste el plugin allí — no porque una bandera amplió el alcance.
Una ventana — nada cambia. Los comandos van allí.
Varias ventanas — un comando debe nombrar su objetivo, o falla con la lista de archivos conectados:
figma_status # lists every connected window figma_run {args: ["canvas","info"], fileKey: "GY5SasBJ…"} figma_spec {nodeId: "12:34", fileKey: "GY5SasBJ…"}figma_render,figma_selection,figma_inspect,figma_screenshotyfigma_specaceptan el mismo parámetrofileKey. Una URL de nodo de Figma completa también proporciona su clave de archivo automáticamente. Sin un objetivo,figma_selectionindica qué archivos están abiertos en lugar de adivinar. En la CLI del motor la bandera es--figma-file, no--file:evalyspecya usan-f, --filepara una ruta local.
Deliberadamente no hay opción "todos los archivos". Cada escritura nombra un archivo, por lo que un comando equivocado no puede propagarse a través de una biblioteca. Dos ventanas en el mismo archivo son indistinguibles para el enrutamiento, por lo que la más nueva toma el control y a la más antigua se le informa que perdió el puente. Las entradas de auditoría llevan la clave del archivo, por lo que figma_history sigue siendo legible cuando hay varios archivos en juego.
Alcanzar archivos que no has abierto está fuera del alcance: la API REST de Figma no puede escribir contenido de documento, por lo que un cambio de nombre masivo en treinta archivos de biblioteca no es algo que esta herramienta pueda ofrecer honestamente.
FigJam
El plugin también se ejecuta en tableros FigJam, sobre el mismo puente — sin segundo transporte, sin permiso adicional:
figma_run ["jam", "sticky", "Ship the handshake", "--color", "green"]
figma_run ["jam", "stickies", "[\"Discovery\",\"Build\",\"Ship\"]", "--columns", "3"]
figma_run ["jam", "shape", "Decide?", "--type", "DIAMOND"]
figma_run ["jam", "connector", "1:2", "3:4", "--text", "yes"]
figma_run ["jam", "table", "3", "4", "--data", "[[\"Step\",\"Owner\"],[\"Handshake\",\"Alex\"]]"]
figma_run ["jam", "board"] # read everything back, with connectors
figma_run ["jam", "arrange"] # arrange only the current selection
figma_run ["jam", "arrange", "--ids", "1:2,3:4"]
figma_run ["jam", "arrange", "--all"] # explicit: whole pageLos nuevos nodos se colocan a la derecha de lo que ya esté en el tablero a menos que pases --at x,y, por lo que un agente que añade a un tablero poblado no apila todo en el origen. Cada comando verifica primero figma.editorType y dice "esto es un archivo de Figma, no un tablero FigJam" en lugar de fallar en una API indefinida. figma_status informa a qué editor está conectado el puente.
jam arrange está deliberadamente limitado al ámbito de la selección. Los agentes pueden pasar ids de nodo exactos sin cambiar la selección del usuario; reorganizar toda la página requiere el flag visible --all. Las secciones y conectores nunca son movidos por este comando. La superficie pública se probó en Figma Desktop el 2026-08-10. Los mantenedores conservan el comando detallado y la evidencia de relectura fuera del repositorio público.
Beta de Figma Slides
Slides utiliza el mismo puente de plugin autenticado. La superficie beta cubre la estructura de la presentación y las propiedades nativas de las diapositivas, no un renderizador de presentaciones separado:
figma_run ["slides", "inspect"]
figma_run ["slides", "create", "Agenda", "--row", "0", "--col", "1"]
figma_run ["slides", "duplicate", "Agenda", "--label", "Agenda alternative"]
figma_run ["slides", "move", "Agenda alternative", "1", "0"]
figma_run ["slides", "transition", "Agenda", "DISSOLVE", "--duration", "0.4"]
figma_run ["slides", "skip", "Appendix", "on"]
figma_run ["slides", "delete", "1:42"]Figma renombra los nombres nativos de las diapositivas cada vez que cambia la cuadrícula del lienzo. El argumento opcional para create y --label en duplicate por lo tanto almacenan una etiqueta Bridge duradera en los datos del plugin; inspect informa tanto el name nativo como la label estable. Las referencias se resuelven por id, nombre nativo exacto o etiqueta, luego subcadena única. La ambigüedad es un error, delete siempre requiere una referencia explícita, y duplicate/move rechazan una fila de destino inexistente en lugar de aceptar la colocación de respaldo de Figma. Cada operación verifica figma.editorType === "slides" antes de tocar una API exclusiva de Slides. Los candidatos abiertos y los criterios para salir de beta residen en docs/slides-roadmap.md; la aceptación del editor es verificada por los mantenedores por separado del repositorio público.
Sincronización de tokens (bidireccional)
tokens import solo crea, por lo que un valor editado en código nunca llega a una variable de Figma existente y un valor editado en Figma nunca llega al código. tokens sync cierra ese bucle:
figma_run ["tokens", "sync", "src/tokens.json"] # plan only
figma_run ["tokens", "sync", "src/tokens.json", "--apply"] # write itLa superficie de importación es más amplia que la superficie de sincronización. El import de una sola vez acepta configuraciones de Tailwind v3, Tailwind v4/CSS, índices de Storybook, JSON DTCG/W3C y las formas de tokens compatibles con DTCG exportadas por Style Dictionary y Tokens Studio. Esa compatibilidad no incluye semántica de temas de Tokens Studio ni preprocesadores arbitrarios; los metadatos como $themes se ignoran mientras se leen los conjuntos de tokens y alias.
Las nuevas variables FLOAT en espacios de nombres explícitos spacing/* o space/* se limitan a los consumidores GAP de Figma solamente. Las variables radius/* y radii/* se limitan a CORNER_RADIUS solamente. La inferencia es deliberadamente exacta al espacio de nombres: nombres como spacingFactor se dejan en el ámbito predeterminado de Figma, y el renderizado no cambia silenciosamente los ámbitos de las variables de usuario o biblioteca existentes. Otras nuevas variables COLOR, FLOAT o STRING muestran SCOPE DECISION REQUIRED con solo las opciones de Figma compatibles. El agente debería preguntar antes de reducirlas; inspecciona el catálogo con figma_reference {name:"variable-scopes"} y aplica la respuesta con figma_run ["var","update","<name>","--collection","<collection>","--scopes","TEXT_FILL,STROKE_COLOR"].
La sincronización segura a tres bandas acepta solo tokens de diseño DTCG / W3C (.json, lo que emite export dtcg) y propiedades personalizadas CSS (.css, lo que emite export css). Las $variables de Sass no son propiedades personalizadas CSS y se rechaza .scss en lugar de analizarlo parcialmente. Ten en cuenta que export dtcg escribe todas las variables locales en un archivo mientras que la sincronización apunta a una colección — pasa --collection en consecuencia. Si la mayoría de los nombres en el archivo ya viven en otra colección, la sincronización lo dice en lugar de ofrecer duplicarlos. Las configuraciones de Tailwind son solo una fuente de importación — su analizador agrupa valores en color/espaciado/radio y no puede hacer un viaje de ida y vuelta, por lo que la sincronización las rechaza por nombre en lugar de eliminar silenciosamente tokens que no entendió.
Por qué un archivo de bloqueo. Una sincronización bidireccional sin memoria no puede distinguir "el código cambió" de "Figma cambió" — solo ve que los dos difieren, y la dirección que elija destruye el trabajo del otro lado. figma-tokens.lock.json registra el estado en la última sincronización exitosa, por lo que cada decisión es una comparación a tres bandas:
código | Figma | resultado |
cambió | sin cambios | actualizar Figma |
sin cambios | cambió | reportado, nunca sobrescrito — actualiza tu archivo de código |
ambos cambiaron | conflicto — no se aplica nada | |
sin cambios | sin cambios | sin cambios |
Los conflictos detienen toda la ejecución. Resuélvelos editando un lado, o decídelos todos a la vez con --ours (gana el archivo de código) / --theirs (gana Figma, y no se escribe nada en Figma).
Las eliminaciones necesitan --prune, y aún así solo tocan variables que la propia sincronización creó — una variable que nunca rastreó se reporta como no rastreada y se deja intacta.
El archivo de bloqueo también almacena el id de Figma de cada variable, que es lo que convierte un cambio de nombre en un cambio de nombre en lugar de un borrar más un crear que perdería todos los enlaces de capa. El emparejamiento es por valor y solo cuando no es ambiguo: cambiar el nombre y el valor de un token en el mismo commit vuelve a crear + borrar, así que haz esos dos pasos si los enlaces importan.
Sin --apply el comando sale con código 1 cuando hay cambios pendientes, por lo que funciona como una verificación de CI para "¿está Figma sincronizada con el repo?".
Vinculación, y cambiar qué colección sigue un diseño
tokens sync escribe valores de token. Dos cosas vecinas que deliberadamente no hace:
figma_run ["node", "bind", "12:34", "radius", "radius/lg", "--collection", "TARGET_COLLECTION"]
figma_run ["tokens", "rebind", "TARGET_COLLECTION", "--node", "12:34"] # plan
figma_run ["tokens", "rebind", "TARGET_COLLECTION", "--node", "12:34", "--apply"] # writenode bind adjunta una variable a una propiedad de un nodo existente — fill, stroke, radius, gap, padding (o un lado), opacity, stroke-width, width, height. Su contraparte de lectura es node bindings. Pasa --batch con un array JSON para vincular muchas propiedades o nodos en una sola llamada.
Un nombre de variable que no es único es rechazado, no adivinado — este archivo tiene radius/lg en dos colecciones, y la respuesta nombra ambas para que --collection pueda resolverlo. El tipo de la variable se verifica contra la propiedad primero, por lo que un COLOR en radius falla con una oración en lugar de un rastro de pila del plugin.
Las variables de tipografía tienen su propio comando con reconocimiento de rango porque el texto puede llevar diferentes vinculaciones en diferentes intervalos de caracteres:
figma_run ["font", "bind", "12:36", "fontWeight", "type/weight", "--collection", "Typography"]
figma_run ["font", "bind", "12:36", "line-height", "type/line-height", "--start", "0", "--end", "12"]
figma_run ["font", "unbind", "12:36", "lineHeight", "--start", "0", "--end", "12"]Los campos enlazables son fontFamily, fontSize, fontStyle, fontWeight,
letterSpacing, lineHeight, paragraphSpacing y paragraphIndent;
también se aceptan las grafías en kebab-case. Las fuentes existentes —y para los
enlaces de familia/estilo/peso los estilos de familia disponibles relevantes— se
cargan antes de que se cambie el enlace. Los nombres de variables se rechazan cuando
son ambiguos, y se comprueba STRING vs FLOAT antes de llamar a Figma. Un enlace
numérico de fontWeight sigue sin ser un asignador general de ejes de fuentes
variables: Figma selecciona un peso válido para la fuente activa.
tokens rebind es el cambio de tema: recorre un subárbol y reasigna cada
enlace a la variable del mismo nombre en una colección destino. Diseña una
tarjeta contra SOURCE_COLLECTION, ejecuta rebind con TARGET_COLLECTION, y la
misma tarjeta sigue los valores de la colección destino — sin rediseño. Por
defecto planifica; --apply escribe. Los tokens
sin contraparte en el destino se listan y se dejan apuntando donde estaban,
así que un tema parcial es un informe, no un diseño a medio estropear.
node set cambia propiedades en nodos que ya existen — fill, stroke,
strokeWidth, radius, opacity, x, y, width/height, name,
visible — un nodo a la vez o muchos mediante --batch, lo cual importa porque
la forma por lotes es un viaje de ida y vuelta:
figma_run ["node", "set", "12:34", "--name", "Card", "--radius", "12"]
figma_run ["node", "set", "--batch", "[{\"node\":\"12:35\",\"fill\":\"var:sage/50\",\"name\":\"Badge\"}]"]Un color acepta un hex o var:<name>. La diferencia no es cosmética: un hex está
congelado, una referencia var: permanece enlazada, por lo que un posterior
tokens rebind puede moverla aún.
Estilos locales, metadatos de variables y modos
Las primitivas locales del sistema de diseño que antes requerían trabajo manual en la UI ahora tienen Figma Commands de primera clase. Utilizan la API de Plugin en vivo, no REST:
figma_run ["style", "list", "--type", "TEXT"]
figma_run ["style", "show", "Heading/H1"]
figma_run ["style", "create", "PAINT", "Brand/Primary", "--properties", "{\"paints\":[{\"type\":\"SOLID\",\"color\":{\"r\":0.1,\"g\":0.3,\"b\":0.9}}]}"]
figma_run ["style", "apply", "Brand/Primary", "12:34,12:35", "--field", "fill"]
figma_run ["style", "consumers", "Brand/Primary"]
figma_run ["style", "publish-status", "Brand/Primary"]
figma_run ["style", "bind-font", "Body", "fontSize", "--variable", "type/size/body"]
figma_run ["style", "unbind-font", "Body", "fontSize"]style cubre los estilos locales PAINT, TEXT, EFFECT y GRID. update acepta las
mismas propiedades JSON específicas de tipo que create; apply valida el tipo
de estilo contra fill, stroke, text, effect o grid. Las búsquedas por nombre rechazan
ambigüedad. Los consumidores provienen de getStyleConsumersAsync(), y el estado de publicación es
uno de los valores UNPUBLISHED, CURRENT o CHANGED de Figma.
Las variables exponen los metadatos y las operaciones de modo que la sincronización de archivos de tokens no posee:
figma_run ["var", "show", "space/md", "--collection", "Primitives"]
figma_run ["var", "update", "space/md", "--description", "Medium spacing", "--scopes", "GAP"]
figma_run ["var", "set-value", "space/md", "12", "--mode", "Light"]
figma_run ["var", "set-value", "space/card", "--alias", "space/md", "--mode", "Light"]
figma_run ["var", "code-syntax", "space/md", "WEB", "var(--space-md)"]
figma_run ["var", "resolve", "space/md", "12:34"]
figma_run ["col", "mode-add", "Primitives", "Dark"]
figma_run ["col", "mode-rename", "Primitives", "Dark", "Dim"]
figma_run ["col", "extend", "Primitives", "Brand"]var show devuelve valores por modo, ámbitos, sintaxis de código, metadatos de colección y
estado de publicación. var resolve requiere deliberadamente un nodo consumidor porque
los alias pueden resolverse de manera diferente bajo los modos seleccionados de ese nodo. Las operaciones
show, update, mode-add, mode-rename, mode-remove y
publish-status de colección siguen la misma política de búsqueda por ID/nombre exacto/subcadena única.
Los límites de Figma en la cantidad de modos permanecen impuestos por Figma y se manifiestan como errores.
Las extensiones de colección usan VariableCollection.extend() para colecciones locales
y extendLibraryCollectionByKeyAsync() para claves publicadas. Figma restringe
esta característica a planes Enterprise; el CLI informa el error de plan de Figma sin cambios.
Los enlaces de estilo de texto admiten exactamente los campos de tipografía enlazables de Figma:
familia, estilo, peso, tamaño, altura de línea, espaciado entre letras y valores de párrafo.
Bibliotecas de equipo habilitadas
El descubrimiento e importación de bibliotecas también se mantienen en el transporte autenticado de plugins:
figma_run ["library", "collections"]
figma_run ["library", "variables", "Acme/Primitives", "--type", "COLOR"]
figma_run ["library", "import-variable", "<published-variable-key>"]
figma_run ["library", "import-style", "<published-style-key>"]
figma_run ["library", "import-component", "<published-component-key>"]
figma_run ["library", "import-component-set", "<published-component-set-key>"]collections y variables son lecturas. Los cuatro comandos import-*
materializan activos publicados en el archivo actual y, por lo tanto, son escrituras en el
Catálogo de Capacidades. Figma solo expone el descubrimiento para colecciones de variables
y variables. Los estilos, componentes y conjuntos de componentes publicados pueden importarse
cuando su clave estable ya se conoce, pero la API de Plugin no puede enumerarlos.
Las bibliotecas deben estar habilitadas para el archivo actual en la UI de Figma antes de que
library collections pueda verlas; la API de Plugin no puede habilitar una biblioteca.
El plugin enviado ya declara el permiso teamlibrary requerido.
La búsqueda de nombres usa la clave de colección, el nombre exacto de la colección y luego una subcadena
inequívoca de colección o nombre de biblioteca. El descubrimiento de bibliotecas tiene un tiempo de espera de
18 segundos de la API de Plugin por debajo del límite de Bridge, por lo que una solicitud de biblioteca de Figma
estancada nombra la operación y sugiere verificar si la biblioteca está habilitada en lugar de degradarse a un
tiempo de espera de ejecución genérico.
Prototipos, mediciones en modo Dev y anotaciones
Estas características de documento también son prioritarias para la API de Plugin:
figma_run ["prototype", "inspect", "12:34"]
figma_run ["prototype", "add", "12:34", "--trigger", "click", "--navigate-to", "12:36"]
figma_run ["prototype", "set", "12:34", "--json", "[{\"trigger\":{\"type\":\"ON_CLICK\"},\"actions\":[{\"type\":\"BACK\"}]}]"]
figma_run ["measure", "add", "12:34:right", "12:36:left", "--offset", "16", "--text", "gap"]
figma_run ["annotate", "categories"]
figma_run ["annotate", "add", "Review spacing", "--node", "12:34", "--category", "Review", "--properties", "width,fontSize"]
figma_run ["annotate", "edit", "12:34", "0", "--text", "Resolved"]prototype set --json es la forma sin pérdida para las múltiples acciones de Figma,
SET_VARIABLE, SET_VARIABLE_MODE y bloques condicionales. Escribe a través de
setReactionsAsync() por lo que se admiten manifiestos de página dinámica. Las escrituras de
medición están protegidas para el modo Dev de Figma y usan los métodos de medición nativos de
PageNode. Los índices de anotación son basados en cero; los comandos de crear/editar/eliminar
categorías personalizadas están disponibles junto con categories. Estas notas de revisión manual son
independientes de las Anotaciones de Límite de Retroceso automáticas del renderizador semántico,
que se emiten solo mediante políticas de mapeo con pérdida explícitamente aceptadas y siguen siendo
legibles por máquina a través de datos de plugin.
APIs de Plugin 2026: video, sombreadores, cuadrícula, slots y Draw
La superficie actual de la API oficial de Plugin se expone como Figma Commands en lugar de llamadas REST:
figma_run ["export", "video", "12:34", "--format", "mp4", "--fps", "30", "-o", "/abs/demo.mp4"]
figma_run ["shader", "list"]
figma_run ["shader", "import", "<shader-id>"]
figma_run ["shader", "apply", "12:34", "<shader-id>", "--field", "fill", "--properties", "{\"definition-id\":0.8}"]
figma_run ["layout", "grid", "set", "12:34", "--rows", "2", "--columns", "3", "--row-gap", "12"]
figma_run ["layout", "grid", "auto-flow", "12:34", "--auto-tracks", "rows", "--positioning", "row_auto_flow"]
figma_run ["slot", "create", "12:37", "Content", "--settings", "{\"minChildren\":1,\"maxChildren\":3}"]
figma_run ["slot", "validate", "12:37"]
figma_run ["draw", "inspect", "12:38"]
figma_run ["draw", "text-path", "12:38", "--text", "Around the curve"]
figma_run ["draw", "stroke-profile", "12:38", "--preset", "TAPER"]
figma_run ["draw", "pattern", "12:38", "12:39", "--field", "fill"]La exportación de video resuelve un descendiente seleccionado a su fotograma animado de nivel superior
y acepta solo los valores FPS específicos de formato de Figma. Las propiedades del sombreador se
identifican por ID de definición, no por nombre para mostrar, y un sombreador disponible debe
importarse antes de aplicarse. layout grid significa el modelo GRID de auto-layout;
el comando grid de nivel superior anterior sigue siendo la gestión de guías de diseño.
Los slots exponen SlotSettings en GA, valores preferidos, reinicio y violaciones de límite;
JSX <Slot> ahora usa ComponentNode.createSlot() y valida los límites configurados después del renderizado.
Los comandos Draw cubren trazados de texto, grupos de transformación repetidos, trazos
stretch/scatter/dynamic, perfiles de ancho variable y setters asíncronos de relleno/trazo de patrón.
Ejecuta las lecturas inspect/validate correspondientes antes de las escrituras al modificar un documento
desconocido.
Encontrar lo que necesita reparación
figma_run ["analyze", "lint", "--node", "12:34"]Una pasada para las cuatro cosas en las que actúa una revisión de sistema de diseño: colores que coinciden
con una variable existente pero no están enlazados a ella, capas que aún llevan un nombre por defecto,
texto sin estilo, texto por debajo de 12px. --fail-on-issues lo convierte en una puerta de CI;
--kind lo acota; --json nunca trunca.
Un color codificado solo se informa cuando una variable ya tiene ese valor exacto — de lo contrario, el hallazgo es ruido sobre el que no se puede actuar. Debido a que la coincidencia se conoce, cada uno llega con el comando que lo repara:
unbound token colour — 1
12:35 Badge fill is #8a9a8d, which is sage/400
fix: node bind 12:35 fill "sage/400" --collection "Sprout Primitives"analyze colors|typography|spacing aún proporciona el censo completo. Lint es la
pasada que responde si hay algo que hacer.
Fuentes variables y hechos OpenType
Figma no expone una tupla general de ejes de variación a través de la API de Plugin. Por lo tanto, el puente separa los hechos que Figma realmente informa de la intención de eje que un llamador registra explícitamente:
figma_run ["font", "inspect", "12:36"]
figma_run ["font", "inspect", "12:36", "--start", "0", "--end", "12", "--all-open-type"]font inspect devuelve rangos de texto con estilo con fontName, fontWeight
numérico de solo lectura, tamaño, etiquetas de características OpenType habilitadas y enlaces de variables
de tipografía resueltas. --all-open-type también incluye valores de características falsos. El
resultado nombra el límite de la API explícitamente: un fontWeight informado no es una tupla
general wght/wdth/opsz/eje personalizado, y las características OpenType son de solo lectura.
Cuando los valores exactos del eje se conocen desde la UI u otra herramienta de fuentes, consérvalos en el nodo de texto como metadatos de rango:
figma_run ["font", "remember-axes", "12:36", "wght=357,wdth=82", "--start", "0", "--end", "12"]
figma_run ["font", "axes", "12:36"]
figma_run ["font", "forget-axes", "12:36", "--start", "0", "--end", "12"]
figma_run ["font", "forget-axes", "12:36"] # clear every stored rangeremember-axes cambia solo los metadatos del plugin — nunca la fuente o los glifos
renderizados — y, por lo tanto, se clasifica como una escritura por el Catálogo de Capacidades.
figma_spec lleva estos registros como axes-meta[inicio:fin](etiqueta=valor,…), más
el valor fw… informado por Figma y las etiquetas ot(…) habilitadas, para que la captura
de diseño a código no descarte silenciosamente la intención documentada.
Hechos nativos de la API de Plugin
Dos comandos de lectura exponen las representaciones propias de Figma sin contactar la API REST:
figma_run ["node", "css", "12:34"]
figma_run ["node", "css", "12:34", "--json"]
figma_run ["export", "node-json", "12:34"]
figma_run ["export", "node-json", "12:34", "-o", "facts/card.json"]node css llama a getCSSAsync() y devuelve las declaraciones que Figma expone para
su panel de Inspección. Esto está deliberadamente separado de export css, que
exporta propiedades personalizadas de tokens de diseño. export node-json usa
exportAsync({format:"JSON_REST_V1"}): la forma se asemeja al esquema de archivo REST,
pero los bytes provienen del documento de plugin en vivo y no necesitan ni un token
ni una solicitud de red.
Historial de versiones y diferencias
La API de plugin de Figma puede escribir una versión pero no leer una, por lo que "qué cambió
desde esta mañana" no tiene respuesta solo desde el puente. history proporciona una
sin ninguna credencial: registra la estructura de un subárbol, la registra de nuevo más tarde,
compara las dos.
figma_run ["history", "save", "Before refactor", "--description", "Agent restore point"]
figma_run ["history", "snapshot", "--label", "before refactor"]
# … agent works …
figma_run ["history", "diff", "latest", "live"]history save crea la entrada nombrada directamente a través de
saveVersionHistoryAsync() y es una escritura de Figma. snapshot, list y diff
siguen siendo operaciones de Figma locales/solo lectura; la lectura de las versiones históricas
nativas de Figma aún requiere el complemento REST opcional.
Una instantánea almacena un registro normalizado por nodo — geometría, diseño, pinturas,
tipografía, claves de componente — más un hash de contenido y un hash de subárbol, por lo que el
comparador puede informar una sección no tocada en lugar de recorrerla. Viven en
~/.figma-bridge-mcp/snapshots/<fileKey>/, comprimidos con gzip, se mantienen los 20 más recientes.
Las referencias son latest, previous, un índice de history list, un nombre de archivo, o
live para el documento en este momento. El informe separa añadido, eliminado,
reemplazado, movido y cambiado — esa última distinción es la que
importa en la práctica: un agente que elimina un marco y lo vuelve a renderizar mantiene la
ruta del nombre pero obtiene nuevos ids de nodo, y sin la detección de reemplazo cada
re-renderizado se leería como cien eliminaciones. --changelog emite markdown en su lugar;
diff sale con 1 cuando algo difiere, por lo que también funciona como puerta de CI.
A través de MCP esto es un parámetro, no una decimotercera herramienta:
figma_history {diff: {from: "latest", to: "live"}}
figma_history {diff: {from: "version:1234", to: "version:5678"}} # REST add-onLas referencias version: pasan por la capa REST y comparan lo que los diseñadores guardaron, usando
el mismo comparador. Las dos fuentes no pueden mezclarse en una sola diferencia: un documento REST
y una instantánea de plugin exponen propiedades diferentes, por lo que cada nodo parecería
cambiado — la herramienta lo dice en lugar de producir un muro de salida engañoso.
Motion
Figma Motion (Config 2026 Beta) es accesible a través de figma_run con
["motion", …]: pistas de fotogramas clave (add), especificaciones completas desde JSON (apply),
preajustes con nombre (preset), desplazamientos coreografiados entre nodos (stagger),
estilos de animación de primera parte de Figma (styles, style), duración de fotograma
(timeline), lectura inversa (inspect) y eliminación (clear).
Como cualquier otro comando, se ejecuta sobre el puente del plugin — no hay
un transporte separado para ello. styles e inspect son lecturas; todo lo demás, incluyendo
timeline (lee o establece según sus argumentos), cuenta como escritura
bajo FIGMA_WRITE_CONFIRM=1.
Motion se está implementando detrás de un indicador Beta de Figma. Sin acceso, los comandos
fallan con un error MOTION_DISABLED con nombre que te dice que actualices Figma Desktop
en lugar de un fallo genérico de API.
Complemento REST (opcional)
Todo lo anterior funciona con cero credenciales de Figma. Tres cosas que el puente de plugin local estructuralmente no puede alcanzar viven detrás de la API REST de Figma, y pueden desbloquearse con un token de acceso personal:
Característica | Qué añade |
Historial de versiones |
|
Comentarios |
|
Metadatos de biblioteca |
|
Activación: el token nunca sale de tu máquina:
Crea un token de acceso personal en Figma (Configuración → Seguridad → Tokens de acceso personal) con los ámbitos: Contenido del archivo (lectura), Versiones del archivo (lectura), Comentarios (lectura y escritura). Usuario actual (lectura) es opcional — solo hace que
figma_statusmuestre tu nombre de usuario.Abre el plugin Figma Bridge en Figma Desktop, conéctate (el campo aparece una vez que el plugin está autenticado) y expande "REST token (opcional)". Pega el token, Guardar token.
figma_statusinforma que el token está configurado sin hacer una solicitud remota. Ejecutafigma_status {validateRest:true}cuando quieras una verificación explícita de validez; informa tu nombre de usuario o verifica el acceso al archivo cuando el ámbito opcional Usuario actual está ausente.
El token viaja desde el plugin a través del WebSocket localhost autenticado
hasta el demonio, que lo almacena en ~/.figma-bridge-mcp/rest-token
(modo 0600). Nunca se introduce en el chat, nunca se almacena en la
configuración de tu cliente MCP, nunca es devuelto por ninguna herramienta y
nunca se escribe en el registro de auditoría (las llamadas REST se registran
solo como método + ruta). Borrar token en el plugin elimina el archivo.
Alternativa sin interfaz/CI: establece la variable de entorno
FIGMA_REST_TOKEN — anula el archivo.
Ámbito: por defecto, las llamadas REST apuntan al archivo actualmente
abierto en Figma Desktop (el plugin envía su clave de archivo). Otros archivos
requieren un parámetro fileKey explícito (clave simple o URL completa de
Figma). Ten en cuenta que un PAT puede leer todos los archivos a los que su
cuenta tiene acceso — mantén los ámbitos al mínimo.
El cliente REST es una lista blanca interna cerrada, no una puerta de escape HTTP genérica. Permite el estado del token, listas de versiones, contenido de documentos anclados a una versión, comentarios y metadatos de componentes publicados de todo el archivo. Una solicitud simple del archivo actual y todos los endpoints de nodo/CSS/exportación/variable/estilo/Recurso de desarrollo son rechazados antes de que se lea el token o se toque la red; esas operaciones deben usar los comandos locales de la API del Plugin mencionados anteriormente.
Modelo de seguridad
No se requiere token de la API de Figma — Figma se controla a través del plugin local, nunca de
api.figma.com. El complemento REST es estrictamente opcional: sin un token, la ruta de código está inactiva, y con uno, el token reside en un archivo 0600 (o en tu propia variable de entorno), no en la configuración del cliente MCP.Sin parches binarios — El modo Yolo/CDP se ha eliminado del motor integrado.
Comandos controlados por capacidades —
figma_runsolo acepta Comandos expuestos por el Catálogo de Capacidades;connectno está expuesto, por lo que se aplica la conexión solo en Modo Seguro. El mismo plan resuelto impulsa la puerta de confirmación de escritura, el requisito de destino y la política de reintentos, evitando la deriva del adaptador.Sin shell — el motor se inicia con
execFile(shell:false).Autenticación del demonio en dos capas, sin secreto en el cable — solicitudes HTTP firmadas (HMAC por solicitud sobre método/ruta/cuerpo, con clave del token de sesión, protección de repetición con nonce) + un apretón de manos mutuo de desafío-respuesta en el socket del plugin (lista blanca de
Origin/Host). Ni el token de sesión ni la clave de acceso se transmiten nunca en ninguna dirección — consulta Apretón de manos.Plugin bloqueado a localhost —
plugin/manifest.jsonrestringenetworkAccess.allowedDomainsaws://127.0.0.1:3456–3460.Estado aislado — token, pid, clave y registro de auditoría viven bajo
~/.figma-bridge-mcp/, separados de cualquier instalación ascendente de figma-ds-cli.Registro de auditoría — cada comando ejecutado se añade a
~/.figma-bridge-mcp/audit.log(con ids de nodo tocados, etiquetas opcionales y una entrada de finalización que registra éxito/fracaso — la fuente de datos parafigma_history). Rota a los 5 MB; se mantiene una generación anterior (audit.log.1) que aún es leída porfigma_history.
Puerto de reserva. El demonio enlaza el primer puerto libre en 3456–3460 y
lo publica en ~/.figma-bridge-mcp/daemon-port; las capas CLI/MCP resuelven el
puerto por llamada (env DAEMON_PORT > archivo de puerto > 3456), y el plugin
escanea todo el rango, por lo que un proceso externo que ocupe el 3456 ya no
bloquea la conexión. La comprobación del ocupante es una sonda /health no
autenticada, y las solicitudes autenticadas están firmadas con HMAC — un
ocupante en un puerto del rango no ve ni el token de sesión ni nada que pueda
repetir (las firmas vinculan la marca de tiempo, el nonce, el método, la ruta y
el cuerpo; el demonio rechaza los nonces reutilizados). El socket del plugin es
seguro en cualquier puerto del rango por la misma razón: el apretón de manos
siguiente no transporta ningún secreto y vincula el puerto en el que se ejecutó.
Establecer DAEMON_PORT explícitamente deshabilita la reserva; los valores
fuera de 3456–3460 no son compatibles — el manifiesto del plugin está impuesto
por Figma y no puede alcanzarlos.
Apretón de manos
El socket del plugin ejecuta un desafío-respuesta mutuo (proto 2,
engine/src/lib/plugin-handshake.js):
daemon → plugin {type:'challenge', proto:2, nonce:<dNonce>, port:<bound>}
plugin → daemon {type:'hello', proto:2, nonce:<pNonce>, version, proof}
daemon → plugin {type:'hello-ack', proof, restTokenConfigured}donde proof = HMAC-SHA256(clave de acceso, transcripción) sobre ambos nonces,
el puerto vinculado y la versión del plugin — con etiquetas de rol distintas y
orden de nonces por dirección, por lo que ninguna prueba puede repetirse como la
otra. De ello se derivan tres propiedades:
La clave nunca cruza el cable. Un proceso que enlaza un puerto del rango antes que el demonio y registra todo el intercambio aprende un HMAC sobre nonces que nunca volverá a ver. Esto elimina el riesgo residual que documentaban versiones anteriores, donde la clave en bruto era el primer marco que enviaba el plugin.
El demonio también se demuestra a sí mismo. Antes del proto 2, el plugin confiaba en quien respondiera y ejecutaba cualquier
evalque se le enviara — hacerse pasar por el demonio no requería ninguna clave. El panel ahora rechaza todo comando hasta que el acuse de recibo se verifica.El puerto vinculado está dentro de la transcripción. Un ocupante en el 3456 que reenvía al demonio real en el 3457 hace que el plugin firme el 3456 mientras que el demonio verifica el 3457, por lo que el relé colapsa.
No hay reserva del proto-1. figma_connect actualiza los archivos del plugin
instalado en cada ejecución, por lo que actualizar es: ejecuta
figma_connect, luego cierra y vuelve a abrir la ventana del plugin — un
panel obsoleto recibe un error con nombre que dice exactamente eso, en lugar de
un apretón de manos silenciosamente más débil.
El panel lleva su propia implementación de SHA-256/HMAC: la interfaz de usuario
del plugin es un iframe de origen nulo en un entorno aislado, donde la
disponibilidad de WebCrypto no es nuestra responsabilidad garantizar, y una
reserva silenciosa a algo más débil es el peor resultado para un apretón de
manos de autenticación. tests/plugin-handshake.test.js ejecuta ese código
enviado contra el crypto de Node para que las dos implementaciones no puedan
desviarse.
Limitaciones conocidas
Figma Slides está en beta y deliberadamente acotado. Se admiten la inspección de cuadrículas, la creación/duplicación/movimiento/eliminación de diapositivas, el estado de omisión y las transiciones. Las notas del orador, las encuestas/inserciones interactivas, los controles del presentador y un flujo de trabajo completo de creación de contenido no lo están. Consulta la hoja de ruta de Slides para candidatos accionables frente a los límites de la API del Plugin.
Las acciones de red que no sean localhost son pocas y explícitas:
api setup(clonación única de git del espejo de la documentación de la API del Plugin de Figma, parafigma_reference;api gapmide en su lugar contra el paquete oficial instalado@figma/plugin-typings), la obtención del índice de Storybook deimport/map storybook(la URL/directorio que proporciones), y — solo cuando optas por el complemento REST — llamadas aapi.figma.com. Nada más habla con la red — las integraciones de iconify/unsplash/remove.bg/screenshot-url del upstream se eliminaron por completo;<Icon>en el JSX defigma_renderse renderiza como un marcador de posición con nombre (los iconos reales salen del archivo de Figma a través deexport assets).Un transporte, sin restos de CDP. Cada comando llega a Figma de la misma forma: motor → demonio → eval del plugin. El cliente Chrome-DevTools del upstream, su viaje redondo de shell
figma-use, el asistente de instalación de parches binarios y la dependenciafigma-usehan desaprecido (~5.600 líneas eliminadas), por lo que no hay una segunda ruta de código que pueda eludir el puente del plugin.
Desarrollo
npm run check:contracts # static JavaScript seam + plugin contracts
npm run check:architecture-latency # warmed latency budget in an idle process
npm run measure:architecture # context, payload and local latency baselines
npm test # all contracts and regression suitesEl lenguaje de dominio actual vive en CONTEXT.md, las decisiones
arquitectónicas aceptadas en docs/adr/, la cobertura de la API
en docs/figma-plugin-api-coverage.md y
las instrucciones de lanzamiento en docs/releasing.md. El
índice de documentación pública es docs/README.md.
Evita ejecutar un figma-cli del upstream al mismo tiempo. El demonio ahora
reserva dentro de 3456–3460 cuando el 3456 está ocupado, por lo que ambos
pueden coexistir, pero el plugin escanea todo el rango y los dos demonios
usan diferentes claves de acceso — a cuál llegue primero el plugin es un
lanzamiento de moneda. Esta compilación aísla sus propios archivos de
token/pid/puerto bajo ~/.figma-bridge-mcp/.
Licencia
figma-bridge-mcp se publica bajo la Licencia MIT. Se proporciona
"tal cual", sin garantía; los términos exactos de garantía y responsabilidad
están en la propia licencia. Los avisos de derechos de autor y licencias de
terceros se conservan en NOTICE y
engine/LICENSE.
Inspiración y atribución
Dos proyectos dieron forma a este, de diferentes maneras.
figma-cli (Sil Bormüller) es de
donde proviene el directorio engine/: se integró en la v2.1.0 en julio de
2026 y ha divergido desde entonces — el transporte CDP y el instalador de
parches binarios han desaparecido, el socket del plugin está autenticado, y la
mayor parte de lo que hace el motor ahora se escribió aquí. Cuatro archivos
permanecen byte-idénticos al upstream. La licencia MIT del upstream se conserva
en su totalidad en engine/LICENSE, y
NOTICE registra lo que cambió.
figma-console-mcp contribuyó con una idea más que con código: que un puente de Figma puede ser genuinamente local — un socket de plugin en la interfaz de bucle local, sin relé en la nube, sin binario parcheado. Nada de esto se deriva de su fuente; las superfices de la herramienta, el transporte y el plugin no están relacionados. Donde este proyecto se diferenca es que el socket también demuestra quién está al otro lado.
Identidad del plugin. Los manifiesos de desarrollo usan los ids alineados
con el producto figma-bridge-mcp y figma-bridge-mcp-dev. Figma clavea
clientStorage — donde vive la clave de acceso emparejada — en el id del
plugin. Las instalaciones anteriores a la 0.5.0, por lo tanto, necesitan
reimportar el manifieso y pegar su clave de acceso de Bridge existente una vez.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityBmaintenanceLocal-first MCP server that connects AI coding agents to the currently open Figma file through a local plugin bridge, requiring no Figma API token.8MIT
- Alicense-qualityCmaintenanceAn open-source MCP server that gives AI assistants full read-write access to Figma, enabling creation, editing, and deletion of designs directly without plugins or API keys.7510MIT
- Flicense-qualityAmaintenanceA local MCP server that gives AI agents live access to open Figma files for design handoff and UX writing without API tokens or rate limits.2
- Flicense-qualityBmaintenanceA self-hosted MCP server that enables AI agents to retrieve Figma design data for generating code, templates, or custom prompts.2,156
Related MCP Connectors
The Figma MCP server brings Figma design context directly into your AI workflow.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/KaiUweHella/figma-bridge-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server