mcpField
P
pxtree

pxtree

本地服务
github.com/alabsi91开发工具05 周前更新

关于 pxtree

pxtree 是供编码 Agent 检查网页布局的命令行工具和 MCP 服务,可用紧凑文本树及测量结果呈现 Chromium 的实际渲染。它还能比较运行变化,并在同次测量中输出无障碍树或截图。

主要功能

  1. 01以文本树呈现网页渲染
  2. 02测量元素尺寸与位置
  3. 03比较同一页面的运行变化
  4. 04支持多个视口和配色方案
  5. 05可附加无障碍树或截图

适用场景

  1. 01检查开发服务器页面的布局问题
  2. 02对比修复前后的页面测量
  3. 03检查不同视口或配色下的呈现
  4. 04查看页面无障碍结构

MCP 相关

pxtree 提供 MCP 服务,包含 measure 和 read_me_first 两个工具。编码 Agent 可请求网页测量报告、ARIA 树和截图。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"alabsi91-pxtree": {
"command": "npx",
"args": [
"-y",
"pxtree"
]
}
}
}
启动命令npx -y pxtree

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmpxtree0.1.2

工具

2

收录的工具列表 · 更新于 2 周前

参数类型必填说明
ariaboolean否布尔值:在报告后添加页面或每个匹配元素的 Playwright aria 快照
diffboolean否布尔值:与相同 target 和设置的上一次运行进行比较。默认值为 true
waitany否脚本运行后:以毫秒为单位的休眠时长,可为数字或数字字符串,且不超过 timeout;或者 CSS 选择器字符串,等待其在 timeout 内出现
colorsboolean否布尔值:在 [text] 和 [renders] 中打印十六进制颜色值
reportenum否可选值为 "tree"、"findings"、"summary"、"changes"、"none"。tree:全部内容。findings:仅显示包含发现项的行及其祖先行。summary:不显示树。changes:事实行和自上次运行以来的变化。none:仅事实行。默认值为 treetree | findings | summary | changes | none
scriptstring否字符串:async (page) => {} 的函数体,或完整函数(如 async (page) => {}),在测量前使用 Playwright 页面运行。此代码受信任,会以 Node 身份在服务器进程中运行,并拥有完整权限
scrollany否一个停止点或停止点数组:数字或数字字符串表示窗口 y 偏移量,"end" 表示底部,其他值均视为要滚动到顶部的 CSS 选择器。数组会依次测量每个停止点,每个停止点运行一次。默认值为 0
targetstring是字符串:URL、类似 localhost:5173 的主机名,或工作目录下的 HTML 文件路径
diffKeystring否名称字符串,用于替代自上次运行以来的键中的 script 和 wait,以便比较使用相同名称的脚本运行和普通运行
elementstring否CSS 选择器字符串:仅打印匹配元素及其祖先行
schemesarray否"light" 和 "dark" 的数组,表示每次运行使用的 prefers-color-scheme。默认值为 ["light"]
timeoutnumber否达到 DOMContentLoaded 的毫秒数。脚本、wait、reveal、settle 和测量都会各自重新获得此时长。默认值为 30000
childrenboolean否布尔值。与 element 一起使用时:包含匹配项内部的内容。默认值为 true
maxCharsnumber否数字:报告的最大字符数。超出后会在一行处截断树;事实、自上次运行以来的内容和摘要仍会保留。默认值为 80000
viewportsarray否一个包含 { width, height } 的数组,数值为整数,每个尺寸运行一次。默认值为 [{ width: 1280, height: 800 }]
screenshotboolean否布尔值:为每次运行在操作系统临时目录下保存一个 PNG,并返回其路径

详细介绍

pxtree

在无头 Chromium 中加载网页,并以紧凑的文本树形式打印实际渲染结果,让 AI 编码 Agent 无需截图即可检查布局。

开发服务器页面中包含一行三张卡片、一行三个方案、一列步骤、一行统计数据、一篇文章、一个表单、一列价格和一行磁贴:

$ npx -y pxtree@latest localhost:5173
1280x800 light dpr 1 ltr scroll 0/382 page 1280x1182 painted to 1134
since last run: no changes
summary: 7 findings
  a.button tops 64..136 across siblings: ul.cards
  div.stat tops 0..6 across siblings: div.stats
  input.field starts 0..3 across siblings: form.fields
  12 wider than li.plan: li.plan.featured
  72 taller than li.card: li.card 3 of 3
  20 shorter than div.tile: div.tile.short
  gaps 16 16 24 16 between li.step: ul.steps
body 1280x1182 [pad 24][gaps 24 24 24 24 16 16 …, free 24 at end]
  ul.cards 1232x208 [gaps across 16, free 600 at end][!! a.button tops 64..136 across siblings]
    li.card 200x136 [pad 16][gaps 8][renders background]
      h3 "Starter" 168x24 [text 19/24]
      p "Short text." 168x24 @0,32 [text 16/24]
      a.button "Choose" 168x40 @0,64 [pad 8 16][text 16/24][renders background]
    li.card 200x136 @216,0 [pad 16][gaps 8][renders background]
      h3 "Team" 168x24 [text 19/24]
      p "Short text." 168x24 @0,32 [text 16/24]
      a.button "Choose" 168x40 @0,64 [pad 8 16][text 16/24][renders background]
    li.card 200x208 @432,0 [pad 16][gaps 8][renders background][!! 72 taller than li.card]
      h3 "Business" 168x24 [text 19/24]
      p "A much longer…" 168x96 @0,32 [text 16/24, 4 lines, 444 on one line]
      a.button "Choose" 168x40 @0,136 [pad 8 16][text 16/24][renders background]
  ul.plans 1232x56 @0,232 [gaps across 16, free 588 at end]
    li.plan "Monthly" 200x56 [pad 16][text 16/24][renders background]
    li.plan "Yearly" 200x56 @216,0 [pad 16][text 16/24][renders background]
    li.plan.featured "Lifetime" 212x56 @432,0 [pad 16][text 16/24][renders background][!! 12 wider than li.plan]
  ul.steps 1232x192 @0,312 [gaps 16 16 24 16][!! gaps 16 16 24 16 between li.step]
    li.step "One" 1232x24 [text 16/24]
    li.step "Two" 1232x24 @0,40 [text 16/24]
    li.step.active "Three" 1232x24 @0,80 [text 16/24]
    li.step "Four" 1232x24 @0,128 [text 16/24]
    li.step "Five" 1232x24 @0,168 [text 16/24]
  div.stats 1232x62 @0,528 [gaps across 16, free 456 at end][!! div.stat tops 0..6 across siblings]
    div.stat "Revenue" 182x56 [pad 16][text 16/24][renders background]
    div.stat "Orders" 182x56 @198,0 [pad 16][text 16/24][renders background]
    div.stat.alert "Refunds" 182x56 @396,6 [pad 16][text 16/24][renders background]
    div.stat "Customers" 182x56 @594,0 [pad 16][text 16/24][renders background]
  article 1232x132 @0,614 [gaps 12]
    h2 "First heading" 1232x24 [text 24/24]
    p "First paragraph." 1232x24 @0,36 [text 16/24]
    h2 "Second heading" 1232x24 @0,72 [text 24/24]
    p "Second paragraph." 1232x24 @0,108 [text 16/24]
  p.with-link "Read the first." 1232x24 @0,762 [text 16/24]
    a "guide" 39x17 @69,3 [text 16/24]
  form.fields 1232x108 @0,802 [gaps 8][!! input.field starts 0..3 across siblings]
    input.field "Name" 208x21 [pad 1 2][text 13/15][renders background, border]
    input.field "Email" 208x21 @0,29 [pad 1 2][text 13/15][renders background, border]
    input.field.nudged "Company" 208x21 @3,58 [pad 1 2][text 13/15][renders background, border]
    input.field "Phone" 208x21 @0,87 [pad 1 2][text 13/15][renders background, border]
  div.prices 300x72 @0,934
    span.price "$9" 18x24 @282,0 [text 16/24]
    …×2 similar span.price 36x24..49x24
  div.tiles 1232x80 @0,1030 [gaps across 16, free 900 at end]
    div.tile 100x80 [renders background]
    div.tile.short 100x60 @116,0 [renders background][!! 20 shorter than div.tile]
    div.tile 100x80 @232,0 [renders background]

第一行是事实行:视口、配色方案、设备像素比、方向、当前滚动位置与最大滚动位置之差、文档尺寸,以及 painted to(最后绘制的像素)。since last run 会与相同 URL 和设置的上一次运行结果进行比较,或与相同 --diff-key 名称的运行结果进行比较。这些历史记录保存在 ~/.cache/pxtree 中,绝不会写入你的项目;使用 --no-diff 可跳过历史记录。

