mcp-perfectpixel
mcp-perfectpixel
AI 设计到代码工作流缺失的验证层。
mcp-perfectpixel 是一个 MCP 服务器,它对线上 URL 截图,并将其与静态设计图(PNG/JPG)进行比对,返回带严重程度分数的分组差异区域——而不是原始像素噪声——每个区域都能追溯到其 DOM 元素、真实源码位置以及最小补丁建议。捕获是确定性的(禁用动画、完整加载字体、固定区域/时区),因此重复运行足够稳定,可以逐像素进行分析。
它是一个验证工具,而不是设计工具:它不读取 Figma 文件,不生成代码,也不知道你使用什么框架。它闭合了其他 MCP 工具留下的循环——“最终结果是否真的与设计匹配?”
为什么会有它
为 BigCommerce、Shopify、WordPress 和落地页 交付像素级完美的主题通常是这样的:构建本身很快,但最后的**“是否与设计匹配”**检查却是一个缓慢、手动、放大对比的苦差事——而这正是 AI 编程智能体容易出错的地方(间距错误、颜色偏差 1 个色阶、缺少设计令牌)。
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),并验证渲染结果——这是另外两者都没有覆盖的步骤。
功能特性
确定性捕获 — 无头 Chromium,禁用动画/过渡,强制
prefers-reduced-motion,等待所有 Web 字体(document.fonts.ready),固定en-US区域 + UTC 时区,浅色模式,deviceScaleFactor: 1。两次运行生成字节完全相同的截图。分组差异区域 — 差异像素被聚类,邻近的聚类被合并,因此你得到的是*“按钮有问题”*,而不是 4,000 个分散的像素。每个区域都带有边界框、像素数量、颜色差异和严重程度评分(
high/medium/low)。区域 → 源码追踪 — 每个区域都解析到其 DOM 元素和为其设置样式的 CSS 规则,每条规则都带有尽力而为的原始
file:line:column(首先使用 CSS source map,然后进行感知 gitignore 的文本搜索)和置信度评分。最小补丁 — 最小的单属性更改(
file, line, property, current → suggested),优先使用项目已定义的设计令牌(var(--color-success),而不是硬编码的十六进制值)。绝不重写组件。磁盘上的产物 — 截图 + 高亮差异图(PNG)写入输出目录并返回,以便智能体检查它们。
对 token 友好的输出 — 类型化的
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 像素视口。默认使用设计图的尺寸。 |
|
| 产物写入位置。默认使用一个新的临时目录。 |
|
| 截图前要等待的 CSS 选择器。 |
|
| 加载后的额外稳定时间,单位 ms(≤ 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 map,然后进行感知 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";仅在被 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: 120px; height: 36px 是在其他视口上破坏真实主题的最快方式。mcp-perfectpixel 的设计使它不会偶然发生这种情况:
它从不建议宽度/高度补丁 — 补丁仅涉及颜色(
background-color、color、边框、outline)。布局永远不会被该工具“修复”。capture.responsive会报告页面自身的断点 — 所有样式表中不同的@media/@container条件计数。非零表示页面是响应式的,输出中的任何 px 尺寸都是特定于视口的。notes[]在重要时发出警告:如果元素以固定的 px 尺寸渲染,而页面使用了媒体/容器查询,或者差异仅涉及几何(没有颜色变化),区域备注会说明这一点,并告诉智能体优先使用流体尺寸(min/max-width、flex/grid、间距令牌),并在其他视口重新运行捕获以进行验证。这些值仍然是准确的 — 计算样式中的
width/height是捕获视口下的真实渲染值;它们是证据,而不是指令。
为了实现响应式 意图,请将此工具与 Figma MCP 的结构化数据 配合使用 (自动布局、约束、变量)——光栅验证像素,结构化数据为布局策略提供依据。
来自 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 像素,设计图 ≤ 50MB(读取前先 stat),≤ 50 个区域,候选选择器有界,抓取超时,文件扫描设限。
信任边界 —
mode: "local"/"hosted"具备 SSRF +file://保护,并明确要求repoRoot。会话感知样式表 — 通过浏览器的请求上下文获取,因此 cookie 会生效,跟踪到的 CSS 与页面实际渲染的 CSS 一致。
诚实的跟踪 —
trace.status/warnings报告失败和截断;测试、文档、生成文件中的文本搜索匹配会被降低优先级。Token 友好输出 — 浮点数取整、计算样式修剪、共享仓库遍历缓存与并行读取(负载减少约 37%,速度提升约 58%)。
密钥卫生 —
.env/.npmrc已加入 gitignore;CI 运行 Gitleaks、lint、构建、测试和覆盖率检查;发布工作流在发布前重新运行所有步骤。
路线图
目标 1 — 确定性捕获 + 像素比对
目标 2 — 将差异追溯到真实源(CSS 源码映射 → 支持 gitignore 的文本搜索,带置信度评分)
目标 3 — 最小补丁输出 优先使用项目自身的令牌
目标 4 — 结构化上下文交接(无需框架知识)
目标 5 — 开源规范 + 发布流水线(从
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 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