内容
# axe-mcp
通过Chrome DevTools协议,axe-mcp服务器**驱动Deque的真实axe DevTools浏览器扩展**,穿过DevTools UI - 它显示扩展的面板,点击**扫描**,并将面板的**自身**结果(影响总数 + 每个问题的列表)作为结构化数据返回给Claude。
这是实际的扩展(axe DevTools 4.x,面板在底层运行axe-core),**不是**重新实现。 还包含一个辅助的axe-core/Playwright路径(见末尾)。
## 工作原理
DevTools面板和面板iframe无法通过普通的页面自动化访问,因此axe-mcp直接使用CDP:
1. 附加到页面的**DevTools前端**目标(`devtools://…/devtools_app.html`)。
2. 从`UI.panels`读取axe面板的id并调用 **`InspectorFrontendAPI.showPanel(panelId)`** - 主机→前端桥。 这可靠地打开面板,没有菜单、坐标或对接黑客(所有这些都失败:DevTools忽略合成事件,溢出菜单/命令菜单不暴露它)。
3. 附加到扩展的 **`panel.html`** 目标,一旦它实例化。
4. 点击面板的 **扫描** 按钮(面板允许程序化点击)。
5. 轮询和抓取面板的渲染结果。
## 要求
- **BrowserOS** (或Chrome/Edge)并安装 **axe DevTools** 扩展(id `lhdoppojpmngadmnindnejefpokejbdd`)。 axe-mcp在磁盘上找到已安装的扩展并加载它。
- Node 18+(在Node 25上构建/测试)。
## 安装和构建
```bash
cd axe-mcp
npm install
npm run build
```
## 在Claude Code中注册
```bash
claude mcp add axe-mcp -- node /Users/chandu/github/axe-mcp/dist/index.js
```
…或在 `.mcp.json` 中:
```json
{
"mcpServers": {
"axe-mcp": { "command": "node", "args": ["/Users/chandu/github/axe-mcp/dist/index.js"] }
}
}
```
## 工具
| 工具 | 功能 |
|---|---|
| `axe_browser_start` | 启动BrowserOS(或Chrome/Edge),加载axe扩展,自动打开DevTools,并启动CDP端点。 参数:`url`,`port`(默认为9222)。 使用专用配置文件(`~/.axe-mcp-browser`),以免干扰您的日常浏览器。 |
| `axe_panel_scan` | 驱动真实的axe面板:显示它,点击扫描,返回结果。 参数:`navigateTo`,`scanType`(`full`/`partial`),`cdpEndpoint`,`timeoutMs`。 |
| `axe_browser_stop` | 停止由 `axe_browser_start` 启动的浏览器。 |
### 典型流程
> “在 https://example.com 上启动axe浏览器,然后运行 axe_panel_scan。”
`axe_browser_start({ url: "https://example.com" })` → `axe_panel_scan({})`。
您也可以附加到 **任何** 您自己使用扩展程序启动的浏览器,并使用 `--remote-debugging-port=9222 --remote-allow-origins=* --auto-open-devtools-for-tabs` 启动,
通过将 `cdpEndpoint` 传递给 `axe_panel_scan`。
### 结果形状
```json
{
"engine": "axe DevTools 扩展面板(Deque)",
"axeVersion": "4.11.4",
"standard": "WCAG 2.1 AA",
"bestPractices": false,
"testUrl": "https://example.com/",
"totals": { "total": 6, "critical": 3, "serious": 3, "moderate": 0, "minor": 0, "automatic": 6, "guided": 0, "manual": 0 },
"issues": [
{ "title": "按钮必须具有可辨别的文本", "description": "确保按钮具有可辨别的文本", "elementsAffected": 1 }
]
}
```
> 注意:面板默认为 **WCAG 2.1 AA 且最佳实践关闭**,因此其总数可能低于启用最佳实践规则的原始 `axe.run()` - 这是面板的配置,如实报告。
## 代码中内置的陷阱
- **`127.0.0.1` 而不是 `localhost`** - Chrome的调试端口仅限IPv4;`localhost` 解析为 `::1` → `ECONNREFUSED`。
- **`--remote-allow-origins=*`** 对于非浏览器CDP客户端是必需的(Chrome 111+);作为离散参数传递,以便shell无法全局变量它。
- **显示面板:** 对DevTools chrome的合成点击被忽略,信任输入不会路由到 *对接* 的前端,溢出菜单的DOM难以捉摸,并且没有命令菜单项 - 因此 `InspectorFrontendAPI.showPanel()` 是唯一可靠的方法。
- ** onboarding选项卡:** 全新配置文件会弹出扩展的 `install-success` 选项卡(第二个DevTools前端);扫描器关闭它并轮询每个前端,直到axe面板注册。
## 烟雾测试
```bash
node test/verify-full.mjs # startBrowser -> panelScan, 新的配置文件
node test/verify-tool.mjs # panelScan 对抗运行在 :9222 上的浏览器
```
`test/bad-page.html` 故意触发了 6 个WCAG规则(缺少alt,空按钮/链接,对比度低,缺少 `lang`,未标记输入)。
## 次要:axe-core / Playwright 路径
`src/scanner.ts` (工具默认未注册)通过CDP运行 **axe-core via `@axe-core/playwright`** 并注入页面结果面板。 当您不需要实际的扩展UI时,请使用它来进行无头,CSP证明的结构化结果。 测试:`test/smoke.mjs`,`test/panel-shot.mjs`。