ul.cards 行表示,三张卡片中“Choose”按钮的顶部与各自卡片顶部相距 64 px 至 136 px。li.plan.featured "Lifetime" 行表示,该方案在所在行中的位置为 x 432,尺寸为 212x56,比同级方案共享的宽度多 12 px。这些发现是带阈值的测量结果,不是结论。Agent 会根据代码判断这些情况是否符合预期。

为什么不用截图

  • 提供 CSS px 数值,而不是需要模型估算的像素。
  • Agent 可以一次性以文本形式读取,并优先看到列出的发现。
  • 一次调用即可覆盖多个视口和配色方案。

安装

pxtree 使用 Playwright 的 Chromium。安装一次即可,约占用 150 MB:

npx -y [email protected] install chromium

pxtree 本身不会下载任何内容,也不会修改你的项目。--channel chrome 会改用已安装的 Chrome。需要 Node 20 或更高版本。

MCP 服务
客户端安装范围
Codexcodex mcp add pxtree -- npx -y pxtree@latest mcp用户,~/.codex/config.toml
Claude Codeclaude mcp add --scope user pxtree -- npx -y pxtree@latest mcp用户。--scope project 会写入 .mcp.json
Cursor在 Cursor 中安装 或 ~/.cursor/mcp.json / .cursor/mcp.json用户 / 项目
VS Code Copilot在 VS Code 中安装 或 code --add-mcp '{"name":"pxtree","command":"npx","args":["-y","pxtree@latest","mcp"]}'用户。项目配置见下文 .vscode/mcp.json
OpenCode~/.config/opencode/opencode.json 或 opencode.json,见下文用户 / 项目

OpenCode,opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "pxtree": { "type": "local", "command": ["npx", "-y", "pxtree@latest", "mcp"], "enabled": true }
  }
}
其他客户端和配置文件

任何读取 mcpServers 的 MCP 客户端:

{
  "mcpServers": {
    "pxtree": { "command": "npx", "args": ["-y", "pxtree@latest", "mcp"] }
  }
}
| 客户端 | 命令或配置路径 | 范围 | | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | | Claude Code 插件(MCP 服务和技能) | `/plugin marketplace add alabsi91/pxtree`,然后运行 `/plugin install pxtree@pxtree` | 用户 | | Gemini CLI | `gemini mcp add -s user pxtree npx -y pxtree@latest mcp` | 用户。不使用 `-s user` 时:项目 `.gemini/settings.json` | | Devin(原名 Windsurf) | `devin mcp add pxtree -- npx -y pxtree@latest mcp`,文件 `~/.config/devin/mcp_config.json` / `.devin/mcp_config.json` | 用户 / 项目 | | Amp | `amp mcp add pxtree -- npx -y pxtree@latest mcp`,文件 `~/.config/amp/settings.json` / `.amp/settings.json`,见下文 | 用户 / 项目 | | Zed | `~/.config/zed/settings.json`,见下文 | 用户 | | Cline | CLI:`cline mcp` 或 `~/.cline/mcp.json`。VS Code 扩展:Cline 面板,MCP Servers,Configure | 用户 | | Roo Code | `.roo/mcp.json`,或 Roo 设置中的 `mcp_settings.json` | 项目 / 用户 | | JetBrains AI Assistant | Settings,Tools,AI Assistant,Model Context Protocol (MCP):粘贴上面的 JSON。文件路径未记录,请查阅客户端文档 | 用户 / 项目 |

VS Code,.vscode/mcp.json:

{
  "servers": {
    "pxtree": { "type": "stdio", "command": "npx", "args": ["-y", "pxtree@latest", "mcp"] }
  }
}

Amp,settings.json:

{
  "amp.mcpServers": {
    "pxtree": { "command": "npx", "args": ["-y", "pxtree@latest", "mcp"] }
  }
}

Zed,settings.json:

{
  "context_servers": {
    "pxtree": { "command": "npx", "args": ["-y", "pxtree@latest", "mcp"], "env": {} }
  }
}

MCP Registry 名称:io.github.alabsi91/pxtree。该服务提供两个工具:measure 和 read_me_first。后者会返回技能包含的内容:如何使用 pxtree、如何报告,以及阅读指南。其说明要求 Agent 在每个会话中调用一次 read_me_first,因此无需安装技能。

