Skip to main content
Glama

mcp-perfectpixel

npm version CI License: MIT

Недостающий слой верификации для рабочих процессов AI от дизайна к коду.

mcp-perfectpixel — это MCP сервер, который делает снимок экрана живого URL и сравнивает его со статическим изображением дизайна (PNG/JPG), возвращая сгруппированные области различий с оценками серьёзности — а не сырой пиксельный шум, — каждая из которых привязана к своему DOM-элементу, реальному исходному расположению и минимальному предложению по исправлению. Съёмка детерминирована (анимации отключены, шрифты полностью загружены, фиксированные локаль/часовой пояс), поэтому повторные запуски достаточно стабильны, чтобы анализировать попиксельно.

Это инструмент верификации, а не инструмент дизайна: он не читает файлы Figma, не генерирует код и не знает, какой фреймворк вы используете. Он замыкает цикл, который другие MCP-инструменты оставляют открытым — «соответствует ли конечный результат дизайну на самом деле?»

Почему это существует

Доставка пиксель-идеальных тем для BigCommerce, Shopify, WordPress и лендингов обычно выглядит так: сама сборка быстрая, но финальная проверка «соответствует ли это дизайну» — медленная, ручная рутина с зумом и сравнением — и именно на этом шаге AI-агенты кодирования ошибаются (неправильные отступы, цвета со смещением на один, отсутствующие токены).

mcp-perfectpixel автоматизирует этот цикл верификации: сделать снимок живого URL, сравнить с изображением дизайна, получить сгруппированные области + исходные расположения + минимальные исправления, исправить и повторять до similarity: 1.0. Вызывающий агент (Claude Code, Cursor, DeepSeek Agent, Codex) применяет исправления — сервер предоставляет точные структурированные доказательства и на этом останавливается.

Где это вписывается

Три MCP-сервера, три момента цикла «от дизайна к коду» — они дополняют, а не конкурируют:

Figma MCP

Chrome DevTools MCP

mcp-perfectpixel

Даёт вам

Структурированные данные дизайна — дерево узлов, стили, переменные, токены, сгенерированный код

Живая отладка DOM / CSS / консоли / сети работающей страницы

Попиксельная верификация — сравнение финального рендера с изображением дизайна

Используйте

Перед написанием кода — что я должен построить, каковы точные стили?

Во время разработки — почему это ведёт себя так, исправьте проблемы рантайма?

После реализации — соответствует ли конечный результат дизайну попиксельно?

Отвечает

Что в дизайне?

Что происходит на странице?

Соответствуем ли мы дизайну?

mcp-perfectpixel намеренно не конкурент Figma MCP: он никогда не касается Figma. Он принимает плоское изображение, которое Figma MCP может передать ему (или любой PNG/JPG), и проверяет отрендеренный результат — шаг, который не покрывает ни один из двух других.

Возможности

  • Детерминированная съёмка — headless Chromium с отключёнными анимациями/переходами, принудительным prefers-reduced-motion, ожиданием всех веб-шрифтов (document.fonts.ready), фиксированной локалью en-US + часовым поясом UTC, светлой темой, deviceScaleFactor: 1. Два запуска дают байт-идентичные скриншоты.

  • Сгруппированные области различий — различающиеся пиксели кластеризуются, а близкие кластеры объединяются, так что вы получаете «кнопка неправильная», а не 4000 разбросанных пикселей. Каждая область содержит ограничивающую рамку, количество пикселей, цветовые дельты и оценку серьёзности (high / medium / low).

  • Трассировка области → исходный код — каждая область сопоставляется с её DOM-элементом и CSS-правилами, которые его стилизуют, каждое с наилучшим возможным оригинальным file:line:column (сначала CSS source maps, затем текстовый поиск с учётом .gitignore) и оценкой уверенности.

  • Минимальные исправления — наименьшее изменение одного свойства (file, line, property, current → suggested), с предпочтением дизайн-токенов, уже определённых в проекте (var(--color-success), а не захардкоженный hex). Никогда не переписывание компонента.

  • Артефакты на диске — скриншот + изображение различий с подсветкой (PNG) записываются в выходную директорию и возвращаются, чтобы агент мог их изучить.

  • Дружелюбный к токенам вывод — типизированный structuredContent (объявленная схема вывода), урезанный вычисленный стиль, округлённые числа с плавающей точкой; ~37% меньший объём данных.

  • Работает с любым стеком — трассировка работает на уровне скомпилированного CSS + текстового поиска, поэтому Liquid, Stencil, Twig, JSX, Blade, Razor или обычный HTML ведут себя одинаково. Никаких парсеров для каждого фреймворка.

