mcp-perfectpixel
mcp-perfectpixel
Недостающий слой верификации для рабочих процессов 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) применяет исправления — сервер предоставляет точные структурированные доказательства и на этом останавливается.
Related MCP server: eyeballs
Где это вписывается
Три 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 chromiumClaude 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 для снимка — |
|
| Изображение дизайна ( |
|
| CSS-пиксельный viewport. По умолчанию — размеры изображения дизайна. |
|
| Куда записывать артефакты. По умолчанию — новая временная директория. |
|
| CSS-селектор, которого нужно дождаться перед снимком. |
|
| Дополнительное время ожидания после загрузки, в мс (≤ 60 с). |
|
| Чувствительность pixelmatch. Меньше = чувствительнее. По умолчанию |
|
| Корень кодовой базы для трассировки исходников. По умолчанию — рабочая директория сервера (обязателен в режиме |
|
| Граница доверия: |
|
| Подробность вычисленного стиля для каждой области. |
Инструмент объявляет схему вывода: 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.
Как это работает
Захват — URL снимается детерминированно (анимации отключены, шрифты ожидаются, фиксированные локаль/часовой пояс).
Сравнение — скриншот сравнивается с изображением дизайна (pixelmatch); различающиеся пиксели кластеризуются в связанные области, объединяются при близости и оцениваются по серьёзности.
Трассировка — элемент каждой области и его CSS-правила сопоставляются с реальными исходными расположениями: сначала CSS source maps, затем текстовый поиск с учётом .gitignore, затем просто DOM-доказательства — никогда не угаданный файл.
Исправление — цвет дизайна сэмплируется из изображения в области, определяется победитель каскада (специфичность / порядок /
!important), и предлагается наименьшее изменение с предпочтением собственных дизайн-токенов проекта.
Порядок трассировки исходников
CSS source maps — стандартный механизм, не зависящий от инструментов сборки (Sass, Less, PostCSS, Tailwind, Webpack, Vite — все их генерируют). Смещение байта каждого правила отображается через source map в оригинальный
file:line:column→confidence: "high". Работает независимо от языка шаблонов, так как действует на уровне скомпилированного CSS.Текстовый поиск с учётом .gitignore — селектор ищется по всему
repoRoot(учитываются вложенные.gitignoreи отрицания,node_modulesникогда не ищется). Не игнорируемый исходник →"medium"; совпадения только в игнорируемых (сборочных) путях →"low"; совпадения в тестовых/документационных файлах имеют низкий приоритет.Только 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»:
Figma MCP — экспортируйте узел (инструмент вроде
get_image) → URL изображения.mcp-perfectpixel —
capture_and_diffсdesignImagePath= этим URL (загружается автоматически),url= живая страница,repoRoot= кодовая база.Примените возвращённые области + исправления, повторяйте до
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.
Лицензия
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for visual regression testing: triage a PR's UI diffs from your coding agent.
MCP server for Mint — AI-powered QA that runs your app in a real browser on every PR.
- mcpOAuthcom.screenshotink
Screenshot, diff, audit and sitemap-capture any web page — 5 MCP tools for AI agents.
Capture screenshots, detect visual regressions between page versions, and analyze with AI.
Related MCP Servers
- AlicenseAqualityDmaintenanceA powerful MCP server for UI designers and developers to extract, analyze, and clone website front-end code (HTML, CSS) with pixel-perfect accuracy using browser automation.118 npm3MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for visual monitoring: take screenshots of URLs and detect visual changes against stored baselines.7 npm1MIT
- AlicenseNot gradedqualityCmaintenanceMCP server for rendering responsive screenshots of URLs at multiple viewports. Enables agents to capture screenshots and detect visual issues like overflow, clipped elements, and missing alt text.MIT
- AlicenseNot gradedqualityAmaintenanceAn MCP server that measures how faithfully one UI reproduces another, returning a score and actionable findings for improvement.1MIT