tactual-mcp
OfficialTactual
スクリーンリーダーのナビゲーションコスト分析ツール。支援技術のユーザーがWeb上のインタラクティブなターゲットを発見し、到達し、操作することがどれほど困難かを測定します。
機能
既存のアクセシビリティツールは適合性(ARIAは正しいか?コントラスト比は十分か?)をチェックします。
Tactualはナビゲーションコストを測定します。スクリーンリーダーのユーザーがチェックアウトボタンに到達するまでに何回のアクションが必要か?操作を誤った場合はどうなるか?そもそもその存在を発見できるか?
Playwrightのアクセシビリティスナップショットを取得し、ナビゲーショングラフを構築し、支援技術プロファイルに基づいて各ターゲットをスコアリングすることで機能します。
インストール
# For CLI usage
npm install tactual playwright
# For MCP server usage (AI tools)
npm install tactual playwright @modelcontextprotocol/sdkPlaywrightと@modelcontextprotocol/sdkはオプションのピア依存関係です。PlaywrightはCLIおよびページ分析に必要です。MCP SDKはtactual-mcpサーバーを実行するために必要です。事前に取得した状態を使用してライブラリ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ツール:
ツール | 説明 |
| WebページをSRナビゲーションコストについて分析します。デフォルトの形式は |
| 特定のターゲットへのステップバイステップのナビゲーションパスを追跡します。各アクション、コスト、モデル化されたSRアナウンスを表示します。ターゲットIDまたはグロブパターン(例: |
| 利用可能なATプロファイルを一覧表示します |
| 2つの分析結果を比較します。解決/追加されたペナルティ、重大度の変化、ターゲットごとのステータスを表示します。 |
| 影響度順にランク付けされた修正案。SARIF出力の場合は冗長です(修正はインラインで行われるため)。 |
| Webアプリで認証し、セッション状態を保存します。認証済みコンテンツを分析するために、出力ファイルパスを |
| サイトレベルの集計を行い、1回の呼び出しで複数のページを分析します。ページあたり約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 Code Scanningにアップロードし、平均スコアがしきい値を下回った場合にビルドを失敗させます。後続のステップのために 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。各次元は、log(0)を避けるためにログを取る前に1を下限としています。これは、いずれかの次元がゼロであれば全体スコアが大幅に低下することを意味します。到達できないものは操作できないためです。
重大度バンド:
スコア | バンド | 意味 |
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およびIssueのコメント |
| ~18KB | プログラムによる消費 |
| ~4-40KB | GitHub Code Scanning / CI |
SARIF以外のすべての形式は、要約された出力(統計、グループ化された問題、最悪の発見(最大15件))を出力します。SARIFは最大25件の結果に制限されます。出力が切り捨てられた場合、上部に注記が表示されます。
MCP使用の場合、sarif がデフォルトであり、推奨される形式です。最小限のヘルスチェック(約835バイト:統計、重大度カウント、上位3つの問題)には summaryOnly: true を使用してください。
キャリブレーション
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はインタラクティブな要素をアクティブにする前に3つの階層に分類します:
階層 | アクション | 例 |
安全 | アクティブ化 | タブ、メニュー項目、開閉式要素、アコーディオン、ページ内アンカー |
注意 | 注意してアクティブ化 | 外部リンク、曖昧なボタン、送信ボタン |
安全でない | スキップ | 削除、サインアウト、購入、デプロイ、登録解除 |
これはキーワードベースのヒューリスティックであり、意味的な欺瞞(例:実際にはデータを削除する「保存」ボタン)を検出したり、サーバー側の動作を検査したりすることはできません。本番環境で使用する場合は、常に信頼できる環境またはサンドボックス化された環境に対して探索を実行してください。
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