Установка и запуск

Требуются Node.js ≥ 20 и бинарник Chromium (установить один раз):

npx playwright install chromium

Claude Desktop — claude_desktop_config.json

{
  "mcpServers": {
    "perfectpixel": {
      "command": "npx",
      "args": ["-y", "mcp-perfectpixel"]
    }
  }
}

Cursor — .cursor/mcp.json

{
  "mcpServers": {
    "perfectpixel": {
      "command": "npx",
      "args": ["-y", "mcp-perfectpixel"]
    }
  }
}

Codex CLI — ~/.codex/config.toml

[mcp_servers.mcp-perfectpixel]
command = "/path/to/node"
args = ["/path/to/mcp-perfectpixel/packages/server/dist/index.js"]

(При запуске из исходников: command — это абсолютный путь к node, args указывает на собранную точку входа сервера. Перезапустите Codex после редактирования. repoRoot по умолчанию равен рабочей директории сессии — вашему проекту, — поэтому трассировка и поиск токенов выполняются по коду, который вы редактируете.)

Попробуйте локально (клиент не нужен)

pnpm install
pnpm --filter @mcp-perfectpixel/core exec playwright install chromium
pnpm build

# one command: renders the fixture design, diffs the fixture page, prints everything
node examples/demo.mjs packages/server/test/fixtures/design.html \
  "file://$PWD/packages/server/test/fixtures/page.html"

examples/demo.mjs вызывает движок напрямую с вашим собственным изображением/URL дизайна: node examples/demo.mjs <design.png|design.html> <url> [repoRoot].

Справочник инструментов

capture_and_diff

Делает снимок url, сравнивает его с designImagePath, возвращает области + артефакты.

Аргумент

Тип

Описание

url

string (обязательный)

Живой URL для снимка — http(s) или file URL.

designImagePath

string (обязательный)

Изображение дизайна (.png, .jpg, .jpeg) или http(s) URL изображения (например, ссылка экспорта Figma).

viewport

{width, height}

CSS-пиксельный viewport. По умолчанию — размеры изображения дизайна.

outputDir

string

Куда записывать артефакты. По умолчанию — новая временная директория.

waitForSelector

string

CSS-селектор, которого нужно дождаться перед снимком.

waitMs

number

Дополнительное время ожидания после загрузки, в мс (≤ 60 с).

diffThreshold

number (0–1)

Чувствительность pixelmatch. Меньше = чувствительнее. По умолчанию 0.1.

repoRoot

string

Корень кодовой базы для трассировки исходников. По умолчанию — рабочая директория сервера (обязателен в режиме hosted).

mode

"local" | "hosted"

Граница доверия: local (по умолчанию) разрешает file:///локальные пути; hosted блокирует их + частные сети (защита от SSRF).

computedStyle

"minimal" | "full" | "none"

Подробность вычисленного стиля для каждой области. minimal (по умолчанию) сохраняет кандидатов по цвету + значения, отличающиеся от родительского.

Инструмент объявляет схему вывода: MCP-клиенты получают типизированный structuredContent (проверенный) плюс JSON-текст. Каждый вызов сообщает trace.status (skipped/ok/partial/failed) и trace.warnings — проблемы никогда не проглатываются молча.

Пример результата (сокращённо):

