mcp-perfectpixel
mcp-perfectpixel
AI 디자인-투-코드 워크플로우를 위한 누락된 검증 레이어
mcp-perfectpixel은(는) MCP 서버로, 실시간 URL을 스크린샷으로 찍어 정적 디자인 이미지(PNG/JPG)와 비교(diff)하고, 심각도 점수가 포함된 그룹화된 차이 영역 — 단순한 픽셀 노이즈가 아닌 — 을 반환합니다. 각 영역은 해당 DOM 요소, 실제 소스 위치, 최소 패치 제안까지 추적됩니다. 캡처는 결정적(deterministic) 입니다 (애니메이션 비활성화, 글꼴 완전 로드, 고정 로케일/시간대). 따라서 재실행 결과가 충분히 안정적이어서 픽셀 단위로 비교할 수 있습니다.
이것은 디자인 도구가 아닌 검증 도구입니다. Figma 파일을 읽지 않고, 코드를 생성하지 않으며, 어떤 프레임워크를 사용하는지 알지 못합니다. 다른 MCP 도구들이 열어둔 루프를 닫아줍니다 — “최종 결과가 실제로 디자인과 일치하는가?”
이것이 존재하는 이유
BigCommerce, Shopify, WordPress 및 랜딩 페이지에 픽셀 완벽한 테마를 납품하는 작업은 보통 이렇게 진행됩니다. 빌드 자체는 빠르지만, 마지막 “디자인과 일치하는가” 검증 단계는 느리고 수동적인 확대-비교 작업이며, 바로 AI 코딩 에이전트들이 실수하는 단계입니다 (잘못된 간격, 1px 차이의 색상, 누락된 토큰).
mcp-perfectpixel은(는) 이 검증 루프를 자동화합니다. 실시간 URL을 스크린샷으로 찍고, 디자인 이미지와 비교하고, 그룹화된 영역 + 소스 위치 + 최소 패치를 얻고, 수정한 뒤 similarity: 1.0이 될 때까지 다시 실행합니다. 호출하는 에이전트(Claude Code, Cursor, DeepSeek Agent, Codex)가 수정을 적용합니다 — 서버는 정확하고 구조화된 증거를 제공하고 거기서 멈춥니다.
적용 위치
세 가지 MCP 서버, 디자인-투-코드 루프의 세 가지 시점 — 경쟁이 아니라 서로 보완합니다:
Figma MCP | Chrome DevTools MCP | mcp-perfectpixel | |
제공하는 것 | 구조화된 디자인 데이터 — 노드 트리, 스타일, 변수, 토큰, 생성된 코드 | 실행 중인 페이지의 라이브 DOM / CSS / 콘솔 / 네트워크 디버깅 | 픽셀 수준 검증 — 최종 렌더링과 디자인 이미지의 차이(diff) |
사용 시점 | 코드 작성 전 — 무엇을 만들어야 하며, 정확한 스타일은 무엇인가? | 개발 중 — 왜 이렇게 동작하며, 런타임 문제를 어떻게 고치나? | 구현 후 — 최종 결과가 실제로 디자인과 픽셀 단위로 일치하는가? |
답변하는 것 | 디자인에 무엇이 있는가? | 페이지에서 무슨 일이 벌어지고 있는가? | 디자인을 완벽히 구현했는가? |
mcp-perfectpixel은(는) 의도적으로 Figma MCP의 경쟁자가 아닙니다. Figma를 전혀 다루지 않습니다. Figma MCP가 전달해 줄 수 있는 평면 이미지(또는 모든 PNG/JPG)를 가져와 렌더링된 결과를 검증합니다 — 다른 두 도구가 모두 다루지 않는 단계입니다.
기능
결정적 캡처 — 애니메이션/트랜지션 비활성화,
prefers-reduced-motion강제, 모든 웹 글꼴 대기(document.fonts.ready), 고정en-US로케일 + UTC 시간대, 라이트 스킴,deviceScaleFactor: 1이 적용된 헤드리스 Chromium. 두 번 실행하면 바이트 단위로 동일한 스크린샷을 생성합니다.그룹화된 차이 영역 — 서로 다른 픽셀을 클러스터링하고 가까운 클러스터를 병합하여 *“버튼이 잘못되었다”*는 결과를 제공합니다. 4,000개의 흩어진 픽셀이 아닙니다. 각 영역에는 경계 상자, 픽셀 수, 색상 델타, 심각도 점수(
high/medium/low)가 포함됩니다.영역 → 소스 추적 — 모든 영역은 해당 DOM 요소와 이를 스타일링하는 CSS 규칙으로 해석되며, 각각 최선의 원본
file:line:column(CSS 소스 맵 우선, 그다음 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와 비교한 뒤 영역과 산출물을 반환합니다.
Argument | Type | Description |
|
| 스크린샷할 라이브 URL — |
|
| 디자인 이미지( |
|
| CSS 픽셀 뷰포트. 기본값은 디자인 이미지의 크기. |
|
| 산출물을 쓸 위치. 기본값은 새 임시 디렉터리. |
|
| 스크린샷 전에 대기할 CSS 선택자. |
|
| 로드 후 추가 대기 시간(ms, ≤ 60초). |
|
| pixelmatch 민감도. 값이 작을수록 더 민감. 기본값 |
|
| 소스 추적을 위한 코드베이스 루트. 기본값은 서버 cwd( |
|
| 신뢰 경계: |
|
| 영역별 계산된 스타일(computed style) 상세 수준. |
도구는 출력 스키마를 선언합니다. 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이 결정적으로 스크린샷됩니다 (애니메이션 제거, 글꼴 대기, 고정 로케일/시간대).
차이(diff) — 스크린샷이 디자인 이미지와 비교됩니다(pixelmatch). 서로 다른 픽셀은 연결된 영역으로 클러스터링되고, 가까우면 병합되며, 심각도로 점수가 매겨집니다.
추적 — 각 영역의 요소와 해당 CSS 규칙이 실제 소스 위치로 해석됩니다. CSS 소스 맵 우선, 그다음 gitignore 인식 텍스트 검색, 그다음 일반 DOM 증거 순입니다 — 추측된 파일은 절대 아닙니다.
패치 — 영역의 이미지에서 디자인 색상을 샘플링하고, 캐스케이드 우선순위(구체성 / 순서 /
!important)를 찾아 가장 작은 변경을 제안하며, 프로젝트 자체 디자인 토큰을 선호합니다.
소스 추적 순서
CSS 소스 맵 — 표준 빌드 도구 중립 메커니즘(Sass, Less, PostCSS, Tailwind, Webpack, Vite 모두 생성). 각 규칙의 바이트 오프셋은 소스 맵을 통해 원본
file:line:column→confidence: "high"로 매핑됩니다. 컴파일된 CSS 레이어에서 작동하므로 템플릿 언어와 관계없이 동작합니다.Gitignore 인식 텍스트 검색 — 선택자가
repoRoot전체에서 검색됩니다 (중첩된.gitignore및 부정(negation) 패턴 존중,node_modules는 절대 검색하지 않음). 무시되지 않은 소스 →"medium"; gitignore된(빌드) 경로에서만 일치 →"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[]에 그 이유를 설명합니다.
반응형 디자인 (하드코딩된 width/height 피하기)
디자인 이미지는 단일 뷰포트 래스터입니다. 중단점, 자동 레이아웃 또는 유동 동작을 인코딩할 수 없습니다. 여기서 픽셀 크기를 복사하여 width: 120px; height: 36px로 옮기는 것은 다른 뷰포트에서 실제 테마를 망치는 가장 빠른 방법입니다. mcp-perfectpixel은(는) 이런 일이 우연히 발생하지 않도록 설계되었습니다:
width/height 패치를 제안하지 않습니다 — 패치는 색상 전용(
background-color,color, 테두리, outline)입니다. 레이아웃은 도구에 의해 절대 “수정”되지 않습니다.capture.responsive는 페이지 자체의 중단점을 보고합니다 — 모든 스타일시트에서 고유한@media/@container조건의 수입니다. 0이 아니면 페이지가 반응형이며, 출력의 픽셀 치수는 뷰포트별 값입니다.notes[]는 중요할 때 경고합니다: 페이지가 미디어/컨테이너 쿼리를 사용하는데 요소가 고정 픽셀 치수로 렌더링되거나, 차이가 지오메트리만 있고(색상 변경 없음) diff가 발생한 경우, 영역 노트가 이를 알리고 에이전트에게 유동적 크기 조정(min/max-width, flex/grid, 간격 토큰)을 선호하고 다른 뷰포트에서 캡처를 다시 실행하여 검증하라고 지시합니다.값은 여전히 정확합니다 — 계산된 스타일의
width/height는 캡처 뷰포트에서 실제 렌더링된 값입니다. 이는 지침이 아니라 증거입니다.
반응형 의도를 위해 이 도구를 Figma MCP의 구조화된 데이터와 페어링하세요. (auto-layout, constraints, variables) — 래스터가 픽셀을 검증하고, 구조화된 데이터는 레이아웃 전략을 안내합니다.
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= 코드베이스로 실행합니다.반환된 regions + patches를 적용하고,
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디자인 철학
구조화된 증거, 프레임워크 지식이 아님. 서버의 역할은 regions + element + rules + confidence + patches에서 끝납니다. 서버는 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 regions, 후보 선택자 제한, 가져오기 타임아웃, 파일 검색 상한.
신뢰 경계 —
mode: "local"/"hosted"및 SSRF +file://보호와 명시적repoRoot요구 사항.세션 인식 스타일시트 — 브라우저의 요청 컨텍스트를 통해 가져오므로 쿠키가 적용되고, 추적된 CSS가 페이지가 렌더링한 내용과 일치합니다.
정직한 추적 —
trace.status/warnings가 실패와 잘림을 보고합니다; 테스트/문서/생성된 파일의 텍스트 검색 일치는 우선순위가 낮아집니다.토큰 친화적 출력 — 반올림된 부동 소수점, 트리밍된 계산 스타일, 병렬 읽기가 포함된 공유 repo-walk 캐시(페이로드 약 37% 감소, 약 58% 빨라짐).
비밀 위생 —
.env/.npmrcgitignore 처리; CI는 Gitleaks, lint, build, tests 및 coverage를 실행합니다; 배포 워크플로는 릴리스 전에 모든 것을 다시 실행합니다.
로드맵
목표 1 — 결정적 캡처 + 픽셀 비교
목표 2 — 변경 사항을 실제 소스로 추적 (CSS 소스 맵 → gitignore 인식 텍스트 검색, 신뢰도 점수 포함)
목표 3 — 프로젝트 자체 토큰을 선호하는 최소 패치 출력
목표 4 — 구조화된 컨텍스트 전달 (프레임워크 지식 없음)
목표 5 — OSS 규칙 + 릴리스 파이프라인 (
v0.1.0부터 semver, 두 패키지 모두 태그 게시)
첫 번째 실제 릴리스에는 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