measure 接受 target 和 CLI 标志作为输入:viewports、schemes、scroll、element、children、colors、wait、script、screenshot(设为 true 时,会在临时目录下为每次运行保存一张 PNG)、timeout、maxChars(默认值为 80000)、diff、diffKey、report(tree、findings、summary、changes 或 none)以及 aria(设为 true 时会添加 aria 树)。一次调用可以同时返回报告、aria 树和截图。输入值有范围限制:视口边长为 1 到 10000,最多 10 个视口,timeout 最大为 120000。文件目标必须位于服务的工作目录下。此规则可防止意外操作,但并非安全边界:script 是受信任的代码,会以 Node 身份在服务进程中运行。

技能

对于会读取 Agent Skills 的 Agent,包括通过 .agents/skills 使用的 Codex:

npx -y skills add alabsi91/pxtree

也可以手动创建链接。Codex、Cursor、Copilot、Gemini CLI、OpenCode、Amp 和 Devin 会读取 ~/.agents/skills。Claude Code 会读取 ~/.claude/skills。

git clone https://github.com/alabsi91/pxtree
mkdir -p ~/.agents/skills ~/.claude/skills
ln -s "$PWD/pxtree/skills/pxtree" ~/.agents/skills/pxtree
ln -s "$PWD/pxtree/skills/pxtree" ~/.claude/skills/pxtree

仅供单个项目使用时,请使用 <project>/.agents/skills 或 <project>/.claude/skills。

仅使用 Shell 的 Agent

告诉 Agent 运行此命令。它会输出标志、输出语法、每个标签和检测结果,以及限制。

npx -y pxtree@latest guide

CLI

npx -y pxtree@latest https://example.com --viewport 390x844,1280x800 --scheme light,dark
npx -y pxtree@latest localhost:5173 --scroll '#pricing' --element '.card'
npx -y pxtree@latest ./dist/index.html
npx -y pxtree@latest localhost:5173 --script "await page.click('text=Menu')" --wait '.menu'
npx -y pxtree@latest localhost:5173 --element '#pricing' --screenshot pricing.png
npx -y pxtree@latest localhost:5173 --viewport 390,1280
npx -y pxtree@latest localhost:5173 --report summary --aria
npx -y pxtree@latest localhost:5173 --report findings
npx -y pxtree@latest localhost:5173 --report changes
npx -y pxtree@latest localhost:5173 --report none --screenshot shot.png

只有当选择器恰好匹配一个元素时,截图才会裁剪到 --element 匹配项。否则截图会覆盖整个视口,事实行会说明匹配了多少个元素。

--report 用于选择打印多少测量结果:tree(默认,全部内容)、findings(仅保留有检测结果的行及其祖先的名称)、summary(不显示树)、changes(显示事实行和上次运行后的变化,用于检查修复效果)或 none(仅显示事实行)。在 --viewport 中只指定宽度时,会匹配相应的高度:390x844、768x1024、820x1180、1024x768、1280x800、1440x900、1920x1080;其他宽度均为 800。--aria 会在报告后添加 Playwright 的页面 ARIA 快照,或每个 --element 匹配项的 ARIA 快照:角色、名称、状态和阅读顺序,均取自与测量相同的状态。这样一次调用就能提供检测结果、无障碍树和截图。

npx -y pxtree@latest --help 会列出标志。npx -y pxtree@latest guide 会说明如何读取输出。

限制

  • 仅检查视口内的覆盖情况。
  • 不会遍历声明式的封闭 shadow root。
  • 不会遍历 iframe。请单独测量框架 URL。
  • 伪元素的绘制内容会放置在元素的盒子上。
  • 裁剪路径按边框盒计算。忽略边框圆角。
  • 在经过旋转或缩放的盒子内部,不会报告重叠、居中或宽度问题。其轴对齐盒无法说明元素的位置。
  • 不会测量图片或渐变上的对比度;[text] 标签会在此类情况下显示 on image。对于渐变文字等透明文字填充,也不会测量对比度;此时会显示 fill transparent。
  • small target 会跳过文本行内的链接,以及间距足够的目标,正如 WCAG 2.5.8 所允许的那样。
  • pxtree 不会猜测意图。全幅区域、头像堆叠、打开的弹出层或折叠面板都会照常打印其数值。
  • 仅模拟桌面端:(hover: hover) 和 (pointer: fine) 匹配。不支持触摸。
  • 垂直书写模式会打印物理位置。
  • 加载时最多等待 load 事件 2 s,以及网络静默 1.5 s;文件会跳过这些等待。加载较慢的页面需要使用 --wait。

API

import { createSession, format } from 'pxtree';

const session = await createSession();
const result = await session.measure('localhost:5173', { viewports: [{ width: 390, height: 844 }] });
console.log(format(result));
await session.close();

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。