{
  "status": "diff",
  "similarity": 0.9951,
  "diffRatio": 0.0049,
  "regions": [
    {
      "id": 1,
      "x": 60,
      "y": 130,
      "width": 120,
      "height": 36,
      "pixelCount": 4120,
      "coverage": 0.99,
      "meanDelta": 0.52,
      "score": 0.58,
      "severity": "high",
      "source": {
        "element": {
          "tag": "button",
          "id": null,
          "classes": ["btn-primary"],
          "selector": "button.btn-primary",
          "computedStyle": { "background-color": "rgb(220, 38, 38)" }
        },
        "rules": [
          {
            "selector": ".btn-primary",
            "media": null,
            "supports": null,
            "container": null,
            "applies": "yes",
            "properties": ["background-color"],
            "declared": { "background-color": "#dc2626" },
            "source": {
              "file": "src/styles/_buttons.scss",
              "line": 42,
              "column": 5,
              "via": "source-map",
              "gitignored": false
            },
            "confidence": "high"
          }
        ],
        "confidence": "high",
        "patches": [
          {
            "file": "src/styles/_buttons.scss",
            "line": 42,
            "column": 5,
            "property": "background-color",
            "current": "#dc2626",
            "suggested": "var(--color-success)",
            "value": "#16a34a",
            "token": {
              "name": "--color-success",
              "reference": "var(--color-success)",
              "kind": "css-variable"
            },
            "confidence": "high"
          }
        ],
        "notes": []
      }
    }
  ],
  "capture": {
    "url": "https://example.com",
    "viewport": { "width": 800, "height": 600 },
    "viewportSource": "design",
    "locale": "en-US",
    "timezoneId": "UTC",
    "reducedMotion": true,
    "animationsDisabled": true,
    "fontsWaited": true,
    "durationMs": 1842
  },
  "artifacts": {
    "screenshotPath": "/var/folders/.../example.com-screenshot.png",
    "diffImagePath": "/var/folders/.../example.com-diff.png",
    "designImagePath": "/repo/designs/home.png",
    "designImageSource": "/repo/designs/home.png"
  },
  "trace": { "status": "ok", "warnings": [] },
  "repoRoot": "/repo"
}

Серьёзность: score = 0.6·meanDelta + 0.25·coverage + 0.15·min(1, areaRatio·10), high ≥ 0.5, medium ≥ 0.2, low < 0.2.

Как это работает

  1. Захват — URL снимается детерминированно (анимации отключены, шрифты ожидаются, фиксированные локаль/часовой пояс).

  2. Сравнение — скриншот сравнивается с изображением дизайна (pixelmatch); различающиеся пиксели кластеризуются в связанные области, объединяются при близости и оцениваются по серьёзности.

  3. Трассировка — элемент каждой области и его CSS-правила сопоставляются с реальными исходными расположениями: сначала CSS source maps, затем текстовый поиск с учётом .gitignore, затем просто DOM-доказательства — никогда не угаданный файл.

  4. Исправление — цвет дизайна сэмплируется из изображения в области, определяется победитель каскада (специфичность / порядок / !important), и предлагается наименьшее изменение с предпочтением собственных дизайн-токенов проекта.

Порядок трассировки исходников

  1. CSS source maps — стандартный механизм, не зависящий от инструментов сборки (Sass, Less, PostCSS, Tailwind, Webpack, Vite — все их генерируют). Смещение байта каждого правила отображается через source map в оригинальный file:line:columnconfidence: "high". Работает независимо от языка шаблонов, так как действует на уровне скомпилированного CSS.

  2. Текстовый поиск с учётом .gitignore — селектор ищется по всему repoRoot (учитываются вложенные .gitignore и отрицания, node_modules никогда не ищется). Не игнорируемый исходник → "medium"; совпадения только в игнорируемых (сборочных) путях → "low"; совпадения в тестовых/документационных файлах имеют низкий приоритет.

  3. Только DOM-доказательства — если ничего не находится, элемент + вычисленный стиль возвращаются как есть с confidence: "low".

Минимальные исправления

Для цветовых различий сервер извлекает предполагаемое значение дизайна, сэмплируя изображение дизайна в области, и выдаёт одно наименьшее возможное изменение, предпочитая токены, которые проект уже определяет — CSS-переменные, конфиги Tailwind, style-dictionary JSON:

{
  "file": "src/styles/_buttons.scss",
  "line": 42,
  "column": 5,
  "property": "background-color",
  "current": "#dc2626",
  "suggested": "var(--color-success)",
  "value": "#16a34a",
  "confidence": "high"
}

Когда у исправления нет якоря (например, проблемный цвет наследуется от предка или задан инлайн-стилем), результат объясняет это в notes[], а не угадывает.

Дизайны из Figma

mcp-perfectpixel работает только с плоскими изображениямиофициальный Figma Dev Mode MCP является идеальным мостом: он экспортирует любой фрейм/узел в изображение, а этот сервер проверяет финальный рендер по нему. Агент управляет обоими; mcp-perfectpixel никогда не общается с Figma сам.

Рабочий процесс — «реализуйте этот дизайн из Figma»:

  1. Figma MCP — экспортируйте узел (инструмент вроде get_image) → URL изображения.

  2. mcp-perfectpixelcapture_and_diff с designImagePath = этим URL (загружается автоматически), url = живая страница, repoRoot = кодовая база.

  3. Примените возвращённые области + исправления, повторяйте до similarity: 1.0.

