tactual-mcp
OfficialTactual
屏幕阅读器导航成本分析器。用于衡量辅助技术用户在网页上发现、到达和操作交互式目标点的难度。
功能概述
现有的无障碍工具主要检查合规性——ARIA 是否正确?对比度是否足够?
Tactual 衡量的是导航成本——屏幕阅读器用户需要多少次操作才能到达结账按钮?如果他们操作过头了会发生什么?他们甚至能发现该按钮的存在吗?
它的工作原理是捕获 Playwright 无障碍快照,构建导航图,并根据辅助技术配置文件对每个目标点进行评分。
安装
# For CLI usage
npm install tactual playwright
# For MCP server usage (AI tools)
npm install tactual playwright @modelcontextprotocol/sdkPlaywright 和 @modelcontextprotocol/sdk 是可选的对等依赖项。CLI 和页面分析需要 Playwright。运行 tactual-mcp 服务器需要 MCP SDK。如果您仅将库 API 用于预捕获的状态,则无需安装这两者。
快速入门
CLI
# Analyze a URL (default profile: generic-mobile-web-sr-v0)
tactual analyze-url https://example.com
# Analyze with a specific AT profile
tactual analyze-url https://example.com --profile voiceover-ios-v0
# Explore hidden UI (menus, tabs, dialogs, disclosures)
tactual analyze-url https://example.com --explore
# Output as JSON, Markdown, or SARIF
tactual analyze-url https://example.com --format json --output report.json
tactual analyze-url https://example.com --format sarif --output report.sarif
# Compare two analysis runs
tactual diff baseline.json candidate.json
# List available AT profiles
tactual profiles
# Run benchmark suite
tactual benchmark
# Initialize a tactual.json config file
tactual init库 API
import { analyze, getProfile } from "tactual";
import { captureState } from "tactual/playwright";
import { chromium } from "playwright";
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto("https://example.com");
const state = await captureState(page);
await browser.close();
const profile = getProfile("generic-mobile-web-sr-v0");
const result = analyze([state], profile);
for (const finding of result.findings) {
console.log(finding.targetId, finding.scores.overall, finding.severity);
}MCP 服务器
Tactual 包含一个供 AI 代理使用的 MCP 服务器:
# Start the MCP server (stdio transport — default)
tactual-mcp
# Start with HTTP transport (for hosted platforms, remote clients)
tactual-mcp --http # listens on http://127.0.0.1:8787/mcp
tactual-mcp --http --port=3000 # custom port (or set PORT env var)
tactual-mcp --http --host=0.0.0.0 # bind to all interfaces (default: 127.0.0.1)可用的 MCP 工具:
工具 | 描述 |
| 分析网页的 SR 导航成本。默认格式为 |
| 追踪到特定目标点的分步导航路径。显示每次操作、成本和模拟的 SR 播报。接受目标 ID 或 glob 模式(例如 |
| 列出可用的 AT 配置文件 |
| 比较两个分析结果。显示已解决/新增的惩罚项、严重性变化以及每个目标点的状态。 |
| 按影响程度排序的修复建议。对于 SARIF 输出是多余的(修复建议已内联)。 |
| 对 Web 应用进行身份验证并保存会话状态。将输出文件路径作为 |
| 在一次调用中分析多个页面并进行站点级聚合。每页返回约 200 字节。适用于在深入分析单个页面之前的站点分类。 |
通过 AI 工具设置
首先在您的项目中安装所需的包:
npm install tactual playwright @modelcontextprotocol/sdkClaude Code — 添加到项目根目录的 .mcp.json 中:
{
"mcpServers": {
"tactual": {
"type": "stdio",
"command": "npx",
"args": ["tactual-mcp"]
}
}
}GitHub Copilot — 添加到 .copilot/mcp.json 或 ~/.copilot/mcp-config.json:
{
"mcpServers": {
"tactual": {
"type": "stdio",
"command": "npx",
"args": ["tactual-mcp"]
}
}
}Cursor / Windsurf / Cline — 在编辑器的 MCP 配置中使用相同格式:
{
"mcpServers": {
"tactual": {
"command": "npx",
"args": ["tactual-mcp"]
}
}
}直接安装(全局安装) — 如果您不想使用 npx:
npm install -g tactual playwright
tactual-mcp # starts the MCP server on stdioGitHub Actions
使用 GitHub Actions Marketplace 中的组合操作:
jobs:
a11y:
runs-on: ubuntu-latest
steps:
- name: Analyze accessibility
uses: tactual-dev/tactual@v0.2.1
with:
url: https://your-app.com
explore: "true"
fail-below: "70"该操作会安装 Tactual 和 Playwright,运行分析,将 SARIF 上传到 GitHub 代码扫描,如果平均分低于阈值,则构建失败。输出 average-score 和 result-file 供后续步骤使用。
或者直接使用 CLI 以获得更多控制权:
- name: Install Tactual
run: npm install tactual playwright
- name: Install browsers
run: npx playwright install chromium --with-deps
- name: Run accessibility analysis
run: npx tactual analyze-url https://your-app.com --format sarif --output results.sarif --threshold 70
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif配置
CLI 标志
Options:
-p, --profile <id> AT profile (default: generic-mobile-web-sr-v0)
-f, --format <format> json | markdown | console | sarif (default: console)
-o, --output <path> Write to file instead of stdout
-d, --device <name> Playwright device emulation
-e, --explore Explore hidden branches
--explore-depth <n> Max exploration depth (default: 3)
--explore-budget <n> Max exploration actions (default: 50)
--explore-max-targets <n> Max accumulated targets before stopping (default: 2000)
--exclude <patterns...> Exclude targets by name/role glob
--exclude-selector <css...> Exclude elements by CSS selector
--focus <landmarks...> Only analyze within these landmarks
--suppress <codes...> Suppress diagnostic codes
--top <n> Show only worst N findings
--min-severity <level> Minimum severity to report
--threshold <n> Exit non-zero if avg score < N
--config <path> Path to tactual.json
--no-headless Headed browser (for bot-blocked sites)
--timeout <ms> Page load timeout (default: 30000)
--probe Run keyboard probes (focus, activation, Escape, Tab)
--wait-for-selector <css> Wait for selector before capturing (for SPAs)
--wait-time <ms> Additional wait after page load
--storage-state <path> Playwright storageState JSON for authenticated pages
--summary-only Return only summary stats, no individual findings
-q, --quiet Suppress info diagnosticstactual.json
使用 tactual init 创建或手动创建:
{
"profile": "voiceover-ios-v0",
"exclude": ["easter*", "admin*", "debug*"],
"excludeSelectors": ["#easter-egg", ".admin-only", ".third-party-widget"],
"focus": ["main"],
"suppress": ["possible-cookie-wall"],
"threshold": 70,
"priority": {
"checkout*": "critical",
"footer*": "low",
"analytics*": "ignore"
}
}配置会自动从工作目录(tactual.json 或 .tactualrc.json)检测。CLI 标志会与配置设置合并并覆盖它们。
AT 配置文件
配置文件 | 平台 | 描述 |
| 移动端 | 标准化移动端 SR 原语(默认) |
| 移动端 | iOS Safari 上的 VoiceOver — 基于转子的导航 |
| 移动端 | Android Chrome 上的 TalkBack — 阅读控件 |
| 桌面端 | Windows 上的 NVDA — 浏览模式快捷键 |
| 桌面端 | Windows 上的 JAWS — 带有自动表单模式的虚拟光标 |
配置文件定义了每个导航操作的成本、评分维度权重、costSensitivity(缩放可达性衰减曲线)以及依赖于上下文的修饰符。有关实现细节,请参阅 src/profiles/。
评分
每个目标点都会收到一个 5 维评分向量:
维度 | 衡量内容 |
可发现性 (Discoverability) | 用户能否判断目标点是否存在? |
可达性 (Reachability) | 到达该处所需的导航成本是多少? |
可操作性 (Operability) | 控件的行为是否可预测? |
恢复性 (Recovery) | 从操作过头中恢复的难度如何? |
互操作风险 (Interop Risk) | AT/浏览器支持差异的可能性有多大?(惩罚项) |
维度权重因配置文件而异:
配置文件 | D | R | O | Rec | costSensitivity |
generic-mobile-web-sr-v0 | 0.30 | 0.40 | 0.20 | 0.10 | 1.0 |
voiceover-ios-v0 | 0.30 | 0.35 | 0.20 | 0.15 | 1.1 |
talkback-android-v0 | 0.25 | 0.45 | 0.20 | 0.10 | 1.3 |
nvda-desktop-v0 | 0.35 | 0.25 | 0.30 | 0.10 | 0.7 |
jaws-desktop-v0 | 0.30 | 0.25 | 0.35 | 0.10 | 0.6 |
综合评分: 加权几何平均值:overall = exp(sum(w_i * ln(score_i)) / sum(w_i)) - interopRisk。在取对数之前,每个维度至少为 1,以避免 log(0)。这意味着任何维度的零分都会严重拖累总分——你无法操作你无法到达的东西。
严重性等级:
分数 | 等级 | 含义 |
90-100 | 强 | 低关注度 |
75-89 | 可接受 | 可改进 |
60-74 | 中等 | 应进行分类处理 |
40-59 | 高 | 可能存在明显的摩擦 |
0-39 | 严重 | 可能存在阻塞 |
诊断
Tactual 会在分析可能不可靠时进行检测并报告:
代码 | 级别 | 含义 |
| 错误 | 检测到 Cloudflare/机器人挑战 |
| 错误 | 未找到任何目标点 |
| 警告 | 对于 http 页面来说目标点数量异常少 |
| 警告 | 仅找到 1-4 个目标点 |
| 警告 | 身份验证受限内容(检测到 |
| 信息 | Cookie 同意弹窗可能遮挡了内容 |
| 警告 | 跳转到了不同的域名 |
| 警告 | 未找到标题元素 |
| 警告 | 未找到地标区域 |
探索
--explore 标志可激活有界分支探索:
打开菜单、选项卡、披露框、手风琴和对话框
从隐藏的 UI 中捕获新的无障碍状态
将发现的目标点标记为
requiresBranchOpen遵守深度、操作次数、目标点数量和新颖性预算
安全操作策略会阻止破坏性交互
探索对于具有大量隐藏 UI(例如下拉菜单、选项卡式界面、模态对话框)的页面非常有用。
探索候选对象在迭代前按稳定键(角色 + 名称)排序,因此相同的内容在多次运行中会产生相同的探索顺序。
探索预算
预算 | CLI 标志 | 默认值 | 用途 |
深度 |
| 3 | 最大递归深度 |
操作 |
| 50 | 所有分支的总点击预算 |
目标点 |
| 2000 | 如果累计目标点超过此值则停止 |
时间 | (仅限库) | 120s | 全局挂钟超时 |
SPA 框架检测
Tactual 会在捕获无障碍树之前检测 SPA 内容是否已渲染。检测到的框架:React、Next.js、Vue、Nuxt、Angular、Svelte 和 SvelteKit。还会检查通用的 HTML5 内容信号(地标、标题、导航、链接)。对于自动检测未覆盖的 SPA,请使用 --wait-for-selector (CLI) 或 waitForSelector (MCP/API) 来指定指示您的应用已水合的 CSS 选择器。
在初始框架检测后,Tactual 使用基于收敛的轮询——重复对无障碍树进行快照,直到目标点数量稳定——这适用于任何框架。
互操作风险
Tactual 包含从 a11ysupport.io 和 ARIA-AT 项目 导出的 ARIA 角色/属性支持数据的静态快照。具有已知跨 AT/浏览器支持差距的角色会受到互操作风险惩罚。
角色 | 风险 | 注意 |
| 0 | 支持良好 |
| 5 | 焦点管理各异 |
| 8 | 最具互操作性问题的模式 |
| 10 | 在 JAWS 之外支持较差 |
| 15 | 滥用时很危险 |
输出格式建议
格式 | 典型大小 | 最佳用途 |
| ~8KB | 终端中的人工审查 |
| ~11KB | PR 和议题评论 |
| ~18KB | 程序化消费 |
| ~4-40KB | GitHub 代码扫描 / CI |
所有非 SARIF 格式都会发出汇总输出:统计信息、分组问题和最差发现(上限为 15)。SARIF 上限为 25 个结果。当输出被截断时,顶部会出现提示。
对于 MCP 使用,sarif 是默认且推荐的格式。使用 summaryOnly: true 进行最小化的健康检查(约 835 字节:统计信息、严重性计数、前 3 个问题)。
校准
Tactual 包含一个校准框架(src/calibration/,导出为 tactual/calibration),用于根据真实数据集调整评分参数。详情请参阅 docs/CALIBRATION.md。
开发
npm install # Install dependencies
npm run build # Build with tsup
npm run test # Run unit + integration tests
npm run test:benchmark # Run benchmark suite
npm run typecheck # TypeScript type checking
npm run lint # ESLint安全性
浏览器沙箱
Tactual 始终在启用默认 Chromium 沙箱的情况下运行 Playwright。它从不禁用 Web 安全性或修改浏览器的安全模型。所有页面交互都在标准的 Chromium 进程沙箱内进行。
安全操作策略
启用探索功能(--explore)时,Tactual 会在激活交互元素之前将其分为三个层级:
层级 | 操作 | 示例 |
安全 | 已激活 | 选项卡、菜单项、披露框、手风琴、页内锚点 |
谨慎 | 谨慎激活 | 外部链接、模糊按钮、提交按钮 |
不安全 | 跳过 | 删除、注销、购买、部署、取消订阅 |
这是一种基于关键字的启发式方法——它无法检测语义欺骗(例如,实际上会删除数据的“保存”按钮)或检查服务器端行为。在生产环境中使用时,请务必在受信任或沙箱环境中运行探索。
URL 验证
所有 URL 在导航前都会经过验证。默认情况下,私有/内部 IP 范围和非 HTTP(S) 方案会被拒绝。
许可证
Apache-2.0
Latest Blog Posts
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/tactual-dev/tactual'
If you have feedback or need assistance with the MCP directory API, please join our Discord server