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) применяет исправления — сервер предоставляет точные структурированные доказательства и на этом останавливается.
Где это вписывается
Три 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 installed
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 Connectors
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.
Conformance checker for MCP servers. Free, no key, verdicts recomputable and re-measured daily.
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/hiimbomb1999/mcp-perfectpixel'
If you have feedback or need assistance with the MCP directory API, please join our Discord server