Автономный экспорт (Figma MCP не нужен):

export FIGMA_TOKEN=figd_...   # create at https://www.figma.com/developers/api#access-tokens
node examples/figma-export.mjs \
  "https://www.figma.com/design/FILE_KEY/slug?node-id=1689-7871" -o /tmp/design.png

node examples/demo.mjs /tmp/design.png https://localhost:3000

Философия дизайна

  • Структурированные доказательства, а не знание фреймворков. Работа сервера заканчивается на областях + элементе + правилах + уверенности + исправлениях. Он никогда не угадывает, что сгенерировало HTML/CSS — это ответственность вызывающего агента.

  • Детерминированность — это фича. Одна и та же страница, один и тот же дизайн, одни и те же байты — именно это делает попиксельное сравнение осмысленным.

  • Минимальное заменяемое ядро. Движок живёт в @mcp-perfectpixel/core (не зависит от фреймворков и MCP), поэтому будущие инструменты смогут его переиспользовать.

Граница (что сервер никогда не будет делать)

  • разбирать шаблоны или файлы Figma — трассировка работает на уровне скомпилированного CSS;

  • поддерживать парсеры/адаптеры для каждого фреймворка (Liquid, Stencil, ...) — максимум опциональный плагин сообщества, но никогда не основная зависимость;

  • предлагать полные переписывания компонентов — вывод всегда является изменением одного свойства;

  • применять патчи или редактировать файлы самостоятельно — он сообщает file:line:column + current → suggested, решение принимает агент.

Ужесточение

  • Патчи с учётом каскада — специфичность, порядок объявлений, !important; дублирующиеся селекторы сопоставляются со своими позициями в исходниках.

  • Условный CSS@media через matchMedia(), @supports через CSS.supports(), @container сообщается как applies: "unknown"; правила псевдоэлементов никогда не сопоставляются с элементом.

  • Лимиты ресурсов — вьюпорт ≤ 16.7M px, дизайн-файл ≤ 50MB (stat перед чтением), ≤ 50 регионов, ограниченное число селекторов-кандидатов, таймауты запросов, ограниченное сканирование файлов.

  • Граница доверияmode: "local" / "hosted" с защитой от SSRF и file:// и явным требованием repoRoot.

  • Таблицы стилей с учётом сессии — загружаются через контекст запроса браузера, поэтому cookies применяются и трассированный CSS соответствует тому, что отрендерила страница.

  • Честная трассировкаtrace.status/warnings сообщают об ошибках и усечениях; совпадения текстового поиска в тестовых/документационных/сгенерированных файлах имеют пониженный приоритет.

  • Дружественный к токенам вывод — округлённые числа с плавающей запятой, обрезанный вычисляемый стиль, общий кэш обхода репозитория с параллельными чтениями (~37% меньшие полезные нагрузки, ~58% быстрее).

  • Гигиена секретов.env/.npmrc игнорируются git; CI запускает Gitleaks, линт, сборку, тесты и покрытие; пайплайн публикации перезапускает всё перед релизом.

Дорожная карта

  • Цель 1 — Детерминированный захват + попиксельное сравнение

  • Цель 2 — Трассировка различий до реального исходного кода (карты исходников CSS → текстовый поиск с учётом gitignore, с оценкой уверенности)

  • Цель 3 — Минимальный вывод патча с предпочтением собственных токенов проекта

  • Цель 4 — Передача структурированного контекста (без знания фреймворков)

  • Цель 5 — OSS-конвенции + пайплайн релизов (semver начиная с v0.1.0, публикация по тегу для обоих пакетов)

Для первого настоящего релиза нужны тег v0.1.0 и секрет NPM_TOKEN — см. CONTRIBUTING.md.

Разработка

pnpm install
pnpm --filter @mcp-perfectpixel/core exec playwright install chromium
pnpm lint        # eslint + prettier
pnpm build       # type-checked compile of both packages
pnpm test        # 104 unit + e2e tests through the MCP stdio protocol
pnpm coverage    # vitest coverage (v8)

См. CONTRIBUTING.md.

Лицензия

MIT

-
license - not tested
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

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/hiimbomb1999/mcp-perfectpixel'

If you have feedback or need assistance with the MCP directory API, please join our Discord server