Skip to main content
Glama

mcp-perfectpixel

npm version CI License: MIT

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)가 수정을 적용합니다 — 서버는 정확하고 구조화된 증거를 제공하고 거기서 멈춥니다.

Related MCP server: eyeballs

적용 위치

세 가지 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 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와 비교한 뒤 영역과 산출물을 반환합니다.

Argument

Type

Description

url

string (required)

스크린샷할 라이브 URL — http(s) 또는 file URL.

designImagePath

string (required)

디자인 이미지(.png, .jpg, .jpeg) 또는 http(s) 이미지 URL (예: Figma export 링크).

viewport

{width, height}

CSS 픽셀 뷰포트. 기본값은 디자인 이미지의 크기.

outputDir

string

산출물을 쓸 위치. 기본값은 새 임시 디렉터리.

waitForSelector

string

스크린샷 전에 대기할 CSS 선택자.

waitMs

number

로드 후 추가 대기 시간(ms, ≤ 60초).

diffThreshold

number (0–1)

pixelmatch 민감도. 값이 작을수록 더 민감. 기본값 0.1.

repoRoot

string

소스 추적을 위한 코드베이스 루트. 기본값은 서버 cwd(hosted 모드에서는 필수).

mode

"local" | "hosted"

신뢰 경계: local(기본값)은 file:///로컬 경로를 허용하고, hosted는 이를 차단하며 사설 네트워크도 차단합니다(SSRF 가드).

computedStyle

"minimal" | "full" | "none"

영역별 계산된 스타일(computed style) 상세 수준. 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. 차이(diff) — 스크린샷이 디자인 이미지와 비교됩니다(pixelmatch). 서로 다른 픽셀은 연결된 영역으로 클러스터링되고, 가까우면 병합되며, 심각도로 점수가 매겨집니다.

  3. 추적 — 각 영역의 요소와 해당 CSS 규칙이 실제 소스 위치로 해석됩니다. CSS 소스 맵 우선, 그다음 gitignore 인식 텍스트 검색, 그다음 일반 DOM 증거 순입니다 — 추측된 파일은 절대 아닙니다.

  4. 패치 — 영역의 이미지에서 디자인 색상을 샘플링하고, 캐스케이드 우선순위(구체성 / 순서 / !important)를 찾아 가장 작은 변경을 제안하며, 프로젝트 자체 디자인 토큰을 선호합니다.

소스 추적 순서

  1. CSS 소스 맵 — 표준 빌드 도구 중립 메커니즘(Sass, Less, PostCSS, Tailwind, Webpack, Vite 모두 생성). 각 규칙의 바이트 오프셋은 소스 맵을 통해 원본 file:line:column → confidence: "high"로 매핑됩니다. 컴파일된 CSS 레이어에서 작동하므로 템플릿 언어와 관계없이 동작합니다.

  2. Gitignore 인식 텍스트 검색 — 선택자가 repoRoot 전체에서 검색됩니다 (중첩된 .gitignore 및 부정(negation) 패턴 존중, node_modules는 절대 검색하지 않음). 무시되지 않은 소스 → "medium"; gitignore된(빌드) 경로에서만 일치 → "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[]에 그 이유를 설명합니다.

반응형 디자인 (하드코딩된 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에서 이 디자인 구현":

  1. Figma MCP — 노드를 내보냅니다 (get_image-스타일 도구) → 이미지 URL.

  2. mcp-perfectpixel — capture_and_diff를 designImagePath = 해당 URL (자동으로 가져옴), url = 라이브 페이지, repoRoot = 코드베이스로 실행합니다.

  3. 반환된 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/.npmrc gitignore 처리; 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를 참조하세요.

라이선스

MIT

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers