Skip to main content
Glama
lostpunk
by lostpunk
README.md
# Figma Local MCP

Локальный MCP для чтения, редактирования и создания макетов с нуля через Figma Plugin API. Версия 0.6.2: переносимый пакет и скилл с профилем shadcn/ui, правилами проекта и сценарием style guide → компоненты → экраны.

```text
MCP-клиент → stdio → Node.js MCP → WebSocket 127.0.0.1:3055
                                        ↓
                            плагин в Figma Desktop
                                        ↓
                          Plugin API открытого файла
```

Сервер и плагин не вызывают Figma REST API, официальный Figma MCP или Figma AI. Токен Figma не нужен. Поэтому эти команды не создают запросов, учитываемых в квотах REST API и официального MCP. Это вывод из архитектуры, а не обещание неограниченного доступа к любым возможностям Figma. Синхронизация самого редактора с Figma продолжает работать обычным образом; лимиты AI-клиента также сохраняются.

Основания: [лимиты официального MCP](https://developers.figma.com/docs/figma-mcp-server/rate-limits-access/), [лимиты REST API](https://developers.figma.com/docs/rest-api/rate-limits/), [доступ к документу из плагина](https://developers.figma.com/docs/plugins/accessing-document/).

## Передача и установка

Скачайте/передайте ZIP из `dist/`. Он содержит собранный сервер, Figma-плагин, скилл и исходники. Получателю нужны Node.js 22+ и Figma Desktop; устанавливать npm-зависимости не требуется.

### Установка из GitHub

Клон исходников предназначен для разработчиков и пользователей без доступа к SkillStore. Нужны Node.js 22+, npm и Python 3:

```bash
git clone https://github.com/lostpunk/figma-local-mcp.git
cd figma-local-mcp
npm ci
npm run release
node scripts/setup.mjs --codex
```

После setup импортируйте `generated/figma-plugin/manifest.json` в Figma Desktop и запустите плагин. Локальные ключи подключения создаются только на компьютере пользователя и не хранятся в GitHub.

Из распакованной папки выполните:

```bash
node scripts/setup.mjs --codex
```

Затем импортируйте `generated/figma-plugin/manifest.json` в Figma Desktop и запустите плагин. Он подключается автоматически, без ввода кода, и восстанавливает связь после перезапуска MCP. Держите его окно открытым. Установщик создаёт отдельный локальный ключ для каждого получателя; передавайте только ZIP из `dist/`.

- [INSTALL.md](INSTALL.md) — пошаговая инструкция для получателя и других MCP-клиентов.
- [CUSTOMIZE.md](CUSTOMIZE.md) — правила проекта, UI-библиотеки и доработка скилла.
- [CONTRIBUTING.md](CONTRIBUTING.md) — пересборка и распространение ZIP.
- [SKILL.md](skills/figma-local-design/SKILL.md) — инструкции для агента.

Сам скилл не запускает MCP: setup регистрирует сервер и устанавливает скилл отдельно. Без Codex CLI команда `node scripts/setup.mjs` создаст конфигурации с корректными путями для вашего компьютера.

## Создание с нуля: от style guide до экрана

Начните с открытого пустого файла Figma Design и подключённого плагина. Один вызов `create_style_guide` с аргументами `{"name":"My Product"}` создаёт:

- фрейм с редактируемыми образцами: на новой странице `My Product — Style guide`, если бюджет позволяет, либо на существующей странице;
- коллекцию переменных: 10 цветов, 8 отступов и 6 радиусов;
- 5 текстовых стилей на Inter: H1, H2, Body, Label и Caption;
- привязки цветовых образцов к COLOR-переменным, промежутков и радиусов к FLOAT-переменным, текстовых образцов к TextStyle.

Это стартовый набор. Агент может передать свои массивы `colors`, `typography`, `spacing`, `radii` под конкретный продукт; каждый переданный массив заменяет соответствующий набор по умолчанию. Создание использует один режим переменных и не требует дополнительных режимов темы.

Команда возвращает `pageId`, `frameId`, `collectionId`, `modeId` и ID каждого токена/стиля. Затем:

1. Прочитайте `get_document.capabilities`: число страниц, источник сведений о тарифе и доступный бюджет. `create_page` возвращает существующую страницу с таким именем либо создаёт новую в пределах бюджета.
2. `create_scene` создаёт до 100 узлов за вызов. Временные `ref` и `parentRef` позволяют описать вложенные фреймы, текст и компоненты без промежуточных запросов.
3. В `props` передавайте `fillVariableId`, `strokeVariableId`, `textStyleId` и `variableBindings`, используя ID из style guide.
4. `create_instance` размещает экземпляры созданного компонента на экранах.
5. `set_variable` меняет цвет или числовой токен; связанные свойства слоёв обновляются средствами Figma.
6. `set_selection` открывает нужную страницу и фокусирует узлы, `export_node` возвращает изображение для проверки.

Пример запроса к агенту:

> Используй только figma_local. В открытом пустом файле создай style guide для сервиса управления проектами: синий основной цвет, светлая тема, Inter, шкала отступов 4/8/12/16/24/32/48. Затем создай страницу Components с компонентом кнопки и страницу Screens с экраном входа. Привяжи цвета, отступы и текст к переменным и стилям. Используй экземпляр кнопки на экране и покажи PNG результата.

Подробный пример аргументов — [examples/from-scratch.md](examples/from-scratch.md).

Повторное создание guide с тем же именем отклоняется, чтобы не размножать стили. Существующий набор можно прочитать через `get_design_system` и изменить его COLOR/FLOAT значения через `set_variable`. Эта версия не редактирует определения текстовых стилей, не создаёт наборы вариантов компонентов и не публикует библиотеки.

Образцы связаны с токенами, но их текстовые подписи с HEX/px отражают момент создания. После изменения токенов актуальные значения читайте через `get_design_system`; подписи при необходимости меняйте через `update_node`. Текущая страница после создания guide не переключается автоматически.

Создание ресурсов основано на [Plugin API переменных](https://developers.figma.com/docs/plugins/working-with-variables/) и [локальных текстовых стилях](https://developers.figma.com/docs/plugins/api/TextStyle/). Ограничения возможностей редактора, прав и тарифного плана сохраняются. Ни один новый инструмент не вызывает REST API или официальный MCP.

## Инструменты

| Инструмент | Действие |
| --- | --- |
| `get_connection` | Статус и код подключения локального плагина |
| `get_document` | Имя файла, список страниц, текущая страница |
| `get_selection` | Выделенные узлы и ограниченное дерево потомков |
| `get_node` | Узел по ID: геометрия, текст, заливки, эффекты, auto layout |
| `find_nodes` | Поиск по имени или тексту на одной странице, с пагинацией |
| `create_node` | Создание FRAME, RECTANGLE, ELLIPSE, TEXT, COMPONENT |
| `update_node` | Изменение поддерживаемых свойств узла |
| `update_page` | Имя страницы и единый цвет холста |
| `reparent_nodes` | Перенос слоёв в контейнер с сохранением координат и опциональным индексом слоя |
| `reorder_nodes` | Порядок прямых потомков: индекс 0 — самый нижний слой |
| `set_image_fill` | Image fill из base64 PNG/JPEG/GIF/WebP; неподдерживаемое кодирование нормализуется локально |
| `set_image_fill_from_path` | Image fill из абсолютного локального пути с проверкой сигнатуры и размера файла |
| `delete_node` | Удаление узла и его потомков |
| `set_selection` | Выделение узлов одной страницы и фокусировка |
| `export_node` | PNG в виде MCP image или SVG в виде текста |
| `create_style_guide` | Страница с образцами, коллекция переменных и текстовые стили |
| `get_design_system` | Локальные коллекции, переменные и текстовые стили; фильтр `prefix` |
| `create_page` | Новая страница в открытом файле |
| `create_scene` | Пакетное создание до 100 узлов по `ref` / `parentRef` |
| `create_instance` | Экземпляр локального компонента |
| `set_variable` | Изменение COLOR/FLOAT значения в default mode или заданном `modeId` |

Для `get_node` и `get_selection`: `depth` от 0 до 6, `maxNodes` от 1 до 1000. По умолчанию 2 и 200. `childrenTruncated` показывает пропущенных потомков; `selectionTruncated` — пропущенные корни выделения. Текст длиннее 10 000 символов сокращается с `charactersTruncated` и полным `characterCount`. Значение `figma.mixed` возвращается как `{"mixed":true}`.

`find_nodes` возвращает `nextOffset` для следующего вызова с прежними фильтрами. `complete: false` означает, что нужно продолжить, даже если `nodes` пуст. `maxVisited` ограничивает новые просмотренные узлы после `offset`; сдвиг к offset тоже требует обхода. Изменения файла между страницами выдачи могут сдвигать результаты.

### Свойства для создания и редактирования

- Геометрия: `x`, `y`, `width`, `height`, `rotation`, `cornerRadius`.
- Вид: `name`, `visible`, `locked`, `opacity`, `fill`, `stroke`, `strokeWeight`.
- Текст: `characters`, `fontName: {family, style}`, `fontSize`, `textAlignHorizontal`.
- Дополнительная типографика: `textAutoResize`, `lineHeight: {unit: "PIXELS" | "PERCENT", value}`.
- Стили и токены: `textStyleId`, `fillVariableId`, `strokeVariableId`, `variableBindings`.
- Auto layout: `layoutMode`, `itemSpacing`, `paddingTop/Bottom/Left/Right`, `primaryAxisAlignItems`, `counterAxisAlignItems`, `primaryAxisSizingMode`, `counterAxisSizingMode`, `clipsContent`.

`fill` и `stroke` принимают `#RRGGBB` или `null` для очистки. Они заменяют весь список заливок/обводок на один сплошной цвет. Свойства текста применяются ко всему текстовому узлу. Перед текстовыми изменениями загружаются шрифты. Свойства, недоступные для данного типа узла, приводят к ошибке. Ограничения экземпляров компонентов проверяет Figma.

`textStyleId` нельзя совмещать в одном вызове с `fontName`, `fontSize` или `lineHeight`; `fillVariableId` — с `fill`; `strokeVariableId` — со `stroke`. Выберите стиль/токен или явное значение. `variableBindings` — объект из полей `width`, `height`, `itemSpacing`, `paddingTop/Bottom/Left/Right`, `topLeftRadius`, `topRightRadius`, `bottomLeftRadius`, `bottomRightRadius`; значения — ID FLOAT-переменных либо `null` для снятия привязки. Привязки применяются после обычных свойств.

Пример аргументов `create_node`:

```json
{
  "type": "FRAME",
  "props": {
    "name": "Card",
    "width": 320,
    "height": 180,
    "fill": "#FFFFFF",
    "cornerRadius": 16,
    "layoutMode": "VERTICAL",
    "itemSpacing": 12,
    "paddingTop": 24,
    "paddingLeft": 24
  }
}
```

Вернувшийся `id` можно передать как `parentId` при создании дочернего текста. `parentId` поддерживает PAGE, FRAME, COMPONENT и SECTION.

## Ограничения

- Один процесс MCP и один подключённый файл одновременно. Параллельные MCP-клиенты на порту 3055 конфликтуют. Для отдельного экземпляра нужно согласованно изменить `FIGMA_BRIDGE_PORT`, WebSocket URL в `plugin/ui.html` и `devAllowedDomains` в manifest.
- Плагин работает в Figma Design. Он не открывает произвольные файлы по ссылке, не работает в фоне с закрытым редактором и не обходит права доступа или политику организации по плагинам.
- Нет Figma AI, Make, Code Connect, комментариев, REST-поиска файлов, публикации библиотек, градиентных заливок или произвольного исполнения JavaScript. Создание нового файла Figma по-прежнему выполняется пользователем; инструменты создают страницы внутри открытого файла.
- Image fill принимает PNG, JPEG, GIF и WebP. Локальный путь должен быть абсолютным, указывать на обычный файл до 8 MiB и проходить проверку сигнатуры; байты не уходят в сторонние сервисы. При необходимости WebP и нестандартные JPEG/PNG декодируются UI плагина и сохраняются в файле как PNG.
- Для style guide создаются только локальные COLOR/FLOAT переменные и TextStyle, без алиасов и дополнительных режимов. Ограничения режима или типа переменной в `set_variable` проверяются до записи.
- Изменения не являются транзакциями. При ошибке `update_node` часть свойств могла измениться; ошибка сообщает об этом. После успешных изменений вызывается `commitUndo`; отмена выполняется в Figma. Неудачно созданный узел удаляется.
- При ошибке `create_style_guide` или `create_scene` выполняется очистка только ресурсов текущего вызова. Если очистка не удалась, ошибка перечисляет оставшиеся ресурсы. Таймаут транспорта не отменяет уже запущенную сборку: перед повтором проверьте файл.
- Таймаут команды — 30 секунд. После таймаута или разрыва связи результат отправленного изменения может быть неизвестен. Проверьте файл, прежде чем повторять команду: остановка соединения не отменяет уже запущенный Plugin API вызов.
- PNG ограничен до 4096 пикселей по большей стороне и 8 MiB; масштаб при необходимости уменьшается и возвращается в метаданных. SVG ограничен по длине 4 Mi символов.

## Локальное соединение и данные

Bridge слушает только `127.0.0.1`. Установщик сохраняет случайный локальный ключ длиной 32 байта в `generated/pairing-key.json` и в персональной копии UI. На macOS/Linux эти файлы доступны только владельцу (0600). Сервер проверяет ключ при каждом соединении. Без setup остаётся ручное сопряжение со случайным кодом на каждый запуск. Плагин не делает запросов к внешним доменам: в manifest разрешён только development WebSocket. Команды идут по списку известных операций, без `eval`, команд оболочки или передачи cookies Figma.

Содержимое макетов, прочитанное инструментами, возвращается MCP-клиенту и может попасть в контекст его AI-провайдера. Локальный bridge не означает локальную обработку моделью. Ключ подключения даёт доступ к сессии открытого файла. Каталог `generated/` содержит персональный ключ и не включается в ZIP; не передавайте этот каталог другим людям.

## Проверки

```bash
npm test
```

Проверены TypeScript-сборка и 42 автоматических теста: операции с узлами, style guide, переменные, импорт локальной картинки, порядок слоёв, ошибки, таймауты и защита подключения; запуск bundle без node_modules; генерация переносимых путей; установка/резервное копирование скилла; регистрация MCP с имитацией Codex CLI. Интеграционные тесты запускают настоящий MCP-клиент через stdio, настоящий WebSocket и собранный код плагина с имитацией Figma API; проходят путь от style guide до экземпляра компонента и изменения токена. Настройки реального Codex в тестах не изменяются.

Чтение, создание макета, компонентов, экземпляров и PNG-экспорт проверены в настоящем Figma Desktop. Автоподключение отдельно проверяется тестами UI и локального транспорта; эти тесты не заменяют проверку новой установки в редакторе.

Основные файлы: `src/server.mjs` — инструменты, `src/design-schema.mjs` — схемы guide/scene, `src/bridge.mjs` — локальное соединение, `plugin/code.ts` — узлы и свойства, `plugin/design-system.ts` — style guide, токены и сборка сцен, `plugin/ui.html` — подключение. После изменения TypeScript выполните `npm run build` и перезапустите плагин. Для появления новых инструментов перезапустите MCP-клиент. После setup плагин восстанавливает подключение автоматически; сборка обновляет его персональную копию в `generated/figma-plugin/`.

## Тариф файла и ограничения страниц

Публичный Plugin API не сообщает тариф команды. Поэтому `get_document.capabilities` честно возвращает неизвестный тариф, подтверждённый пользователем тариф или ограничение, ранее полученное в ошибке Figma. `figma.payments` относится к оплате плагина и здесь не используется.

В окне Figma Local MCP Auto можно выбрать тариф команды текущего файла; настройка хранится отдельно в документе. При неизвестном тарифе действует предел безопасности в три страницы. При Starter — три страницы. Для подтверждённого Professional/Education/Organization/Enterprise искусственный предел снимается, но ограничения самого редактора остаются.

При исчерпанном бюджете `create_page` останавливается **до вызова Figma API**, а `create_style_guide` размещает фрейм справа от существующего контента. Можно явно указать `pageId`. Никаких пробных страниц для определения тарифа не создаётся. Повторный `create_page` с тем же именем возвращает существующую страницу.

См. [правила скилла для лимитов](skills/figma-local-design/references/file-limits.md) и [лимиты страниц Figma](https://help.figma.com/hc/en-us/articles/360038511293-Create-and-manage-pages).

## Установка одним скиллом

Передайте `dist/figma-local-design-skill-0.6.2.zip`. Получателю достаточно установить папку `figma-local-design` как скилл и написать агенту:

> Используй $figma-local-design и установи всё необходимое для работы с Figma.

Скилл содержит установщик и проверяемый SHA256 пакет MCP. Агент развернёт его локально, зарегистрирует MCP и откроет manifest автоматического плагина. Нужны Node.js 22+ и Codex CLI для автоматической регистрации; npm и Python получателю не нужны. В Figma останется один раз импортировать manifest через меню Plugins → Development и запустить Figma Local MCP Auto.

По умолчанию отдельное скачивание не нужно: пакет вложен в скилл. Для размещённого вами релиза поддерживается HTTPS-загрузка runtime-payload.json.gz с обязательным SHA256. Публичный адрес релиза не настроен.