Skip to main content
Glama
Guddion Figma

Guddion Figma

by TheGudwinn
README.md
<p align="center">
  <img src="docs/mascot.gif" alt="Guddion Figma mascot" width="640" />
</p>

<h1 align="center">Guddion Figma</h1>

<p align="center">
  Локальный MCP-сервер для Figma — без лимитов официального коннектора.
</p>

---

## Почему это вообще появилось

Я использую Claude Code как основной инструмент в работе с дизайном и фронтендом, и рано или поздно всегда упираюсь в официальный Figma Dev Mode MCP — он режет запросы лимитами, которые никак не настроить. Для разовой правки это терпимо, но когда нужно вытащить целую секцию с токенами, компонентами и layout за один присест, упираешься в стену ровно тогда, когда это важнее всего.

Решение оказалось простым: написать свой сервер, который говорит с Figma напрямую — по REST API через персональный токен и, отдельно, через плагин внутри самого Figma Desktop. Второй путь вообще не упирается ни в какой лимит, потому что читает документ прямо из памяти приложения, а не через HTTP.

Получилось два транспорта в одном MCP-сервере. Для разового запроса "дай мне вот этот фрейм" хватает REST. Для записи в файл, доступа к variables на Free-плане или частых тяжёлых запросов — подключаешь плагин.

## Как это устроено

**REST + Personal Access Token.** Даёшь ссылку на фрейм — сервер достаёт из неё `fileKey` и `nodeId`, бьёт точечно по `/files/:key/nodes?ids=`, а не по всему файлу целиком. Это важно: Figma считает лимит по "стоимости" запроса в минуту, и дёрганье всего файла съедает его моментально, а точечные запросы по конкретной ноде почти не ощущаются даже на Free-плане.

**Plugin Bridge.** У плагина Figma нет сетевого доступа в главном потоке — это ограничение самой платформы, не моё решение. Сеть есть только в UI-iframe плагина. Поэтому мост состоит из трёх частей: локальный websocket-сервер ↔ невидимый UI плагина ↔ главный поток плагина, который и дёргает Plugin API. Через этот путь доступны вещи, которых нет в REST вообще — запись нод на холст и чтение Variables без Enterprise-плана.

MCP-клиент сам решает, какой инструмент вызвать: для чтения по ссылке обычно достаточно REST, а для записи или variables используются инструменты фазы 2.

## Статус

Обе фазы написаны и проверены на реальном аккаунте и реальном открытом файле, не только на заглушках: REST-инструменты отдают настоящие ноды и стили, плагин создаёт настоящие объекты на холсте и возвращает реальные design tokens.

## Установка

### 1. Сервер

```bash
npm install
cp .env.example .env
```

В `.env` нужен `FIGMA_TOKEN` — персональный токен из Figma: **Settings → Security → Personal access tokens**.

```bash
npm run build
npm start
```

Websocket для плагина по умолчанию поднимается на `ws://localhost:9684`. Если нужен другой порт — переменная `FIGMA_BRIDGE_PORT` в `.env` (и тогда же поправь порт в `plugin/manifest.json`, об этом ниже).

### 2. Подключение к MCP-клиенту

Сервер обычный stdio MCP, так что заводится в любом клиенте, который их поддерживает — не только в Claude.

**Claude Code**

```bash
claude mcp add guddion-figma -- node "<путь-к-проекту>/dist/server.js"
```

**Cursor** — добавить в `.cursor/mcp.json` (или в глобальный `~/.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "guddion-figma": {
      "command": "node",
      "args": ["<путь-к-проекту>/dist/server.js"]
    }
  }
}
```

**Codex CLI** — добавить в `~/.codex/config.toml`:

```toml
[mcp_servers.guddion-figma]
command = "node"
args = ["<путь-к-проекту>/dist/server.js"]
```

Во всех случаях `<путь-к-проекту>` — абсолютный путь до этого репозитория, а сервер должен быть собран (`npm run build`) до первого подключения. После добавления конфигурации клиент нужно перезапустить, чтобы он подхватил новый MCP-сервер.

Инструменты REST заработают сразу же. Инструменты плагина ответят ошибкой "plugin не подключён", пока не выполнен следующий шаг.

### 3. Плагин в Figma Desktop

Нужен только для записи и variables — для чтения по ссылке плагин не обязателен.

1. Figma Desktop → **Plugins → Development → Import plugin from manifest…**
2. Выбрать `plugin/manifest.json` из этого проекта.
3. Открыть нужный файл и запустить плагин **Guddion Figma Bridge** (Plugins → Development → Guddion Figma Bridge). У него нет видимого окна — он просто подключается к серверу на `localhost:9684` и сидит там.
4. `get_plugin_status` должен вернуть `connected: true` и имя файла.

Порт в `plugin/manifest.json` зашит как конкретное число, потому что Figma не принимает wildcard по порту в манифесте (`localhost:*` считается невалидным URL). Поменял порт в `.env` — поправь то же число в манифесте и переимпортируй плагин.

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

### REST — работает всегда, Figma Desktop не нужен

| Инструмент | Что делает |
| --- | --- |
| `resolve_link` | ссылка Figma → `{ fileKey, nodeId }` |
| `get_node_tree` | дерево ноды: layout, fills, strokes, текст, стили, компоненты |
| `get_styles` | метаданные стилей файла |
| `get_components` | компоненты и component sets |
| `export_image` | рендер ноды в PNG/SVG/JPG, временная ссылка на скачивание |

### Plugin Bridge — нужен открытый файл и запущенный плагин

| Инструмент | Что делает |
| --- | --- |
| `get_plugin_status` | подключён ли плагин и к какому файлу |
| `get_variables` | локальные variables и их коллекции — доступно на Free, в отличие от REST Variables API |
| `get_selection` | что сейчас выделено на холсте |
| `write_node` | создаёт FRAME / RECTANGLE / TEXT в открытом файле |

## Структура проекта

```text
src/            — MCP-сервер, REST-клиент, резолвер ссылок, websocket-мост
plugin/         — код Figma-плагина (main thread + UI-iframe)
```

## Лицензия

MIT — делай с этим что хочешь.