mcpField
M
mcp-accessibility-scanner

mcp-accessibility-scanner

ローカル
github.com/JustasMonkev開発ツール59今日更新

mcp-accessibility-scanner について

mcp-accessibility-scannerは、コーディングエージェント向けのMCPサーバーで、axeによるページスキャン、キーボード操作の検査、アクセシビリティツリーの監査を行います。結果を保存しますが、WCAG適合の認証や手動テストの代替にはなりません。

主な機能

  1. 01axeによるWCAGスキャン
  2. 02キーボードフォーカスの監査
  3. 03ブラウザーのアクセシビリティツリー検査
  4. 04JSONの検出結果とレポート保存
  5. 05ブラウザー操作とキャプチャの自動化

活用シーン

  1. 01開発中のローカルWebアプリを確認
  2. 02キーボード操作とフォーカスを検証
  3. 03アクセシブルネームとページ構造を確認
  4. 04チームレビュー用に監査結果を保存

MCP 対応

MCPクライアントに、`scan_page`、`audit_keyboard`、`audit_screen_reader`などのブラウザー自動化、アクセシビリティスキャン、監査ツールを提供します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"justasmonkev-mcp-accessibility-scanner": {
"command": "npx",
"args": [
"-y",
"mcp-accessibility-scanner"
]
}
}
}
起動コマンドnpx -y mcp-accessibility-scanner

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmmcp-accessibility-scanner1.1.1

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

MCP アクセシビリティスキャナー 🔍

コーディングエージェント内でアクセシビリティをチェックできます。axe によるスキャン、キーボードフォーカスのチェック、再現可能なレポートに対応しています。

Weekend Workshop デモのスキャナー生成スクリーンショット。画像の代替テキストの欠落、コントラスト不足のテキスト、ラベルのないメール入力欄、名前のない矢印ボタンを示す赤い枠とルールラベルが表示されています。

意図的に問題を含めたローカルデモページを、自動ツールでチェックしました。これらの注釈は手作業で追加したものではなく、annotateScreenshot: true を指定した scan_page によって生成されました。

この MCP サーバーを使うと、コーディングエージェントがページを検査し、axe チェックを実行し、キーボードフォーカスを操作して、確認用の検出結果を保存できます。自動チェックで WCAG 準拠が認定されるわけではありません。手動でのアクセシビリティテストも引き続き必要です。audit_screen_reader は、ブラウザーのアクセシビリティツリー、アクセシブルな名前、要素のジオメトリを検査します。実際のスクリーンリーダーを使ったテストは行いません。

クイックスタート:コーディングエージェントを接続する

最初の監査を実行する前に、Google Chrome をインストールしてください。以下の設定ではシステムの Chrome を使用します。npm パッケージをインストールしてもブラウザーはインストールされません。別の方法については、ブラウザーの設定をご覧ください。

スキャナーをインストールします。

npm install -g mcp-accessibility-scanner --allow-scripts=re2

このフラグを指定すると、npm 12 でネイティブの re2 依存関係をインストールできます。ビルド済みバイナリが利用できない場合、インストーラーにはネイティブのビルドツールチェーンが必要です。re2 のインストールに関する注意事項をご覧ください。

この stdio サーバーをコーディングエージェントの MCP 設定に追加してから、クライアントを再起動するか再接続します。

{
  "mcpServers": {
    "accessibility-scanner": {
      "command": "mcp-accessibility-scanner",
      "args": ["--headless", "--isolated", "--output-dir", "./a11y-output"]
    }
  }
}

クライアントがインストールしたコマンドを PATH 上で見つけられる必要があります。--isolated を指定すると、個人用の Chrome セッションではなく、新しいブラウザープロファイルが使用されます。出力パスはサーバーの作業ディレクトリからの相対パスです。クライアントが別の場所からサーバーを起動する場合は、絶対パスの --output-dir を使用してください。クライアントごとのセットアップ方法やその他のインストール方法については、以下のリファレンスをご覧ください。

最初の監査

アプリをローカルで起動し、接続済みのコーディングエージェントに、URL をアプリのアドレスに置き換えて、以下のツールを順番に実行するよう依頼します。

browser_navigate {"url":"http://localhost:3000"}
scan_page {"annotateScreenshot":true}
audit_keyboard {"maxTabs":30}
audit_screen_reader {}

これらは MCP ツール呼び出しであり、シェルのサブコマンドではありません。ターミナルから使用する方法については、対話モードをご覧ください。

scan_page は、JSON 形式のノード詳細と修正用リンクを含むテキスト形式の検出結果を返します。annotateScreenshot: true を指定すると、ページ全体に注釈を付けた PNG も保存され、ファイルリソースのリンクが返されます。JSON レポートは保存されません。audit_keyboard と audit_screen_reader は JSON レポートを保存し、概要とレポートへのリンクを返します。audit_site と scan_page_matrix も JSON レポートを保存します。HTML レポートのダッシュボードは生成されません。未完了のチェック、カバレッジに関する警告、まだテストしていないページの状態を確認してください。

スクリーンショットを再現するには、このリポジトリからデモを python3 -m http.server 8765 --bind 127.0.0.1 --directory docs/assets で配信し、http://127.0.0.1:8765/accessibility-demo.html に移動してから、annotateScreenshot: true を指定して scan_page を実行します。スクリーンショットでは、1000×720 のビューポート(--viewport-size 1000,720)を使用しました。

バッジ

MCP Toplist

MseeP.ai セキュリティ評価バッジ

Star History

Star History Chart

機能

アクセシビリティスキャン

✅ WCAG 2.0/2.1/2.2 の基準(A、AA、AAA レベル)を自動チェックします
📄 修正方法のガイダンスを含む JSON 監査レポートとスキャン結果を保存します
🎯 特定の違反カテゴリー(色のコントラスト、ARIA、フォーム、キーボード操作など)に対応しています

ブラウザーの自動操作

🖱️ アクセシビリティスナップショットを使って要素をクリック、ホバー、ドラッグします
⌨️ テキストを入力し、キーボード入力を処理します
🔍 ページのスナップショットを取得して、すべてのインタラクティブ要素を検出します
📸 スクリーンショットを撮影し、PDF を保存します
🎯 要素ベースと座標ベースの両方の操作に対応しています

高度な機能

📑 複数ページのワークフローに対応するタブ管理
🌐 コンソールメッセージとネットワークリクエストを監視します
⏱️ 動的コンテンツが読み込まれるまで待機します
📁 ファイルのアップロードとブラウザーダイアログを処理します
🔄 ブラウザーの履歴を移動します

インストール

以下のいずれかの方法でパッケージをインストールできます。

npm を使用する場合:

npm install -g mcp-accessibility-scanner --allow-scripts=re2

npm 12 では、許可しない限り依存関係のインストールスクリプトは実行されません。このスキャナーは re2 に依存しています。これはインストールスクリプトが re2.node をダウンロードまたはビルドするネイティブモジュールです。実行されないと、サーバーの起動時に Cannot find module './build/Release/re2.node' エラーが発生します。npm install -g と npx に --allow-scripts=re2 を渡してください(古い npm バージョンではこのフラグを受け付けて無視します)。npm 12 以降でプロジェクトの依存関係として使用する場合は、npm install-scripts approve re2 を実行してから npm rebuild re2 を実行してください(許可しても、すでにスキップされたスクリプトは実行されません)。npm 11 以前では、インストールスクリプトはデフォルトで実行されます。スクリプトが明示的に無効化されていない場合は、npm rebuild re2 を実行して、失われたバイナリを復元してください。npm 12 でのすべてのグローバルインストールに対して許可するには、npm config set allow-scripts=re2 --location=user を実行します。

Docker を使ったインストール

Docker Hub でビルド済みのイメージを利用できます。このイメージには Chromium が含まれており、コンテナーでの使用に合わせて事前設定されているため、追加のフラグは不要です。

Docker Hub から取得:

docker pull justasmonkev/mcp-accessibility-scanner
Claude Code
 claude mcp add mcp-accessibility-scanner -s user -- docker run -i --rm justasmonkev/mcp-accessibility-scanner

スクリーンショットとレポートをホスト上に保存するには、ボリュームマウントを追加します。

claude mcp add mcp-accessibility-scanner -s user \
  -- docker run -i --rm -v /tmp/mcp-output:/app/output justasmonkev/mcp-accessibility-scanner

-v マウントを指定しない場合、出力ファイルはコンテナー内にのみ作成され、コンテナーの終了時に失われます。

Docker Compose
docker compose up -d

Compose の設定では、認証なしの MCP HTTP トランスポートを 127.0.0.1:8931 のみに公開します。このポートを信頼できないネットワークに公開しないでください。

ソースからビルド
docker build -t mcp-accessibility-scanner .

この Dockerfile からビルドしたイメージには、初期化プロセスとして tini が含まれています。Docker の --init フラグは省略可能です。

Docker のスモークテスト
npm run test:docker
VS Code へのインストール

VS Code CLI を使って VS Code に Accessibility Scanner をインストールします。

VS Code の場合:

code --add-mcp '{"name":"accessibility-scanner","command":"npx","args":["--allow-scripts=re2","mcp-accessibility-scanner"]}'

VS Code Insiders の場合:

code-insiders --add-mcp '{"name":"accessibility-scanner","command":"npx","args":["--allow-scripts=re2","mcp-accessibility-scanner"]}'

CLI モード

スキャナーは、使用方法に応じて 2 つのモードで実行できます。

MCP サーバー(デフォルト、サブコマンドなし)

サブコマンドなしで起動すると、プロセスは stdio 経由で通信する MCP サーバーを起動します。これは Claude Desktop、VS Code、Claude Code などの MCP クライアントが使用するモードです。手動で実行する必要はありません。

npx --allow-scripts=re2 mcp-accessibility-scanner            # starts the MCP server (stdio)

この README に記載されている MCP クライアントの設定例は、すべてこのデフォルトモードを使用しています。

インタラクティブ REPL(interactive サブコマンド)

ターミナルから手動で使用する場合、interactive サブコマンドを実行すると readline REPL が起動し、任意のツールを直接呼び出せます。

$ npx --allow-scripts=re2 mcp-accessibility-scanner interactive
Interactive mode. Type "<tool-name> <json>" to call a tool. Ctrl+D to exit.
> browser_navigate {"url": "https://example.com"}
> scan_page {"violationsTag": ["wcag21aa"]}
> audit_keyboard {"maxTabs": 30}
> audit_screen_reader {}

各行の形式は <tool-name> <json-arguments> です。{} を渡す場合は JSON を省略します。 ここでもブラウザー接続に関するグローバルフラグは引き続き適用されます。たとえば、npx --allow-scripts=re2 mcp-accessibility-scanner --headless interactive のように実行できます。 汎用モバイルデバイス(Chromium では Pixel 10、WebKit では iPhone 17)をエミュレートするには、--mobile または PLAYWRIGHT_MCP_MOBILE=1 を使用します。--device、CDP の接続/起動モード、リモートブラウザーエンドポイント、または --extension とは併用できません。

ブラウザー拡張機能モード

--extension を使用すると、現在の Playwright Extension 経由で接続できます。この拡張機能は、拡張機能プロトコル v2 に対応している必要があります。

npx --allow-scripts=re2 mcp-accessibility-scanner --extension

PLAYWRIGHT_MCP_EXTENSION_TOKEN に、接続承認ダイアログを省略するための拡張機能に表示されるトークンを設定してください。リレーの CDP WebSocket エンドポイントには、リレーごとに生成され、サーバー自身の接続用に自動的に付加される別個のランダムなトークンが常に必要です。この CDP トークンが Chrome の起動引数や拡張機能の URL に渡されることはありません。また、拡張機能の承認トークンで CDP クライアントを認証することはできません。 トークンを使った接続はバックグラウンドでの利用には適していません。Chrome で接続タブとウィンドウが前面に表示され、クライアントが作成したタブは切断後も開いたままになります(上流側の制限)。 トークンを使用する場合、接続ページが開いてから 30 秒以内に拡張機能が接続してセットアップを完了する必要があります。失敗した試行ではリレーが解放されるため、次のツール呼び出しで再試行できます。トークンを使用しない場合、手動承認は呼び出しを承認するかキャンセルするまで待機します。 --user-data-dir に複数の Chrome プロファイルが含まれている場合、拡張機能がインストールされているプロファイルが自動的に選択されます。Chrome で最後に使用したプロファイルが優先されます。プロファイルを明示的に選択するには、--profile-dir-name を渡すか、PLAYWRIGHT_MCP_PROFILE_DIR_NAME を設定してください。このオプションには --user-data-dir が必要で、Default や Profile 1 などの Chrome プロファイルディレクトリ名を指定します(chrome://version の「Profile Path」を参照)。PLAYWRIGHT_MCP_EXTENSION_TOKEN の承認トークンはプロファイル固有です。プロファイルを明示的に選択する場合は、そのプロファイルに表示されるトークンを使用してください。

パッケージ化された拡張機能は、プロファイルの設定に有効なレコードが必要です。拡張機能のディレクトリが残っているだけでは、インストール済みとは見なされません。設定で拡張機能が無効または未インストールとされているプロファイルは、自動選択の対象外となり、明示的に選択した場合も拒否されます。カスタム実行ファイルを使用する場合、明示的な選択ではローカルのインストール確認が省略されます。空白文字のみの PLAYWRIGHT_MCP_PROFILE_DIR_NAME は未設定として扱われます。それ以外の文字列環境変数では、従来どおり空の値が処理されます。

利用可能なツールの確認(list-tools サブコマンド)

組み込みツールの名前と説明を表示するには、次のようにします(ページに登録された WebMCP ツールには、ライブの MCP tools/list リクエストが必要です)。

npx --allow-scripts=re2 mcp-accessibility-scanner list-tools

注: browser_navigate や scan_page などのツール名は、MCP ツール識別子(および対話モードでの REPL コマンド)です。シェルのサブコマンドではないため、npx mcp-accessibility-scanner browser_navigate のように実行することはできません。

設定

Claude Desktop の設定は次のとおりです。

{
  "mcpServers": {
    "accessibility-scanner": {
      "command": "npx",
      "args": ["-y", "--allow-scripts=re2", "mcp-accessibility-scanner"]
    }
  }
}
詳細設定

Playwright の動作をカスタマイズするには、設定ファイルを渡します。

{
  "mcpServers": {
    "accessibility-scanner": {
      "command": "npx",
      "args": ["-y", "--allow-scripts=re2", "mcp-accessibility-scanner", "--config", "/path/to/config.json"]
    }
  }
}
ツール名の完全一致による選択
npx --allow-scripts=re2 mcp-accessibility-scanner --allowed-tools browser_pdf_save --blocked-tools browser_evaluate,browser_file_upload
CLI環境変数JSON 設定
--allowed-toolsPLAYWRIGHT_MCP_ALLOWED_TOOLSallowedTools
--blocked-toolsPLAYWRIGHT_MCP_BLOCKED_TOOLSblockedTools

CLI/環境変数の値は、カンマ区切りの大文字と小文字を区別する完全一致の名前です。JSON の値は文字列の配列です。allowedTools は、コアおよび有効な機能に名前付きツールを追加します。制限付きの許可リストではありません。たとえば、browser_pdf_save を許可してもナビゲーションやアクセシビリティ監査が無効になるわけではなく、browser_install を許可すると --caps install がなくてもブラウザーのダウンロードが明示的に有効になります。リストを省略すると、既存の公開設定が維持されます。

blockedTools は、コアツール、機能、allowedTools より優先されます。ブロックされたツールは tools/list に表示されず、事前に一覧表示されていなくても、またリクエストでブラウザーセッションが指定されていても、tools/call で拒否されます。初期化時に送信されるサーバーの指示では、ブロックされたツールの推奨が停止されるため、クライアントが拒否される呼び出しに誘導されることはありません。ブロックされたツールが、開いているモーダルを閉じるツール(browser_handle_dialog または browser_file_upload)の場合、モーダル状態に関するガイダンスではそのツールがブロックされていることを示し、次の手段として案内しません。ほかのツールは、モーダルが開いている間は引き続き拒否されます。このポリシーは、stdio と HTTP の両方で、スタンドアロン、CDP、拡張機能、プロバイダー切り替え、VS Code の各バックエンドに適用されます。browser_session_open、browser_session_close、アクセシビリティツール、プロキシが所有する browser_connect も例外ではありません。ツールを許可しても、プロバイダーの制限を回避したり、接続モードを有効にしたりすることはできません。browser_connect を使用するには、引き続きそのツールを提供するモードが必要です。

優先順位は、各リストについて個別にCLI > 環境変数 > 設定ファイルです。優先順位の高いリストが低いリストを置き換えます。リストは結合されません。JSON の []、--blocked-tools=、または空の環境変数値を指定すると、そのリストが明示的にクリアされます(allowedTools も同様です)。空のリストは何も追加もブロックもしません。重複があっても問題ありません。空でないリスト内の空の項目、配列以外の JSON 値、不明な名前(生成された webmcp_* ページツール名を含む)、ワイルドカードがある場合、起動時にエラーになります。

ページが提供する WebMCP ツールは、デフォルトで引き続き検出可能であり、このポリシーの対象外です。生成される webmcp_<name>_<identity> という名前は、サーバーの各実行、ドキュメント、登録ごとに生成される識別子をハッシュ化するため、tools/list からコピーした名前は、再起動後やナビゲーション後には一致しません。適用できない値を受け入れるのではなく、起動時に、ほかの不明な名前と同様に両方のリスト内の webmcp_* 名を拒否します。ページツールには既存のスコープと古さのチェックが引き続き適用されます。永続的なページアクションポリシーには安定した登録キーが必要ですが、これはこの機能には含まれません。

この設定が制御するのはツール名によるディスパッチであり、別のツールを介した同等の操作ではありません。たとえば、browser_click をブロックしても、browser_evaluate を介したページのクリックは防止されません。導入に関する決定を参照してください。

設定オプション

次のオプションを含む config.json ファイルを作成します。

{
  "browser": {
    "browserName": "chromium",
    "launchOptions": {
      "headless": true,
      "channel": "chrome"
    },
    "cdpLaunch": {
      "command": "open",
      "args": ["-a", "Slack", "--args", "--remote-debugging-port={port}"],
      "startupTimeoutMs": 30000
    }
  },
  "timeouts": {
    "navigationTimeout": 60000,
    "defaultTimeout": 5000,
    "settle": 500,
    "idle": 0
  },
  "network": {
    "allowedOrigins": ["example.com", "trusted-site.com"],
    "blockedOrigins": ["ads.example.com"]
  },
  "snapshot": {
    "boxes": true
  }
}

利用可能なオプション:

  • browser.browserName:使用するブラウザー(chromium、firefox、webkit) 固定バージョンの Playwright 1.63.0 で WebKit を使用すると、閉じた <details> の中にある開いた <details> の内容が表示されているものとして扱われます。この内容は browser_snapshot と browser_find の結果に表示され、browser_verify_element_visible と browser_verify_text_visible も成功します。Chromium と Firefox では、外側の <details> を開くまで内容は非表示になります。上流の修正 は、まだ安定版リリースに含まれていません。このサーバーは、スナップショットをフィルタリングしたり、この問題に対処するために Playwright にパッチを適用したりしません。検証メモをご覧ください。

  • browser.allowedUploadDirs:browser_file_upload と browser_drop で送信できるファイルを、これらのディレクトリ内の通常ファイル(解決後のシンボリックリンクのリンク先を含む)に制限します。制限付きのアップロードとドロップでは、検査済みのファイルハンドルを使用し、1 回の呼び出しにつき合計 50 MiB まで受け付けます。未設定の場合は、どのパスも許可されます。[] の場合は、すべてのファイルアップロードとドロップが拒否されます(テキストのみのドロップは引き続き機能します)。空白のリスト項目は拒否されます。CLI:--allowed-upload-dirs(セミコロン区切り。"" はすべて拒否)、環境変数:PLAYWRIGHT_MCP_ALLOWED_UPLOAD_DIRS(空文字列はすべて拒否)。

    リストは null ではなく配列でなければなりません。ルートは起動時に存在している必要があります。正規パスは一度だけ解決され、サーバーの稼働中は保持されるため、設定済みのシンボリックリンクのリンク先を変更しても、新しいツリーへのアクセスは許可されません。空でないアップロード許可リストを使用するには、/proc/self/fd が利用可能な macOS または Linux が必要です。macOS はファイルを開く際に祖先ディレクトリのシンボリックリンクをブロックし、Linux は開いたファイル記述子のパスを検査します。それ以外のプラットフォームでは、競合状態が発生しやすいパス名の検査に依存せず、制限付きのファイルアップロードとドロップを拒否します。制限なしのアップロード、すべて拒否するリスト、テキストのみのドロップは、すべてのプラットフォームで引き続き機能します。

  • browser.launchOptions.headless:ブラウザーをヘッドレスモードで実行します(デフォルト:ディスプレイのない Linux では true、それ以外では false)

  • browser.launchOptions.channel:ブラウザーチャネル(chrome、chrome-beta、msedge など)

  • browser.contextOptions.clientCertificates:クライアント証明書を使用する場合、browser.contextOptions.proxy で明示的に上書きしない限り、設定済みの起動プロキシも新しいコンテキストに適用されます。Playwright 1.63.0 は証明書インターセプターのプロキシバイパスルールを無視するため、証明書と空でない実効 proxy.bypass を組み合わせる設定は、起動前に拒否されます。リモートブラウザーで新しいコンテキストを作成する場合は、そのプロキシを明示的に設定してください。そのブラウザーからのみ継承されるプロキシは検査できません。既存のアタッチ済みコンテキストの設定は保持されます。

  • browser.launchOptions.proxy:ブラウザープロキシ(CLI:--proxy-server、--proxy-bypass、環境変数:PLAYWRIGHT_MCP_PROXY_SERVER、PLAYWRIGHT_MCP_PROXY_BYPASS)。http://user:password@myproxy:3128 のような CLI または環境変数のプロキシ URL に含まれる認証情報は、ブラウザーが 407 Proxy Authentication Required に応答できるよう、proxy.username と proxy.password に移されます。@、:、/ などの予約文字はパーセントエンコードしてください。設定ファイルで指定したプロキシでは、明示的な username フィールドと password フィールドが保持されます。 認証付きプロキシの認証情報漏えい: 固定バージョンの Playwright 1.63.0 では、プロキシの 407 チャレンジへの応答がキャッシュされた後にウェブサイトが 401 を返すと、プロキシの認証情報がウェブサイトの HTTP 認証として送信される可能性があります。これは、--proxy-server、PLAYWRIGHT_MCP_PROXY_SERVER、browser.launchOptions.proxy、browser.contextOptions.proxy を通じて指定された認証情報に影響します。上流の修正が含まれるリリースが採用されるまでは、認証付きプロキシを使用しないでください。2026 年 10 月 20 日時点で確認された最新の安定版リリースである Playwright 1.64.1 も、この修正より前のバージョンです。設定されたプロキシのいずれかに認証情報が含まれている場合、起動時に、設定解決ごとに認証情報を含まない警告が stderr に 1 回出力されます。これには、プログラムによる createConnection の使用も含まれます。この警告によって漏えいが防止されるわけではありません。認証なしのプロキシには変更はありません。接続済みブラウザーからのみ継承されたプロキシは、このサーバーでは検査も警告もできません。

  • browser.launchOptions.chromiumSandbox:Linux 上でダウンロードされた Chromium ビルドは setuid サンドボックスヘルパーを備えていないため、デフォルトは false です。それ以外の場合は true です。リモートエンドポイントと VS Code エンドポイントでは、リモートホスト上で設定されます。明示的な設定または PLAYWRIGHT_MCP_SANDBOX の値が優先されます。--no-sandbox は常に無効にします。

  • browser.cdpEndpoint:CDP を有効にした、すでに実行中の Chromium 系アプリに接続します。

  • browser.cdpHeaders:CDP 接続リクエストとともに送信する HTTP ヘッダーのマップです。ヘッダーベースの認証が必要なエンドポイントでは、たとえば { "Authorization": "Bearer <token>" } を指定します。

  • browser.cdpTimeout:CDP エンドポイントへの接続時に待機する最大時間(ミリ秒)です(デフォルト:30000)。

  • browser.cdpLaunch:CDP を有効にして Chromium 系デスクトップアプリを起動し、エンドポイントを待機して、子プロセスのライフサイクルを管理します。startupTimeoutMs(デフォルト:30000)は、アタッチの試行も含む待機全体の上限時間です。各試行の待機時間も browser.cdpTimeout が上限となります。

  • CDP アタッチモードでは、Playwright のデフォルト設定を適用せず、対象ブラウザーの既存のデフォルトコンテキスト設定を保持します。

  • browser.contextOptions.storageState:記録済みの Playwright ストレージ状態から、新しいコンテキストを開始します。既存の CDP コンテキストまたは VS Code コンテキストへのインポートは拒否されます。CDP の場合は --isolated を使用するか、対話形式でサインインしてください。ブラウザーがコンテキストを公開していない場合、サーバーはストレージ状態を使ってコンテキストを作成します。同じサーバーが作成したそのコンテキストに参加する CDP セッションは、リセットせずにそのライブ状態を引き継ぎます。

  • browser.profileDirName:拡張機能モードで使用する Chrome プロファイルディレクトリ名です。たとえば Default や Profile 1 を指定します(CLI:--profile-dir-name、環境変数:PLAYWRIGHT_MCP_PROFILE_DIR_NAME)。--user-data-dir と拡張機能モード(--extension または --connect-tool)が必要です。デフォルトでは、拡張機能がインストールされている最後に使用したプロファイルが選択されます。

  • timeouts.navigationTimeout:ページナビゲーションの最大時間(ミリ秒)です(デフォルト:60000)。

  • timeouts.defaultTimeout:Playwright 操作のデフォルトのタイムアウト時間(ミリ秒)です(デフォルト:5000)。

  • timeouts.settle:アクションのたびに、応答前にトリガーされた処理が落ち着くまで待機する時間です(デフォルト:500)。静かに完了するアクションでは、スケジュール済みのネットワーク処理も settle の遅延前に待機できるよう、まず最大 100ms(または settle の遅延のうち短い方)監視します。

  • timeouts.idle:このアイドル時間(ミリ秒)が経過すると、デフォルトのブラウザーコンテキストを解放します(デフォルト:0、無効)。0 から 2147483647 までの整数を指定できます。

  • network.allowedOrigins:許可するオリジンのリストです(指定した場合、それ以外はすべてブロックされます)。

  • network.blockedOrigins:ブロックするオリジンのリストです。

  • snapshot.boxes:スナップショットに各要素のビューポート相対の境界ボックスを [box=x,y,width,height] として含めます(デフォルト:false、CLI:--snapshot-boxes、環境変数:PLAYWRIGHT_MCP_SNAPSHOT_BOXES=1)。

  • imageResponses:allow(デフォルト)はテキストと画像を返します。omit は画像を除外します。only は、画像を含む成功レスポンスからテキストを除外します。エラー、ブラウザーのライフサイクルに関する通知、画像を含まないレスポンス(全ページのスクリーンショットを含む)では、テキストが保持されます。構造化された結果とリソースリンクは常に保持されます。only モードでは、スクリーンショットの保存先パスを示すテキスト、生成コード、および付随するテキストのみの検出結果が除外されます。これらが必要な場合は allow を使用してください。対話モードでは、REPL がテキストのみを出力するため、only は拒否されます。その場合は allow または omit を使用してください。auto は従来の allow の別名です。CLI:--image-responses only、環境変数:PLAYWRIGHT_MCP_IMAGE_RESPONSES=only。優先順位:CLI、環境変数、設定ファイルの順です。

  • server.authToken:設定すると、Streamable HTTP リクエスト(--port)には Authorization: Bearer <token> が必要になり、指定がない場合は 401 が返されます(環境変数:PLAYWRIGHT_MCP_AUTH_TOKEN)。空または形式が不正なトークンを指定すると、起動時に失敗します。認証スキームでは大文字と小文字が区別されませんが、トークンは完全一致が必要です。Bearer 認証では通信は暗号化されません。認証付きのリスナーは、--host 127.0.0.1 のようにループバックにバインドしてください。リモートアクセスには TLS リバースプロキシを使用してください。出力されるクライアント設定には、シークレットをログに記録せず、ローカルで置き換えるヘッダーのプレースホルダーが含まれます。未設定の場合、認証なしでアクセスできます。

  • filePaths:スクリーンショット/PDF の結果、生成コード、レポートのメタデータ、注釈付きスクリーンショット、キーボード操作のスクリーンショット、ダウンロードの概要に含まれる出力パスを、相対パスまたは絶対パスで表示するための任意の設定です。相対パスは、クライアントのワークスペースや出力ディレクトリではなく、サーバーの作業ディレクトリを基準とします。ファイルへの書き込み、保存されたレポートの内容、絶対パスの file:// リソース URI は変更されません。省略すると従来の表示方法が維持されます。設定済みの相対出力ディレクトリでは相対パスが使用され、デフォルトの一時出力パスでは絶対パスが使用されます(上流の Playwright での相対パスのデフォルトとは異なります)。CLI:--file-paths absolute、環境変数:PLAYWRIGHT_MCP_FILE_PATHS=absolute。優先順位:CLI、環境変数、設定ファイルの順です。

  • outputDir:レポート、スクリーンショット、トレース、セッションログなどの出力ファイルを保存するディレクトリです(CLI:--output-dir、環境変数:PLAYWRIGHT_MCP_OUTPUT_DIR)。デフォルトでは、システムの一時フォルダー内に新しいディレクトリが作成されます。サーバー実行ごとに一度だけ解決されるため、その実行で生成されるすべての成果物が同じ場所に保存されます。出力先は常にサーバー設定で指定します。非推奨の MCP roots 機能(クライアントのワークスペースフォルダー)は参照されなくなりました。

  • redactUrlParams:値が空でない URL クエリ/フラグメントパラメーターの値を REDACTED として表示する、パラメーター名の任意の配列です(CLI:--redact-url-params code,access_token、環境変数:PLAYWRIGHT_MCP_REDACT_URL_PARAMS=code,access_token)。デフォルトでは URL パラメーターは非表示になりません。名前はキーをデコードせず、文字どおり、大文字と小文字を区別せずに照合されます。繰り返し出現するパラメーター、相対リンク、ハッシュルート内のクエリパラメーターも対象です。空の値と選択されていないパラメーターはそのまま保持されます。CLI は環境変数より優先され、環境変数は設定ファイルより優先されます。リストは統合されず、置き換えられます。JSON の []、または空の CLI/環境変数の値を指定すると、優先順位の低い設定のリストがクリアされます。配列以外の設定値、文字列以外の要素、空白のみの名前は、ブラウザーの起動前にエラーになります。出力や成果物を共有する前に、URL の非表示対象を確認してください。 CLI では、--cdp-launch-command、--cdp-launch-args、--cdp-launch-cwd、--cdp-launch-port、--cdp-launch-startup-timeout、--cdp-endpoint、--cdp-header(複数のヘッダーを指定する場合は繰り返します。例:--cdp-header "Authorization: Bearer <token>")、--cdp-timeoutも使用できます。CDP ヘッダーとタイムアウトは、環境変数PLAYWRIGHT_MCP_CDP_HEADERS(1 行につきName: Value形式のエントリを 1 つ)およびPLAYWRIGHT_MCP_CDP_TIMEOUTでも設定できます。

WebSocket の接続後に CDP へのアタッチがタイムアウトする場合、既存のタブが Playwright によるブラウザーの初期化を妨げている可能性があります。固定バージョンの Playwright 1.63.0 では、レンダラーのないタブ(レンダラーがクラッシュしたタブ、または Chrome のメモリセーバーによって破棄されたタブ)に応答が返されないため、そのタブが存在する間はアタッチできません(上流の修正、未リリース)。スリープ中または応答しないタブも処理を停滞させることがあります(上流の報告)。この場合、--cdp-endpointは--cdp-timeoutの経過後に失敗し、--cdp-launchは--cdp-launch-startup-timeoutの経過後に失敗します(各アタッチ試行も--cdp-timeoutで終了します)。エラーにはこの原因が示されます。--cdp-launchが停止するのは、起動したアプリケーションのみです。--cdp-endpointでは、試行時間に上限を設けるため、正の値を明示的に指定した--cdp-timeoutを使用してください。0を指定するとタイムアウトが無効になり、アタッチが永久に待機する可能性があります。該当するタブを自分で再読み込みまたは閉じるか、別の使い捨てブラウザーにアタッチしてください。noDefaultsと--isolatedを指定しても、既存のタブの初期化は省略されません。この問題を回避するために、サーバーがタブを閉じたり再読み込みしたり、Playwright の初期化を迂回したりすることはありません。検証メモを参照してください。

Playwright 1.63 は、戻る・進むキャッシュ(BFCache)の復元をサポートしていません。BFCache が有効なブラウザーにアタッチすると、戻る操作後に使用できない参照が返されたり、iframe の内容が欠落したりすることがあります。この問題は、完全な Chromium、Chrome、Edge で再現されています。自分で起動するブラウザーの場合は、アタッチする前に--disable-back-forward-cacheを指定してください。または、Playwright のデフォルトのフラグが維持される、サーバーの通常のブラウザー起動モードを使用してください。サーバーがアタッチ済みブラウザーのフラグを変更したり、戻る操作を再読み込みに置き換えたりすることはありません。上流メンテナーによる説明、Playwright の BFCache に関する制限、検証と再現コマンドを参照してください。

HTTP リスナーは、ループバックの別名、バインド先のワイルドカードではないアドレス、および設定済みのホスト名(--host、server.host、またはPLAYWRIGHT_MCP_HOST)に対するHostヘッダーを受け付けます。名前付きホストをバインドするには、サーバー上でそのホスト名がアドレスに解決される必要があります。それ以外のホスト名は引き続き禁止されます。ワイルドカードへのバインド(--host 0.0.0.0または--host ::)では、任意のホスト名やワイルドカードアドレス自体は許可されません。ループバックのホスト名を使うか、特定のホスト名またはアドレスにバインドしてください。Hostがない場合、または無効な場合は400を返します。許可されていないホストには403を返します。Originが指定されている場合は、HTTP を使用し、正規化されたHostのホスト名とポートに完全に一致する必要があります。HTTPS または異なるオーソリティには403を返します。これらのチェックはベアラートークン認証を使用する場合にも適用されます。この認証でも、リスナーをループバックにする必要があります。

リモートから HTTP にアクセスする場合は、TLS リバースプロキシを明示的に設定してください。たとえば、--host 127.0.0.1 --port 8931を使って MCP サーバーをバインドし、PLAYWRIGHT_MCP_AUTH_TOKENを設定した場合は、次のようになります。

  • 設定済みの公開ホスト名からの HTTPS 接続のみを受け付け、/mcp を http://127.0.0.1:8931/mcp に転送してください。
  • 上流の Host ヘッダーは公開ホスト名ではなく、127.0.0.1:8931 に設定してください。クライアントの Authorization ヘッダーは変更せずに転送し、認証されていないクライアントに共有トークンを挿入しないでください。
  • Origin を削除する前に、空でない値が明示的に許可した HTTPS オリジンのリスト(例:https://mcp.example.com)に含まれていない場合は拒否してください。ブラウザー以外のクライアントでは、Origin がない場合も許可してください。その後、上流への Origin を削除するか、http://127.0.0.1:8931 に書き換えてください。任意のオリジンを、先に検証せず削除してはいけません。
  • SSE ストリームではレスポンスのバッファリングを無効にしてください。異なるオリジンからのブラウザークライアントには、プロキシで範囲を限定した CORS ポリシーも必要です。

サーバーは、チェックを回避する目的で Forwarded や X-Forwarded-* を信頼しません。有効なベアラートークンがあっても、公開 Host または HTTPS の Origin を上流に保持すると 403 が返されます。

状態を持つ初期化を含め、予期しない HTTP リクエストのセットアップ失敗は、HTTP ステータス 500 の汎用エラーを返します。解析済みのレガシー JSON-RPC リクエストでは ID が保持され、バッチエラーでは通知が省略されます。通知のみの失敗では、レスポンス本文は空になります。初期化に失敗した場合や拒否された場合、未登録のバックエンドは破棄されます。リクエスト本文がまだ読み取られていない場合、またはレスポンスの送信がすでに始まっている場合は、接続を再利用可能なままにせず、閉じます。

呼び出し元が指定したスクリーンショット、PDF、検索結果、ページスキャンマトリックス、監査レポートのファイル名には、既存ファイルを上書きしないポリシーが適用されます。既存ファイルがある場合、上書きされずにツール呼び出しが失敗します。設定した名前がホスト間で一貫して動作するよう、Windows で予約されているベース名と、ピリオドまたはスペースで終わる名前は、すべてのプラットフォームで拒否されます。

ダウンロードの保存に失敗した場合、タブが閉じた後も含め、現在または次のレスポンスでツールエラーとして報告されます。失敗した項目は、保存済みファイルや進行中のダウンロードとして通知されません。サーバーは、レスポンス間で最大 20 件の長さが制限されたエラーメッセージを保持し、省略された件数があれば報告します。Playwright 1.63.0 で Chromium 系の完全なブラウザーを使用すると、永続プロファイルの再起動後にネイティブクラッシュが発生することが確認されています。エラー報告では、このネイティブクラッシュは修正されません。明示的な --isolated の指定は機能しますが、起動間でプロファイルは保持されません。認証に必要な場合は、記録済みのストレージ状態を使用してください。既存のプロファイルとブラウザーのデフォルト設定は保持されます。

アクション後の待機時間を変更するには、--timeout-settle または PLAYWRIGHT_MCP_TIMEOUT_SETTLE を使用してください。遅延した DOM のみの更新もレスポンスに含まれるよう、すべてのアクション後に適用されます。また、短い監視時間によってスケジュール済みのリクエストも検出され、その待機が完了してからこの遅延時間が適用されます。

--timeout-idle 300000、timeouts.idle、または PLAYWRIGHT_MCP_TIMEOUT_IDLE を使用すると、5 分間アイドル状態が続いた後にデフォルトのブラウザーを解放できます。共有コンテキストは、いずれかのクライアントが作業中である限り開いたままになります。アイドル時間の計測は、最後のツール呼び出しまたはダウンロードが完了した後に始まります。明示的な記録がある場合は、browser_stop_recording が完了するまでアイドルによる解放を防ぎます。パッシブな --save-session のキャプチャは対象外です。クリーンアップ時にトレースが確定されます。次にブラウザーツールを呼び出すと接続が再開され、再度移動して要素の参照を更新するよう促すメモが含まれます。接続済みの CDP、拡張機能、VS Code のブラウザーは切断されますが、外部のページは開いたままです。終了ツールやセッション管理ツールでは、アイドル状態のブラウザーは再起動されません。明示的な browser_session_open ハンドルには、個別の PLAYWRIGHT_MCP_BROWSER_SESSION_TTL_MS の動作が適用されます。値を 0 にするとこの機能は無効になります。空白の環境変数値では既存の設定は変更されません。

VS Code の browser_connect ツールでは、playwright または playwright-core ライブラリと、ループバック WebSocket URL のみが使用できます。リモートエンドポイントを許可するには、PLAYWRIGHT_MCP_VSCODE_ALLOW_REMOTE=1 を設定してください。その場合、エンドポイントには wss: を使用する必要があります。URL のユーザー情報に含まれる認証情報は拒否されます。

HTTP ハートビート

サーバーが --port を指定して実行されている場合、Streamable HTTP クライアントが任意のイベントストリームを開いた後に、MCP ハートビートの ping を送信します。POST のみを使用するクライアントは、サーバーから開始するリクエストを受信できないため、ハートビートなしで接続を維持します。既定のタイムアウトである 5000 ms を変更するには PLAYWRIGHT_MCP_PING_TIMEOUT_MS を設定します。0 または負の値を設定すると、ハートビートの ping が無効になります。ping に JSON-RPC の「method not found」エラーで応答するクライアントは、稼働中として扱われます。サーバーはそのセッションへのハートビートを停止し、セッションを閉じません。セッションが閉じられるのは、ping に応答しない場合(タイムアウト)またはトランスポート障害が発生した場合のみです。

initialize ハンドシェイクを行わないクライアント

MCP 2026-07-28 リビジョンのクライアントは、initialize ハンドシェイクを送信しなくなりました。--port を指定すると、このリビジョンのリクエスト単位の _meta エンベロープを含むリクエストは、2026-07-28 プロトコルでネイティブに処理されます。server/discover に応答するため、versionNegotiation: 'auto' を使用してネゴシエーションするクライアントや、2026-07-28 を固定するクライアントは直接接続できます。結果には resultType と SEP-2549 のキャッシュフィールドが含まれます。動的なブラウザツール一覧では、1 時間のキャッシュではなく、安全側の既定値 ttlMs: 0 が使用されます。また、SEP-2243 の標準ヘッダー(MCP-Protocol-Version、Mcp-Method、Mcp-Name)は、リクエスト本文に対して検証されます。古いハンドシェイクを行わないクライアント(エンベロープを含まない 2025 年頃のリクエスト)は、従来どおりステートレスに処理されます。

どちらの場合も、リクエストはハートビートの ping を受け取りません。また、サーバーがブラウザコンテキストを自ら作成するモードでは、各リクエストは新しい既定のブラウザーセッションで処理されます。既定の永続プロファイルでは、リクエストごとの既定のコンテキストは、明示的なブラウザーセッションと同様に、それぞれ専用の破棄可能なプロファイルで実行されます。そのため、ハンドシェイクを行わないリクエストを並行しても安定プロファイルを奪い合うことはなく、安定プロファイルのサインイン状態もそれらのリクエストからは見えません。一方、--isolated、リモートエンドポイント、分離 CDP モードでは、いずれにしてもリクエストごとに新しいコンテキストが作成されます。

1 つのライブブラウザーコンテキストを再利用するモードは例外です。--extension(および接続済みブラウザープロバイダーに切り替えられた browser_connect または VS Code セッション)と、--isolated を指定しない CDP アタッチでは、ハンドシェイクを行わないすべてのリクエストが同じ共有コンテキストで処理されるため、そのタブ、Cookie、ストレージはリクエスト間で保持されます。この共有が理由で、これらのモードでは browser_session_open も拒否されます(--vscode でセッションツールを提供する場合は例外です。セッションツールはホストのスコープに属し、切り替え後も既定のプロバイダーで実行されます。詳しくはブラウザーセッションツールを参照してください)。固定された --cdp-launch-port を指定した場合、一度に提供できる起動済みアプリケーションは 1 つだけです。そのため、別のリクエストのブラウザーコンテキストがまだ稼働中に 2 つ目のハンドシェイクを行わないリクエストが届くと、最初のリクエストのアプリケーションに黙ってアタッチするのではなく、明確なエラーを返して拒否されます。--user-data-dir を指定すると、ハンドシェイクを行わない各リクエストは、設定された 1 つのプロファイルでブラウザーを起動します。プロファイルの状態はリクエスト間で保持され、並行するリクエストはブラウザーのロックを奪い合い、「Browser is already in use」で失敗することがあります。

それ以外の場合、ハンドシェイクを行わないリクエスト間で保持する必要があるブラウザー状態は、明示的なブラウザーセッションに保存してください。あるリクエストで browser_session_open が発行する browserSessionId ハンドルは、後続のリクエストで解決できます(詳しくはブラウザーセッションツールを参照してください)。initialize を送信するクライアントでは、従来の Mcp-Session-Id セッションの動作は変わりません。既定の永続プロファイルモードで、このようなステートフルクライアントが複数同時に接続されると、最初のクライアントの既定のコンテキストが安定プロファイルを保持します。並行するクライアントの既定のコンテキストは、安定プロファイルが解放されるまで、安定プロファイルのサインイン状態を持たない専用の破棄可能なプロファイルで実行されます。「Browser is already in use」で失敗することはありません。

ログインが必要なページの監査

実際の監査対象の多くは、サインインしたユーザーにのみ表示されるページです。そこにアクセスする方法は 2 つあります。

インタラクティブなルート(セットアップ不要)

すべての手順を同じブラウザーセッションで行ってください。このセッション内では、audit_site は同じブラウザーコンテキストの一時タブでクロールするため、ブラウザーを操作している間に作成された Cookie とローカルストレージをクロールで利用できます。

1. browser_navigate to the login page
2. browser_fill_form / browser_click to sign in
3. browser_navigate to the first page you want audited
4. audit_site — the crawl inherits the session you just created

インタラクティブ CLI、stdio MCP、および初期化済みのステートフル HTTP 接続では、この一連の操作に既定のセッションを使用できます。ハンドシェイク不要の HTTP クライアントでは、まず browser_session_open を呼び出し、リクエストごとにコンテキストを作成するモードを使用する場合は、返された browserSessionId をすべてのナビゲーション、操作、スキャンの呼び出しに渡してください。そうしないと、次のリクエストで新しい既定コンテキストが開始され、ログイン状態とページの状態が失われます。--extension などの共有コンテキストモードと、分離されていない CDP アタッチでは browser_session_open は拒否されます。共有コンテキストまたはステートフル接続を使用してください。モードごとの動作については、ブラウザーセッションツールを参照してください。

既定の永続プロファイルでは、サーバーを再起動してもサインイン状態が維持されるため、通常は一度サインインするだけで済みます。既定のプロファイルはサーバーの作業ディレクトリにひも付けられているため、ワークスペースごとのサーバーがそれぞれ独自のサインイン状態を保持します。異なるワークスペースで起動したサーバー間で Cookie が共有されたり、同じプロファイルを取り合ったりすることはありません。

ログインフォームが先に進まない場合
  • 再レンダリング後に新しい browser_snapshot を取得し、現在のフィールド参照を使用してください。データを入力する前に、browser_wait_for でアプリケーション固有の準備完了メッセージを待ってください。
  • browser_fill_form と通常の browser_type は、Playwright の fill を使用します。アプリケーションで個別のキーイベントが必要な場合は、browser_type の text: "" でフィールドをクリアしてから、slowly: true を指定して browser_type を使用してください。ゆっくり入力すると文字が追加されます。既存の値はクリアされません。
  • スキャンの前に、認証済みページまたはアカウント固有の要素が表示されていることを確認してください。フィールドへの入力やクリックの成功は、ログイン成功の証明にはなりません。送信に失敗した場合は、browser_console_messages と browser_network_requests を確認してください。バグ報告でパスワード、トークン、非公開のレスポンス本文を共有しないでください。
  • Docker ではブラウザーはコンテナー内で実行されるため、localhost はホストではなくコンテナーを指します。そのコンテナーから到達可能なホストアドレスを使用し、開発サーバーがその特定のアドレスからの接続を受け入れるように設定してください。バインドアドレス、許可されたホスト、認証のオリジン/リダイレクト設定を確認してください。ホストチェックを無効にしたり、CORS の範囲を一律に広げたりしないでください。

DOM の値を直接設定するとアプリケーションのイベントハンドラーを迂回する場合があり、合成セッターも制御入力に対する一般的な解決策ではありません。標準的な操作でも問題が解決しない場合は、スキャナーのバージョン、ブラウザーモード、ツールの正確な引数(シークレットを削除したもの)、最小限のローカル再現手順を報告してください。

ストレージ状態を使う方法(繰り返し実行可能、CI に適しています)

Playwright の codegen でセッションを一度記録し、そのファイルをサーバーに渡します。

npx [email protected] codegen --save-storage=auth.json https://example.com/login

開いたブラウザーでサインインしてから閉じます。これで auth.json に Cookie とローカルストレージが保存されます。

CLI フラグ、環境変数、または設定ファイルでサーバーに渡します。

npx --allow-scripts=re2 mcp-accessibility-scanner --isolated --storage-state ./auth.json
PLAYWRIGHT_MCP_ISOLATED=true PLAYWRIGHT_MCP_STORAGE_STATE=./auth.json npx --allow-scripts=re2 mcp-accessibility-scanner
{
  "browser": {
    "isolated": true,
    "contextOptions": {
      "storageState": "./auth.json"
    }
  }
}

サポートされているすべてのモードで状態が処理されます。適用するか、拒否するかのいずれかです。

Playwright 1.63.0 の安全上の制限: 既存のコンテキストへのインポートは、ロールバック用のスナップショットを取得したり、ストレージをリセットしたりする前に拒否されます。このバージョンでは、以前アクセスしたオリジンのタブがすでに閉じていても、スナップショットの取得時にサービスワーカー経由で配信されるスクリプトが実行される可能性があります(上流の修正)。新しいコンテキストを使用するか、--storage-state を省略して対話的にサインインしてください。サービスワーカーは無効化されません。将来依存関係をアップグレードする際は、この制限を見直す前に、#218 のレコーダー/共有クライアントのチェックと、#224 の IndexedDB のチェックにも合格する必要があります。

IndexedDB スナップショットの制限: 固定された Playwright 1.63.0 と Chromium 153.0.8010.12 および Firefox 155.0 では、storageState({ indexedDB: true }) を使うと Map と Set の内容が失われます。newContext({ storageState }) と setStorageState() のどちらで復元しても、空の通常のオブジェクトになります。通常の JSON レコードは保持されます。新しいコンテキストを使えば既存のブラウザーデータは保護できますが、取得時にすでに失われた値は復元できません。上流の修正 はマージされていますが、この固定バージョンには含まれていません。既存のコンテキストへのインポートを再び許可する前に、各対応エンジンで両方の復元方法が Map/Set の型とエントリーを保持することを、インポート失敗後も含めて確認してください。実ブラウザーの回帰テスト tests/browser-failures.integration.test.ts では、インポートの拒否後に元の Map/Set レコードが保持されることと、分離された JSON の IndexedDB インポートが引き続き機能することを確認します。

  • 新しいコンテキストを使うモード(--isolated、リモートエンドポイントモード、または --isolated と組み合わせたどちらかの CDP モード):ストレージ状態を直接使ってコンテキストを作成します。
  • --storage-state を指定したデフォルトの永続プロファイルモード:セッションでは、状態から構築した新しい使い捨てプロファイルを使用します。このプロファイルはセッションごとに固有で、セッション終了時に削除されるため、記録した状態だけがセッションデータであることが保証されます(--storage-state を指定しない場合は、従来どおり通常の永続プロファイルを使用し、再起動後も保持されます)。起動時に開かれたページ(たとえば browser.launchOptions.args の URL で開かれたページ)は、状態が適用される前に空白の置き換えページへ移され、その後、置き換えページが同じ URL に移動します。これにより、実行中の匿名ページが記録された ID を上書きすることを防ぎ、スキャンがそのページの DOM を読み取ることもありません。また、--storage-state は --user-data-dir と併用できません(ユーザー指定のプロファイルには独自のセッションがあり、消去されないため、サーバーはこの組み合わせを拒否します)。
  • --isolated を指定しない CDP モードと VS Code プロバイダー:ブラウザーにすでにコンテキストがある場合、--storage-state は拒否されます。CDP モードで新しいコンテキストを作成するには --isolated を追加してください。それ以外の場合は状態を省略し、対話的にサインインしてください。ブラウザーにコンテキストがない場合、サーバーは状態を使ってコンテキストを作成します。同じサーバー作成コンテキストに接続する CDP セッションは、状態をリセットせず、そのライブ状態を引き継ぎます。
  • --extension(--isolated の有無を問いません):ストレージのインポートは一切拒否されます。すでに実行中のブラウザーを使うため、記録した状態を適用する目的で Cookie を消去することは許容できる副作用ではありません。そのため、サーバーはその処理を黙って実行するのではなく、起動を拒否します。この場合は、代わりに対話的にサインインしてください。永続プロファイルを使うと、再起動後もセッションが保持されます。
クロールによってセッションが失われないようにする

audit_site はデフォルトで logout|signout を除外しますが、多くのアプリケーションではこれだけでは不十分です。クロールを開始する前に、セッションを終了または変更するものをほかにも追加してください:

{
  "excludePathPatterns": ["logout|signout", "account/(close|delete)", "sessions/revoke", "/switch-(locale|account|org)"]
}

excludePathPatterns はデフォルトの設定を拡張するのではなく置き換えるため、リストには logout|signout も繰り返し指定してください。

セッション Cookie がそれでも消失した場合、audit_site は確信に満ちた誤った監査結果を報告するのではなく、そのことを知らせます。結果は WARNING: cookie(s) … disappeared while loading <url> という行で始まり、JSON レポートと構造化コンテンツの両方に sessionLosses リストが含まれます。このリストには、失われた Cookie ごとに、それを失ったページが記録されます。ここでいうページはリダイレクト後に到達したページであり、そのページの読み込みが完了しなかった場合も報告されます。失われた Cookie のいずれかがセッション Cookie だった場合、その時点以降にスキャンされたすべてのページは、サインアウトしたユーザーとして監査されています。問題の URL を除外し、再度サインインしてから再実行してください。

このチェックでは Cookie の値ではなく、クロール対象の URL がどの Cookie を持っているかを比較するため、ローテーションする CSRF トークンがセッションの消失として誤認されることはありません。ブラウザーが Cookie に明記された有効期限に従って削除した場合も、同じ理由で無視されます。Cloudflare の __cf_bm は30分で期限切れになるため、この扱いがなければ、それより長いクロールでは警告が表示されてしまいます。それ以外では、認証 Cookie とほかの Cookie を区別しようとはしません。Cookie のどれにも認証用であることを示す印は付いていないため、クロール開始時に存在していて後から失われた Cookie はすべて報告されます。監視は最初の消失で停止しません。各 Cookie は消失した URL で一度ずつ報告されるため、分析用 Cookie の早期の期限切れによって、後から発生したセッション Cookie の消失が隠れることはありません。クロール中に見つかった URL は、アクセスされる前に Cookie の追跡対象に加わるため、開始 URL より下のパス(たとえば /app)にスコープされたセッション Cookie も監視されます。

利用可能なツール

ページ登録型 WebMCP ツール

現在のページがサポート対象の WebMCP API を公開している場合、MCP tools/list には、組み込みツールとともに webmcp_<name>_<identity> としてそのツールが含まれます。PLAYWRIGHT_MCP_EXTENSION_TOKEN を指定せずに --extension モードを使用する場合、一覧表示によって拡張機能との接続が開始されることはありません。接続には承認が必要なためです。ページのツールは、ブラウザツールの呼び出しによって接続された後に一覧表示されます。また、ステートレス(ハンドシェイク不要)リクエストで一覧表示するには、トークンが必要です。返された名前を正確に使用してください。名前はブラウザーのセッション、フレーム/ドキュメント、登録ごとにスコープが設定されており、古い名前は別のアクションに振り替えられず、拒否されます。そのため、--allowed-tools / --blocked-tools では選択できません。ブラウザーのフラグやポリフィルは自動的にインストールされません。

明示的なブラウザーセッションでツールを検出または呼び出すには、tools/list と tools/call の両方で、そのハンドルをリクエストメタデータ(params._meta.browserSessionId)に指定してください。これは params.arguments とは別のもので、ページ定義の browserSessionId 引数と _meta 引数は変更されずに保持されます。ルーティングメタデータがない場合、検出と呼び出しにはデフォルトセッションが使用されます。検出時にセッションハンドルが列挙されることはありません。一覧表示が完了するかリクエストがキャンセルされるまで、セッションが閉じられたり期限切れになったりしないよう、一覧表示中はそのセッションが保持されます。

名前、説明、スキーマ、結果、ページエラーはすべて信頼できないものとして扱います。ページが読み取り専用だと主張していても、ページツールにはすべて保守的なアクション注釈が適用されます。呼び出しには上限時間が設定され、キャンセルも可能ですが、タイムアウトまたはキャンセルされたページのアクションが実行中のままの場合があります。むやみに再試行しないでください。ステートフル接続では、最後に一覧表示したスコープに対する変更通知が重複排除されて配信されます。ステートレスクライアントは結果をキャッシュせず、再度一覧表示してください。

ネイティブの Chromium WebMCP 呼び出しは、外部 CDP 接続を含め、Chromium 153 の JSON 文字列コントラクトと、Chromium 156 で検証されたオブジェクト入力コントラクトをサポートします。ブリッジは呼び出し前にネイティブメソッドのシグネチャからコントラクトを選択します。ページ提供の JavaScript シムでは、JSON 文字列の入力が維持されます。呼び出しエラーが発生しても、自動的に再試行されることはありません。

ステートフルプロキシは、保留中のツール一覧表示が返されるまで、カタログの変更をバッファリングします。一覧表示が完了する直前に届いた変更も対象となるため、更新通知は返されたカタログに続いて送信されます。

リクエスト例、検出の制限、検証コマンドについては、WebMCP の使用方法、制限、テストをご覧ください。ページ記述子は公開前に MCP SDK のツールスキーマ検証に合格し、入力スキーマは呼び出し引数を後で検証するバリデーターでコンパイルできる必要があります。pattern または patternProperties サブスキーマを定義するスキーマ、あるいはルート型として object 以外を宣言するスキーマは除外されます。format キーワードは通知されますが、検証はページ側に委ねられます。また、引数の検証は 500 ms 経過後に中断されます。一覧が空であっても、ページにツールがないことの証明にはなりません。サポート対象外、無効、またはタイムアウトした登録は除外されます。

組み込みツール

MCP サーバーは、包括的なブラウザー自動化ツールとアクセシビリティスキャンツールを提供します。

アクセシビリティの主要ツール
scan_page

Axe-core を使用して、現在のページの包括的なアクセシビリティスキャンを実行します。

パラメーター:

  • violationsTag:チェックする WCAG/違反タグの配列
  • includeIncomplete(デフォルトは true):Axe の「未完了」結果も報告します
  • maxNodesPerViolation(デフォルトは 10):ルールごとに報告するノードの詳細の上限です。出現回数の合計には、上限で切り詰められたサンプルではなく、重複排除されたすべての検出結果が使用されます
  • includeSelectors / excludeSelectors:スキャン対象を絞り込む CSS セレクター
  • withRules / disableRules:実行するルールを絞り込む Axe ルール ID
  • annotateScreenshot(デフォルトは false):違反箇所を注釈付きでスクリーンショットに記録します 注釈付きスクリーンショット: annotateScreenshot が true の場合、違反している各要素が枠で囲まれ、違反したルール ID のラベルが付けられます。ページ全体の PNG が MCP 出力ディレクトリ(scan-page-annotated-{timestamp}-{token}.png)に書き込まれ、リソースリンクとして返されます。その後、マーカーが削除されるため、ページは元の状態のままです。マーカーは各要素のボックス内でクリップされる、フローの外側にあるオーバーレイに描画されるため、ページの再レイアウトは発生しません。オーバーレイにはスキャンごとに新しい ID が割り当てられ、ブラウザーのトップレイヤーに配置されるため、開いているダイアログ、ポップオーバー、全画面要素の上でも表示されます。また、CSS の zoom やスケールされた祖先要素を補正し、マーカーがレンダリング結果に正しく重なるようにします。 複数のルールに違反する要素には、すべてのルール ID を記載したボックスが 1 つ表示されます。また、開いているシャドウルート内の要素には、Axe が報告するシャドウパスをたどってマーカーが付けられます。 実行中のアニメーションは、要素の測定前に現在の時点で停止され、キャプチャ後に再開されるため、動いている要素にもマーカーを付けられます。マーカー自体はオーバーレイ配下のシャドウルート内に配置され、そのスタイルには !important が指定されているため、ページの CSS によってレポート対象の内容が再スタイルされたり非表示になったりすることはありません。また、各ルールのラベルはクリップされたボックスの外側に配置されるため、要素がラベル自体より小さくても読み取れます。 1 回のスキャンで注釈を付ける要素は最大 50 個です。結果テキストには、合計のうち何個のノードにマーカーを付けたかに加え、上限を超えた、非表示、サイズが 0、またはキャンバス外にあった(ページ全体のスクリーンショットはドキュメントのボックス内でクリップされます)、あるいは iframe 内にあった(クロスフレームセレクターはトップドキュメントから解決できません)ために対象外となった数が常に表示されます。

サポートされる違反タグ:

  • WCAG 規格(デフォルトのセット):wcag2a、wcag2aa、wcag2aaa、wcag21a、wcag21aa、wcag21aaa、wcag22a、wcag22aa、wcag22aaa
  • Section 508(デフォルトのセット):section508
  • カテゴリー(オプトイン):cat.aria、cat.color、cat.forms、cat.keyboard、cat.language、cat.name-role-value、cat.parsing、cat.semantics、cat.sensory-and-visual-cues、cat.structure、cat.tables、cat.text-alternatives、cat.time-and-media
  • 適合性以外のタグ(オプトイン):best-practice、experimental(下記の注意事項を参照してください。一部の実験的なルールには WCAG タグも付いており、デフォルトで実行されます)

デフォルトのセットは WCAG と Section 508 のタグのみであるため、デフォルトのレポートは「適合基準に違反している」ことを意味します。カテゴリータグがオプトインなのはこのためです。Axe は指定されたタグを OR 条件で照合するため、cat.keyboard を指定すると、region や skip-link など、両方のタグが付いたベストプラクティスのルールも対象になります。カテゴリータグを除外しても、現行の適合性ルールが失われることはありません。cat.* タグのみで対象となるルールは duplicate-id と duplicate-id-active だけで、WCAG が SC 4.1.1 を削除したため、Axe はこれらを非推奨としています。より広範なレビューを行う場合は、best-practice(ランドマーク構造、見出しの順序、tabindex の適切な使用)または cat.* タグを追加してください。

同じ OR 条件は experimental にも適用されますが、意図的な例外が 1 つあります。4 つの実験的なルール、すなわち css-orientation-lock(SC 1.3.4)、p-as-heading、table-fake-caption、および td-has-header(SC 1.3.1)にも wcag* タグが付いているため、デフォルトのセットで実行されます。Axe における experimental は、基準が実際に存在するかではなく、ヒューリスティックの確立度を示すため、これらのルールは除外されません。experimental タグを追加すると、適合性タグが付いていない残りの実験的なルールも対象になります。Axe 4.14 では、label-content-name-mismatch(SC 2.5.3)は実験的なルールとして扱われなくなりましたが、引き続きデフォルトで実行されます。 スキャン範囲の指定: scan_page、audit_site、scan_page_matrix では、includeSelectors と excludeSelectors を指定して、Axe の検査対象を絞り込めます。includeSelectors を使うと、1 つのコンポーネント(["#checkout-form"])を監査できます。また、excludeSelectors を使うと、すべてのレポートに混入するサードパーティー由来のノイズ(["#cookie-banner", "iframe.intercom-frame"])を除外できます。除外は包含の後に適用されるため、包含したサブツリーからウィジェットを除外できます。

セレクターはスキャンの開始前に解決されます:

  • 構文が無効な CSS を指定すると、セレクター名を示してスキャンが失敗します。
  • includeSelectors の項目に一致するものがない場合、スキャンは失敗します。Axe 単体では、一部にしか一致しない包含対象のセットを受け入れ、指定した範囲より狭い範囲をひそかにスキャンします。そのためスキャナーは、対象範囲の一部が欠けたまま問題がないように見えるレポートを返すのではなく、処理を拒否します。
  • excludeSelectors の項目に一致するものがない場合は、エラーではなく何も起こりません。クロールで、除外対象のウィジェットがないページにアクセスするのは正常なことです。

audit_site では、セレクターはクロール対象のすべてのページに適用されます。そのため、特定のページに存在しない includeSelectors の値があると、クロールは続行されますが、そのページはレポートでエラーとして示されます。リンクの検出はスキャンの前に行われるため、エラーになったページからのみ到達できるページもクロールされます。

ルール単位の制御: scan_page、audit_site、scan_page_matrix では、withRules と disableRules を指定して、タグセット全体ではなく Axe の個別ルールを選択できます。withRules を使うと、修正後に 1 つのルールを再チェック(["color-contrast"])できます。また、disableRules を使うと、すでにトリアージしたルールを無効化(["region"])できます。ルール ID は Axe が報告するもの(image-alt、color-contrast、…)です。Deque のルールリファレンスを参照してください。

  • withRules は violationsTag より優先されます。 Axe はルールリストとタグリストのどちらか一方だけを実行でき、両方は実行できません。そのため withRules が設定されている場合、タグは完全に無視されます。withRules: ["image-alt"] は、violationsTag の値にかかわらず、そのルールだけを実行します。ルール ID のほうがより具体的な指定であるため、優先されます。
  • disableRules は選択されたルールから指定のルールを差し引きます。 violationsTag と withRules のどちらにも適用されます。(明示的なルールリストを渡すと、Axe 自体は無効化されたルールを無視します。スキャナーは事前にそれらを差し引くため、2 つのオプションを併用しても個別に使っても、同じ意味になります。)withRules のすべてのルールを無効化すると、空のスキャンではなくエラーになります。
  • withRules を明示的に空にした場合もエラーになります。 withRules: [] はルールを何も選択しません。タグセットにひそかにフォールバックすると、要求とは異なるスキャンが実行されます。タグでスキャンする場合は、このオプションを省略してください。リストを動的に作成するクライアントでは、リストが空になった場合にキーを削除してください。
  • 不明なルール ID を指定すると、ID を示してスキャンが失敗します。 どちらのオプションも、ブラウザーにアクセスする前に Axe のルールカタログと照合されます。そのため、ページ内から後で frame.evaluate の失敗として表面化するのではなく、Unknown Axe rule id(s) in withRules: image-altt と報告されます。ルール ID は実行全体に適用されるため、audit_site と scan_page_matrix はページにアクセスする前に一度だけ ID を検証します。不正な ID があると、すべての URL をクロールしたり、ページを再読み込みして再エミュレートしたりしてから引数を拒否するのではなく、呼び出し全体が失敗します。

audit_site と scan_page_matrix は、レポートの JSON メタデータに両方の値を記録するため、保存済みのレポートからフルスキャンかどうかを判別できます。

未完了(「要確認」)の結果: Axe は、背景画像やグラデーション上のコントラスト、あいまいなラベル、完全には評価できなかった要素など、独自に判定できないチェックについて incomplete を返します。scan_page、audit_site、scan_page_matrix では、これらを違反とは別のセクションに報告します。ページ(スクリーンショット、スナップショット、browser_evaluate)を確認して解決できます。詳細な検出結果を抑制するには、includeIncomplete: false を設定してください。マトリックススキャンでは、これによって以下で説明する比較の妥当性チェックが無効になることはありません。 スキャンできなかったフレーム: スキャンの実行前に、Axe はページのすべてのフレームにインストールされます。インジェクション中に遷移するフレームや、レンダラーが1秒以内に応答しないフレームは対象から外され、その内容からは検出結果が得られません。これを問題のない結果として扱わないよう、3つすべてのスキャンツールが、フレームの URL を列挙した WARNING: Axe could not be installed in N frame(s) ブロックを出力します。また、audit_site と scan_page_matrix は、JSON レポート(unscannedFrames)と structuredContent に、ページごとおよびバリアントごとにそれらのフレームを記録します。読み込み中だったフレームは再実行で成功することが多く、繰り返し失敗するフレームは個別に監査する必要があります。

上位のフレームのいずれかがスキャンされなかった場合は、ネストされたフレーム自体へのインジェクションが成功していても、そのフレームは報告されます。Axe は上位のフレームを経由してのみネストされたドキュメントに到達できるため、外側のフレームに Axe がなければ、その下のすべてがスキャン対象から外れます。

自分でスコープから除外したフレームは報告されません。excludeSelectors: ["iframe.intercom-frame"] を指定した場合、そのウィジェットの読み込み失敗は、スキャンの抜けではなく、指定したとおりの結果です。スコープはフレームチェーン全体とシャドウ境界をまたいで解決されるため、祖先を指定する includeSelectors の項目は、数階層下やシャドウルート内にネストされたフレームにも適用されます。また、外側のフレームやシャドウホストを除外すると、その内部のすべてが対象外になります。チェックで解決できないものは、隠されずに報告されます。

監査ツール
audit_site

複数の内部ページをクロールしてスキャンし、サイト全体の違反を集計します。

  • デフォルトの戦略:現在のURLを起点とするリンクベースのBFS
  • links、nav、sitemap、provided のURL戦略をサポートします
  • サイトマップのURLとすべてのリダイレクト先は、サーバーのネットワークポリシーとクロール範囲を満たす必要があります。フェッチはMCPホスト上で実行され、ブラウザーのCookieや認証ヘッダーを使わず、HTTP(S)を使用します。合計タイムアウトは15秒、リダイレクト上限は20回、レスポンスサイズ上限は10 MiBです。この戦略では、ブラウザーのプロキシ設定、browser.remoteEndpoint、browser.cdpEndpoint(リモートブラウザーへのトンネルとなる可能性のあるループバックエンドポイントを含む)、および切り替えられたbrowser_connectプロバイダーは拒否されます。これらのモードではprovided URLを使用してください。ブラウザーのHTTPSエラーを無視する設定でも、サイトマップのTLS証明書は有効でなければなりません。
  • 常にJSONレポートを書き出します(デフォルトのファイル名:audit-site-{timestamp}-{token}.json)。ページごとのsummary.totalNodes、byImpact、byRuleIdは、重複を除いたすべての違反ノードをカウントします。maxNodesPerViolationは、保存するノードの詳細のみを制限します。
  • ブラウザーのナビゲーションが落ち着いた後、到達したURLをHTTP(S)、sameOriginOnly、includeSubdomains、excludePathPatternsに照らして再確認します。遷移先がその範囲外の場合、要求されたURLと到達したURLを示すページエラーとして記録され、スキャンやリンク検出には使用されません。クロールは続行されます。これはナビゲーション後の確認であり、ネットワークリクエストをブロックするものではありません。リダイレクト先にはすでに接続され、セッションの状態が変化している可能性があります。
  • 監査中のページでalert、confirm、promptが開くと、ダイアログが開いた時点で、そのページはエラーページとして報告され、errorにはダイアログ名が記載されます。リダイレクトせずにドキュメントを読み込む終端HTTP 3xxページ(例:Locationのない300や302)も対象です。クロールがダイアログに応答することはありません。そのページのタブを閉じ、次のURLを新しいタブで開いて続行するため、このようなページが後続ページの失敗や停止を引き起こすことはありません。クロールがすでにページから移動中に前のページが開いたダイアログは、次のページの責任とはみなされません。次のページは新しいタブで改めて監査されます。同一ドキュメント内の履歴更新は、URLが完全に同じままの場合も含め、次のページの読み込みとはみなされません。新しいタブには前のタブのsessionStorageが引き継がれないため、その場合は結果の冒頭にWARNING: … continued in a fresh tab from <url>という行が追加され、JSONレポートと構造化コンテンツの両方にcrawlTabRestartsリストが含まれます。サイトがセッションをsessionStorageに保存している場合、そのURL以降のページは別のセッションで監査された可能性があります。このツールを呼び出したタブには影響しません。
  • クロール開始時に存在したCookieが失われた場合、警告を出し、sessionLossesに記録します。詳しくはログイン後のページの監査をご覧ください。ブラウザー内部のエラーページでナビゲーションに失敗した場合、警告には要求されたURLが記載されます。

実行例:

1. Navigate to your site homepage with browser_navigate
2. Run audit_site with maxPages: 25 and maxDepth: 2
3. Review the report path returned by the tool (written to the MCP output directory)
scan_page_matrix

同じページに対して、ビューポート/メディア/ズームの各バリエーションで Axe スキャンを実行し、ベースラインとの差分を比較します。

  • デフォルトのバリエーション:baseline、mobile、desktop、forced-colors、reduced-motion、zoom-200
  • カスタムバリエーションと、バリエーション間で任意に再読み込みする機能に対応しています
  • 常に JSON レポートを出力します(デフォルトのファイル名:scan-matrix-{timestamp}-{token}.json)
  • JSON レポートと構造化結果スキーマ v2 では、いずれかのスキャンで未スキャンのフレームが残っている場合、またはどちらかの側で違反として記録されたルールに、どちらかの側で不完全な結果もある場合、ベースラインとの差分を null に設定します。判定不能な結果は、違反が修正された、新たに発生した、または件数が変わったことを示す証拠にはなりません。
  • 各バリエーションの JSON と構造化出力には comparisonIncompleteRuleIds が含まれます。比較が不確実になるルール ID をソートした一覧です。不確実になるルールがない場合は [] です。テキストテーブルでは、フレームのカバレッジ不足とチェックの不完全さを区別します。これらの安全対策は includeIncomplete: false の場合も適用されます。このオプションで非表示になるのは詳細な検出結果であり、比較の有効性ではありません。
  • 無関係な不完全な結果のみを持つルールによって、確認済みの違反の比較が抑制されることはありません。同じルールに違反ノードと不完全なノードの両方がある場合、ベースラインとの自己比較も利用できません。
  • 概要の合計数とベースラインからの件数差分には、重複を除去したすべての違反ノードが使われます。一方、保存されるノード詳細は maxNodesPerViolation によって上限が設定されます。この上限を変更しても、発生件数の合計は変わりません。

実行例:

1. Navigate to a page state you want to validate
2. Run scan_page_matrix with defaults (or provide custom variants)
3. Review per-variant deltas and open the generated JSON report path
audit_keyboard

実用的なヒューリスティックを使い、Tab(および任意でShift+Tab)を押して、実際のキーボードフォーカスの動作を監査します。

  • スキップリンク、フォーカスの可視性、フォーカスの移動、およびフォーカストラップの可能性を確認します
  • ドキュメントをまたぐスキップリンクによるナビゲーション後に、元のURLに戻します。履歴エントリの増加が1件だけ観測された場合はBackを使用して、復元されたURLを確認します。それ以外の場合は、現在のエントリを元のURLに置き換えます。フラグメントへの移動、同一ドキュメント内での履歴変更、同じURLの再読み込みでは、以前の履歴エントリは消費されません。進む方向の履歴が切り詰められた場合やエントリが置き換えられた場合、復元時に監査対象ページが再読み込みされ、以前のドキュメントの状態は復元されないことがあります。
  • WCAG 2.2 SC 2.5.8に照らしてターゲットサイズを確認します(checkTargetSize、既定でオン)
  • フォーカスが完全に隠されていないことを確認します。WCAG 2.2 SC 2.4.11(checkFocusObscured、既定でオン)
  • 問題発生時のスクリーンショット(screenshotOnIssue)
  • 常にJSONレポートを書き出します(既定のファイル名:audit-keyboard-{timestamp}-{token}.json)

WCAG 2.2のチェックの制限 — これらはヒューリスティックであり、適合性の判定ではありません。

  • ターゲットサイズは、タブ順序で実際に到達する要素のみを検査するため、ポインターでしか操作できないターゲットは測定されません。
  • SC 2.5.8の例外のうち評価対象となるのは、間隔(ターゲットを中心とした直径24pxの円が、別のターゲットのボックスにも、サイズ不足の別のターゲットの円にも届かないこと)と、インライン(周囲の文章内にあるインラインレベルのターゲット — inline、inline-block、inline-flexなど。<strong>などのインラインラッパーをたどって包含ブロックまで確認します)のみです。ユーザーエージェントのコントロール、必須、同等の例外はDOMから検出できないため、これらの例外に該当するターゲットも報告され、手動でのトリアージが必要です。
  • 間隔の近隣要素には、フォーカスされた要素と同じポインターターゲットのルールを適用するため、描画される:disabledコントロールは近隣要素として数えられず、contenteditable領域は両側のターゲットとして数えられます。
  • ターゲットサイズは要素のバウンディングボックスを使用するため、複数行に折り返されるインラインターゲットは行ごとではなく結合した1つのボックスとして測定され、overflowまたはclip-pathを持つ祖先によって表示領域が狭められたターゲットも、クリップされていない全体のサイズで測定されます。
  • SC 2.4.11は最低限のレベル(AA)です。フォーカスされた要素のボックス上でサンプリングされたすべての点がほかのコンテンツに覆われている場合にのみ、その要素が報告されます。一部が覆われているフォーカスはここでは合格となり、より厳しいSC 2.4.12(AAA)はチェックされません。これは、iframeなどのポインターターゲットではない要素を含め、描画されたボックスを持つすべてのフォーカス停止位置に適用されます。
  • 被覆状況は、サンプル点のヒットテストを行い、ヒットした要素が実際に描画されていること(可視であること、フォーカスされた要素と最初に共通するラッパーまで不透明度が0でないこと、不透明でない背景色または背景画像を持つこと)を確認して測定します。そのため、透明でクリックを捕捉するオーバーレイは遮蔽として数えられません。一方、pointer-events: noneを持つ被覆レイヤーはヒットテストで返されず、検出されません。コンテンツを判読できる状態で残す半透明のオーバーレイは報告されます。

フローの例:

1. Navigate to the target page and let it fully load
2. Run audit_keyboard with maxTabs: 50
3. Review focus findings and open the generated JSON report path
audit_screen_reader

ブラウザーのアクセシビリティツリー(page.ariaSnapshot)、アクセシブルな名前、および要素のジオメトリを調べ、アクセシビリティ上の問題の可能性を確認します。実際のスクリーンリーダーはインストールも操作もされず、その読み上げや操作もテストされません。 チェック(checkNames)

  • missing-accessible-name:アクセス可能な名前がない状態で公開されているコントロールや画像(WCAG 4.1.2)
  • uninformative-accessible-name:「ここをクリック」「続きを読む」「画像」など、文脈から切り離すと意味がわからない名前(WCAG 2.4.4)
  • filename-as-accessible-name:ファイル名を代替テキストとして使っている画像。例:IMG_1234.jpg、DSC00123(WCAG 1.1.1)。チェック対象は画像のみです。ダウンロードするファイル名(logo.png)がリンクやボタンの名前になっていても問題ありません。
  • label-in-name-mismatch:アクセス可能な名前に表示ラベルが含まれておらず、音声コントロールに支障がある状態(WCAG 2.5.3)。<input type="submit|button|reset"> の表示ラベルは value から取得し、Web コンポーネントのラベルは開いたシャドウルートから取得します。
  • duplicate-accessible-name:同じ名前を持ち、異なる URL に移動する兄弟リンク(WCAG 2.4.4)

名前の比較では、正規的に等価な Unicode テキストを正規化するため、Café のような合成済み表記と分解表記は一貫して扱われます。

チェック(checkReadingOrder)

  • reading-order-mismatch:アクセシビリティツリーの順序(読み上げられる順序)と視覚上の位置が一致しない状態(WCAG 1.3.2)。例:order、flex-direction: row-reverse、絶対配置

意図的に検出しないもの

  • 読み上げ順序を比較するのは、単一の行または単一の列を形成する兄弟要素間のみです。実質的に二次元のレイアウト(グリッド、CSS の段組み、折り返しのあるフレックス)には正しい単一の線形順序がないため、推測せずにスキップします。
  • テキストを表示しない要素、aria-hidden が設定された要素、フロート要素、position: fixed の要素、キャンバス外の要素、または 1px にクリップされた要素は、読み上げ順序の比較から除外されます。設計上、これらの視覚上の位置はソース順序と一致しないためです。許容範囲:比較する軸上でボックスが完全に離れている場合(1px)に限り、順序が入れ替わっていると判断します。また、右から左に読むコンテナーは右から左へ比較します。
  • 重複する名前は、リンク先が異なり、かつ判別可能な場合にのみ報告されます。現時点では、解決済みのリンク URL がその対象です(/help と https://site/help は同じリンク先です)。1つのフォームにある Save という名前の送信ボタンが2つあっても、公開されているツリーから異なる動作をするかどうかわからないため、曖昧とは判定しません。
  • AI スナップショットで ref が割り当てられている要素のみを解析します。Playwright が ref を割り当てるのは、表示されていてポインターイベントを受け取る要素です。そのため、通知はされるものの操作できないコントロール(pointer-events: none、一部のキャンバス外ウィジェットなど)はスキップされます。ref がなければ測定できず、aria-hidden の状態も、修正用のセレクターも特定できません。報告しても、装飾目的の aria-hidden アイコンが大半を占めることになります。
  • 見出しレベルやランドマーク構造はチェックしません。これらは axe がすでに報告するため(heading-order、region、landmark-one-main)、scan_page を使用してください。
  • 名前に関する検出結果は、link-name、button-name、image-alt などの axe ルールと重複します。このツールは、axe では判定できない品質チェック(汎用的な名前、ファイル名、名前に含まれるラベル、重複)を追加します。
  • ページを現在の表示状態で報告します。折りたたまれたパネルの背後にあるコンテンツや、別のビューポートにあるコンテンツは、その状態に基づいて判定されます。 名前の測定方法: AI スナップショットでは、コントロールのレンダリングされた子要素が持つ名前(<a><strong>Docs</strong></a>、ラベルが <span> 内にあるボタンなど)が省略されます。そのため、監査では測定対象の各フレームに axe-core のコピーを独自にインストールし、そのフレーム内で axe が計算したアクセシブルネームを取得します。ページ独自の window.axe が存在する場合も、そのまま変更しません。インストールには時間制限があります(メインフレームは 10 秒、子フレームはそれぞれ 1 秒)。コピーのインストールを拒否するフレーム(CSP によるブロックや、ページがコピーを削除する場合)は、名前を測定せずに評価します。その場合は、WARNING: accessible names could not be measured for N of these という行、構造化サマリーの elementsWithoutMeasuredName、および JSON レポートの elements.unmeasuredNames でその旨が示されます。これらのフレームでは、スナップショット独自の名前がそのまま使われます。これには / や /docs/ のようなスラッシュ区切りの名前も含まれるため、子要素を通じてのみ名前が付けられたコントロールに対する missing-accessible-name の指摘は、誤検出の可能性があります。測定できなかった名前の数がゼロでない場合、その実行での名前に関する指摘は部分的なものとして扱い、手動で確認してください。タイムアウトしたり応答を停止したりしたフレームは、どのチェックでも評価されず、その要素は unresolved としてカウントされます(その旨の警告も表示されます)。評価済みの要素がなくなった場合、監査は問題なしと報告せず失敗します。各フレームの読み取りには同じ時間制限(メインフレームは 10 秒、子フレームは 1 秒)が適用されます(どのフレームが要素を所有しているかを特定する検索には、より長い時間制限が適用されます)。そのため、応答を停止したフレームが監査を停止させることはありません。監査が重複して実行されても、ページあたり同時に実行中のフレーム操作は最大 4 件です。タイムアウトした操作が 4 件実行中の場合、それ以上のフレーム処理は開始されず、測定が停止した箇所が結果に示されます。

上限: maxElements(デフォルトは 400)は、スクリーンリーダーから到達可能なアクセシビリティツリー要素のうち、解析する数の上限です。スナップショットにはチェックで報告されない aria-hidden サブツリーの参照も含まれるため、到達可能な要素が上限に達するまで、測定はそれらを超えて続行されます(測定数は maxElements の 2 倍を上限とするため、非表示の参照が大半を占めるページでも処理量に上限があります)。maxFindingsPerCheck(デフォルトは 20)は、チェックごとに一覧表示する指摘の上限です。どちらの上限に達した場合も、サマリーと JSON レポートにその旨が記載され、常に全件数が報告されます。JSON レポートは必ず書き出されます(デフォルトのファイル名:audit-screen-reader-{timestamp}-{token}.json)。

実行例:

1. Navigate to the target page and let it fully load
2. Run audit_screen_reader (optionally raise maxElements for a large page)
3. Review the accessibility findings and open the generated JSON report path
ナビゲーションツール
browser_navigate

URL に移動します。

  • パラメーター:url(文字列)
  • メインドキュメントの 2xx 以外のレスポンスは、ページ状態に HTTP status の行として表示されます。
  • 読み込み中にページがダイアログを開いた場合、ナビゲーションは保留中のダイアログを返します。browser_handle_dialog を使って解決してください。ダイアログは自動的に閉じられず、中断されたレスポンスには page.goto の再生用スニペットも含まれません。モーダルがすでに開いている状態でナビゲーションを試みると、操作方法の案内とともに失敗します。中断されたナビゲーションが後から失敗した場合、ドキュメントが変更されていなければ、エラーはページのコンソールメッセージに表示されます。
browser_navigate_back

前のページに戻ります。

  • ページが beforeunload ダイアログを開いた場合、ツールはダイアログを閉じずに保留中のダイアログを返します。browser_handle_dialog を使ってページを離れる操作を許可するか、ダイアログを閉じてページにとどまるまで、ナビゲーションは保留されます。ダイアログが開いている間、レスポンスには page.goBack の再生用スニペットが含まれません。後からナビゲーションが失敗した場合、ドキュメントが変更されていなければ、エラーはページのコンソールメッセージに表示されます。
browser_navigation_timeout

既存のタブのデフォルトのナビゲーションタイムアウトを設定します。

  • パラメーター:timeout(ミリ秒、30000~300000)
browser_default_timeout

既存のタブのデフォルトの操作タイムアウトを設定します。

  • パラメーター:timeout(ミリ秒、30000~300000)
ページ操作ツール
browser_snapshot

現在のページのアクセシビリティスナップショットを取得します(分析にはスクリーンショットより適しています)。 スナップショット出力内の大きな data: URL ペイロードは、メディアタイプのプレフィックスまでに切り詰められます。 AI スナップショットでは、視覚的に表示されているもののアクセシビリティクエリから除外されたサブツリーの境界要素に [aria-hidden] が付与されます。子孫要素には再度付与されません。

  • パラメーター:compress(任意のブール値、デフォルトは false)、boxes(任意のブール値。この呼び出しでは snapshot.boxes を上書きします)
    • compress が true の場合、繰り返される構造パターンが 100 回を超えると、レンダリングされた応答内で、繰り返される非インタラクティブな ARIA スナップショットノードがまとめられます。各パターンの最初の 10 件は残されます。
    • 必要に応じて、browser_evaluate() を使用して、圧縮されていない全リストを取得します。
    • boxes が true の場合、各要素にビューポート相対の CSS ピクセル単位で [box=x,y,width,height] が含まれます。
browser_find

現在のページのアクセシビリティスナップショットを、スナップショット全体を返さずに検索します。

  • パラメーター:text(大文字と小文字を区別しない部分文字列)または regex(正規表現。/pattern/flags に対応)、maxResults(任意の正の整数。デフォルトではすべての一致)、filename(任意)
  • 一致したスナップショット行を前後のコンテキストとともに、ツリーのルートからのパスの下に表示します。... は、パス外のコンテキストが省略されていることを示します。
  • maxResults は、コンテキストウィンドウを作成する前に一致した行の先頭から選択し、祖先パスを保持します。コンテキストに追加の一致行が含まれる場合があります。切り詰められた場合、ヘッダーに一致件数の合計と (先頭から Y 件を表示) が記載されます。
  • filename を指定すると、同じテキスト(一致なしのメッセージや件数・切り詰めに関するヘッダーを含む)が、同じ maxResults 上限で保存されます。インラインの検索結果の代わりに Saved find results as <path> と text/plain リソースリンクが返されます。filename を指定しない場合、応答は変わりません。
  • ファイル名はこのサーバーのアーティファクトポリシーに従います。設定された出力ディレクトリ内に収まるよう名前がサニタイズされ、既存のファイルは拒否されます。上流の Playwright MCP とは異なり、パスはワークスペースのルートを基準に解決されません。
browser_click

Web ページの要素をクリックします。

  • パラメーター:element(説明)、ref(要素参照)、doubleClick(任意)
browser_type

編集可能な要素にテキストを入力します。

  • パラメーター:element、ref、text、submit(任意)、slowly(任意)
browser_hover

ページ上の要素にカーソルを合わせます。

  • パラメーター:element、ref
browser_drag

2 つの要素間でドラッグ&ドロップを実行します。

  • パラメーター:startElement、startRef、endElement、endRef
browser_drop

ページ内からドラッグを開始する操作が発生しないドロップゾーンをテストするため、要素上へのファイルまたはクリップボード形式のデータの外部ドラッグ&ドロップをシミュレートします。

  • パラメーター:element、ref、paths(任意の絶対ファイルパスの配列)、data(任意の MIME タイプと値のマップ。例:{"text/plain": "hello"})
  • paths または data の少なくとも一方が必要です。
  • 対象の dragover ハンドラーがペイロードを受け付けない場合は失敗します。
  • paths は、サーバーを実行しているマシンのファイルシステムから読み込まれます。これは browser_file_upload と同じ動作で、相対パスはサーバーの作業ディレクトリを基準に解決されます。browser_file_upload とは異なり、ファイル選択ダイアログを開く必要はありません。そのため、dragover ハンドラーのあるページであればどれでも対象になります。ローカルファイルの内容をページに渡せるツールとして扱ってください。
browser_select_option

ドロップダウンからオプションを選択します。

  • パラメーター:element、ref、values(配列)
browser_fill_form

1 回の呼び出しで複数のフィールドに入力します。生成された Playwright コードでは、実行した操作に合わせてチェックボックス/ラジオボタンのブール値が保持され、コンボボックスのオプションはラベルで選択されます。

  • パラメーター:fields(name、type、ref、value を含むオブジェクトの配列)
browser_press_key

キーボードのキーを押します。

  • パラメーター:key(例:'ArrowLeft' または 'a')
  • キーは Playwright の米国キーボードレイアウトで送信されます。固定されている Playwright 1.63.0 では、一部のテンキーキーの動作が物理キーボードと異なります。Chromium、Firefox、WebKit では、NumpadDecimal は Delete ではなく "\u0000" を送信します。また、macOS の WebKit では、この NUL 文字がフォーカス中の入力欄にも挿入されます(上流での修正は 1.63.0 の公開後にマージされており、安定版の固定バージョンには含まれていません)。Chromium のみ、テンキーの keyup イベントではテンキーの位置が報告されません(上流での修正は 1.63.0 の公開後にマージされています)。また、Shift+Numpad1 や Shift+NumpadDecimal など、Shift キーを押しながらテンキーを押しても何も入力されません。そのため、テンキーの key、location、または Shift キーを押したときの数字に依存するページでは、忠実なテストを実施できない可能性があります。サーバーはキーを再割り当てせず、そのまま渡します。物理的なテンキーのキーとしての識別より削除を優先する場合は、Delete を使用してください。tests/numpad-keys.integration.test.ts で特性を確認しているのは、測定済みのバージョン、ブラウザーのビルド、プラットフォームの組み合わせのみです。その他の環境では、意図したキーの動作を満たす必要があります。
browser_start_recording / browser_stop_recording

ブラウザー操作を記録し、Playwright JavaScript として返します。サーバーを --caps devtools で起動し、browser_start_recording を呼び出して操作を実行した後、browser_stop_recording を呼び出します。

複数タブの記録には、生成されたページエイリアスに必要な context.newPage() 宣言が含まれます。 記録されたアサーションには、実行に必要な playwright/test の expect セットアップが含まれます。

ハンドシェイクを行わない HTTP クライアントでは、最初に browser_session_open を呼び出し、その browserSessionId を両方の記録ツールに渡す必要があります。これにより、リクエストをまたいで記録を維持できます。--extension や分離されていない CDP 接続など、個別のブラウザーセッションを開けないモードで記録するには、状態を保持する MCP 接続が必要です。

browser_evaluate

ページ上、または ref が指定されている場合は特定の要素上で JavaScript 式を評価します。関数の戻り値はシリアライズされ、結果として返されます。

  • パラメーター:function(例:() => document.title または (element) => element.textContent)、element(省略可)、ref(省略可)
  • element と ref は、両方を指定するか、どちらも指定しない必要があります。一方だけを指定すると拒否されます。
  • 式だけを指定することもでき、自動的にラップされます。たとえば、document.title は () => document.title と同様に動作し、element と ref の両方が指定されている場合、element.textContent は (element) => element.textContent と同様に動作します。パラメーター名は常に element です。
  • 入力が関数か式かは、評価結果ではなくソース形式に基づいて判定されます。そのため、window.open のような式は呼び出されず、そのまま返されます。
スクリーンショットとビジュアルツール
browser_take_screenshot

現在のページのスクリーンショットを撮影します。

  • パラメーター:filename(省略可)、type(png、jpeg、または webp)、scale(css または device、デフォルトは css)、fullPage(省略可)、element/ref のペア(要素のスクリーンショット用)
  • scale: device は、デバイスピクセルを使用して高解像度のスクリーンショットを撮影します(デバイスピクセル比を考慮します)。scale: css は、画像のサイズを CSS ピクセルに合わせます。
  • キャプチャが空の場合はエラーとなり、自動生成されたファイルも含め、出力ファイルは削除されます。要求された形式が黙って変更されることはありません。WebP のキャプチャが空の場合は、サイズを小さくするか、PNG/JPEG を明示的に指定してください。
browser_pdf_save

ページを PDF として保存します。

  • パラメーター:filename(省略可。デフォルトは page-{timestamp}-{token}.pdf)

このツールを有効にするには、--caps pdf または --allowed-tools browser_pdf_save を指定します。

browser_install

設定されたブラウザーエンジンをインストールします(ブラウザーの実行ファイルが見つからない場合に使用します)。

  • パラメーター:なし
  • インストールが完了すると、タブが開いていない場合でも Browser <channel> installed successfully. と報告されます。

デフォルトでは無効です。サーバーの起動時に --caps install、PLAYWRIGHT_MCP_CAPS=install、または設定ファイルの "capabilities": ["install"] を指定して有効にします。--allowed-tools browser_install または allowedTools による完全一致でのオプトインにも対応しています。明示的な core-install 設定も非推奨のエイリアスとして引き続き使用できます。新しい設定では install を使用してください。このオプトインがない場合、ツールは一覧に表示されず、呼び出すこともできません。既存のブラウザーインストールは引き続き使用できます。

このツールはPlaywrightのインストーラーを実行し、実行可能コードをダウンロードします。Playwright 1.63.0では、ブラウザーのアーカイブは展開前にチェックサムや署名の検証を行いません。デフォルトのダウンロードホストではHTTPSが使用されます。カスタムの PLAYWRIGHT_DOWNLOAD_HOST、ブラウザー固有のホスト設定、TLS検査プロキシを含め、ダウンロード元とTLS設定を信頼できる場合にのみインストールを有効にしてください。TLS証明書の検証を無効にしないでください。

独立した検証済みバイナリが必要なデプロイでは、信頼できるデプロイプロセスを通じてブラウザーを用意し、--executable-path または既存のブラウザー接続を使用してください。この機能のオプトインによって制限されるのは、MCPによるインストールの呼び出しのみです。アーカイブの検証機能が追加されることも、手動、CI、Dockerビルドでのダウンロード方法が変更されることもありません。

ブラウザー管理
browser_close

ページを閉じます。

browser_resize

ブラウザーウィンドウのサイズを変更します。

  • パラメーター:width、height
browser_emulate_media

省略された機能はリセットせずに、現在のページでCSSメディア機能をエミュレートします。

  • パラメーター:colorScheme(light または dark)、reducedMotion(reduce または no-preference)、forcedColors(active または none)、contrast(more または no-preference)、media(screen または print)。少なくとも1つ指定してください。
タブ管理
browser_tabs

1つのツールでブラウザーのタブを管理します。

  • パラメーター:action(list、new、close、select)、省略可能な index(close と select 用)、省略可能な isolatedContext(上流の @playwright/mcp との互換性用)。
  • "default" のみ(または isolatedContext の省略)が受け付けられます。他の名前は無視されず、拒否されます。別のブラウザーコンテキストを使用する場合は、ブラウザーセッションツールを使い、browser_session_open を呼び出して返された browserSessionId を渡してください。
  • タブの作成中にブラウザーコンテキストが閉じると、リクエストは失敗します。遅れて作成されたページには、対象が閉じたかどうかを確認する制限付きの終了試行が行われます。応答しない対象によってシャットダウンが無期限に遅れることはありません。
ブラウザーセッションツール

MCP 2026-07-28のステートレス化の規定に従い、ブラウザーの状態は接続に暗黙的に保持する代わりに、サーバーが発行する明示的なハンドルで指定できます。2つのセッションツールを除くすべての組み込みブラウザーツールは省略可能な browserSessionId 引数を受け付けます。省略した場合、ツールはデフォルトのセッションで実行され、従来どおりに動作します。一方、動的な webmcp_* ツールは、上記の説明に従ってリクエストメタデータをルーティングに使用するため、ページ引数が上書きされることはありません。

browser_session_open

個別のブラウザーセッションを開きます。セッションごとに独自のブラウザーコンテキストとタブ、Cookie、ストレージを持ち、不透明なハンドル(bs_...)を結果テキストと structuredContent.browserSessionId の両方で返します。他のブラウザーツールの browserSessionId 引数にこのハンドルを渡すと、そのセッション内でツールを実行できます。

個別のコンテキストの提供方法はモードによって異なります。

  • デフォルトの永続プロファイルモード:各セッションは、それぞれ新しく使い捨てのプロファイルで実行されます(セッションの終了時または期限切れ時に削除されます)。デフォルトセッションのみ、安定した永続プロファイルを使用し、サインイン状態は再起動後も維持されます。これは必須です。1 つのプロファイルディレクトリで同時に実行できるブラウザーは 1 つだけです。
  • --isolated、リモートエンドポイント、および CDP/--cdp-launch と --isolated の組み合わせ:各セッションには、それぞれ新しいブラウザーコンテキストが割り当てられます。--cdp-launch モードでは、各コンテキストが、設定されたアプリケーションの独自のインスタンスを、それぞれ空いているポートで起動します。そのため、--cdp-launch-port と --isolated を組み合わせた場合も browser_session_open は拒否されます。固定されたポートで起動できるインスタンスは 1 つだけなので、2 つ目のセッションは、気付かれないまま最初のセッションのアプリケーションに接続されてしまいます。固定ポートで 2 つ目のブラウザーコンテキストを同時に起動した場合(並列クライアントからの場合など)も、最初のコンテキストのアプリケーションに接続されるのではなく、エラーで拒否されます。
  • 1 つのライブブラウザーコンテキストを再利用するモード(CDP 接続、--isolated を指定しない --cdp-launch、--extension、VS Code ブリッジ、およびカスタムコンテキストゲッターで作成されたサーバー)では、個別のコンテキストを作成できません。そのため、他のすべてと同じタブ、Cookie、ストレージを共有するハンドルを渡す代わりに、説明を添えて browser_session_open を拒否します。デフォルトモードで --user-data-dir によりすべてのブラウジングがユーザー指定の 1 つのプロファイルに固定されている場合も同様です。

--vscode でサービスを提供する場合、ブラウザーセッションはホストのスコープで管理されます。browser_session_open、browser_session_close、および browserSessionId を含むすべての呼び出しは、browser_connect によるプロバイダーの切り替えにかかわらず、常にホスト上のデフォルトプロバイダーのセッションレジストリに対して実行されます。切り替え前に開いたハンドルは、プロキシを VS Code 接続のブラウザーに切り替えた後も引き続き使用でき、閉じることもできます。切り替え中に開いたセッションはデフォルトプロバイダーによって作成されます。VS Code 接続のブラウザー自体は 1 つのライブコンテキストを再利用するため、個別のセッションをホストできません。セッション ID を含まないツール呼び出しのみ、切り替えに従います。

デフォルトプロバイダーに戻った後は、ツールを再度一覧表示して、利用可能なアクションを更新し、カタログ変更の通知を受け取ってください。以前のホストセッションのクライアントからの保留中の一覧表示で、そのサブスクリプションを置き換えることはできません。

browser_session_close

browser_session_open で開いたセッションを閉じ、ブラウザーリソースを解放します。

  • パラメーター:browserSessionId(閉じるセッションのハンドル)

そのセッションでツール呼び出しがまだ実行中の場合、ツールエラーが発生して閉じることはできません。呼び出しの途中でブラウザーを破棄すると実行中のツールが失敗するため、処理が完了するまで待ってから再試行してください。

セッションを閉じる際に保留中のダウンロードが失敗した場合、セッションが閉じられたことを示す確認とともに、ダウンロードエラーも応答に含まれます。そのセッションハンドルはすでに削除されています。

アイドル状態が30分続いたセッションは自動的に期限切れになります。タイマーは使用のたびに、またセッション内でツールが実行中の間も更新されます(並行する各呼び出しがカウントされるため、最後の呼び出しが完了するまでセッションは維持されます)。そのため、長時間の audit_site クロールが実行中に期限切れになることはありません。PLAYWRIGHT_MCP_BROWSER_SESSION_TTL_MS を設定すると、アイドル状態の TTL をミリ秒単位で変更できます(0 または負の値を指定すると期限切れが無効になります)。不明または期限切れのハンドルを渡すと、browser_session_open を参照するツールエラーが発生します。ハンドルはツール呼び出しをセッションにルーティングするベアラートークンであるため、このエラーには他の開いているセッションのハンドルは意図的に含まれません。--save-session を指定すると、ログに記録されるツール呼び出しには、ルーティング先の browserSessionId が記録されます(リクエストメタデータでルーティングされる webmcp_* 呼び出しの場合は、ページ引数を変更しないよう、別の Metadata ブロックに記録されます)。明示的なセッションで行われたユーザー操作も、ログに記録される引数に同じ browserSessionId が含まれるため、異なるセッションのエントリーを区別できます(デフォルトセッションのエントリーにはタグが付きません)。ハンドルはベアラートークンであるため、ログでは実際のハンドルを記録せず、そこから導出した固定の bs_redacted_<8 hex> ラベルとして記録します。これには browser_session_open のログ記録された結果も含まれます。

情報・モニタリングツール
browser_console_messages

ページからすべてのコンソールメッセージを返します。 コンソールメッセージ内の大きな data: URL ペイロードは、メディアタイプのプレフィックスまでに切り詰められます。

browser_network_requests

現在のリクエスト一覧を番号付きで返します。番号を指定すると、browser_network_request で個別のリクエストを調べられます。all: true を設定すると、現在のすべてのリクエストに加えて、以前の明示的な browser_navigate 呼び出しから保持されている最大200件のリクエストも含まれます。 リクエスト URL 内の大きな data: URL ペイロードは、メディアタイプのプレフィックスまでに切り詰められます。 リクエストが1件以上ある場合、末尾の行に browser_network_request への案内が表示されます。

browser_network_request

browser_network_requests の一覧にある 1 件のリクエストについて、認証情報を伏せたリクエスト/レスポンスヘッダーと本文のメタデータを返します。

  • パラメーター:index(いずれかの一覧に表示されるリクエスト ID)。ID はタブごとに 1 から始まり、そのタブの存続中に増加します。ナビゲーションや削除の後も振り直されたり再利用されたりすることはありません。そのため、現在の一覧は 1 より大きい ID から始まることがあり、欠番が含まれる場合もあります。
  • デフォルトでは、明示的な browser_navigate を実行すると一覧がリセットされます。以前と同様に、リンクのクリック、フォームの送信、history の呼び出しではリクエストが追加され続けます。all: true を指定すると、保持されている以前のリクエストも追加されます。詳細の参照では、デフォルトの一覧に表示されていなくても、保持されている ID を指定できます。最も古い履歴リクエストが削除された後、その ID は別のリクエストを示すのではなく、エラーを返します。タブを閉じるか破棄すると、両方の一覧がクリアされます。各タブとブラウザーセッションは、それぞれ独自の履歴と ID を持ちます。ID は、その ID を生成したタブ/セッションで使用してください。
  • サーバーの再起動やブラウザーセッションコンテキストの再作成後も ID が保持されることはありません。複数のリクエスト間でブラウザーの状態を保持する必要があるステートレスクライアントは、明示的なブラウザーセッションを使用してください。
  • 認証情報を含むヘッダー(authorization、proxy-authorization、cookie、set-cookie、x-api-key、x-auth-token)は <redacted, N characters> として報告されます。これにより、存在とサイズは確認できますが、秘密情報がトランスクリプトに含まれることはありません。その他すべてのヘッダーは、1 行ずつ完全な内容が報告されます。
  • リクエストとレスポンスの本文は、送信された認証情報や非公開の API データが含まれる可能性があるため、内容は返されません。空でない本文は <redacted, N bytes, mime/type>、空の本文は <empty> として報告されます。
  • レスポンスの受信後に失敗したリクエストでは、ステータスと失敗の両方が報告されます。
  • 読み取れなかったセクションは、呼び出し全体を失敗させるのではなく、その箇所に <headers unavailable: ...> または <body unavailable: ...> として報告されます。読み取りにはデフォルトのタイムアウトが適用されるため、ストリーミング中のレスポンスによってツールが停止することはありません。
URL のマスキング範囲

--redact-url-params code,access_token は、出力を見やすくするための任意設定であり、セキュリティ境界ではありません。上流の Playwright テキスト照合ポリシーに従い、?、&、または # の後に続く設定済みの名前がそのまま現れ、その後に = が続く場合、文章中を含むテキスト内のどこでも一致として扱われます。キーはデコードされないため、code は c%6Fde には一致しません。値は &、#、空白、引用符、不等号括弧、丸括弧、角括弧、バッククォート、またはバックスラッシュで終わります。これらの区切り文字以降の文字列は表示されたままです。たとえば、?code=first'tail は ?code=REDACTED'tail になります。パーセントエンコードされた値の文字は、通常のテキストと同様にマスキングされます。この機能では、あらゆるシークレットを検出したり、パーセントエンコードされた URL 全体の文字列をデコードしたりすることはできません。

REDACTED マーカーは URL で安全に使用でき、Markdown リンクや生成コード内でも問題ありません。パラメーターをマスキングしたコードスニペットを表示しても、実際に実行されたコードやブラウザーの URL は変更されませんが、元の認証情報を再現することはできなくなります。

対象有効時のポリシー
ページ/タブの URL、スナップショット、ネットワーク履歴/詳細、エラー、表示されるコードなど、MCP ツールの結果テキスト選択された URL 値をマスキング
構造化された結果コンテンツ文字列値を再帰的にマスキング。プロパティキー、数値、ブール値は変更なし
MCP の進行状況メッセージ、ツールリストのタイトル/説明表示テキストをマスキング。リクエストトークン、ツール名、入力スキーマは変更なし
--save-session の Markdown と関連するスナップショット YAML(レコーダーによる更新を含む)選択された URL 値をマスキング
未加工のアクセシビリティ JSON/HTML レポート、browser_find のファイルエクスポート、個別に保存されたコード変更なし
スクリーンショット、PDF、動画、トレース、ダウンロード、ストレージ状態、埋め込みリソース変更なし
リソースリンクオブジェクト/URI、ファイルの場所リンクを引き続き使用できるよう変更なし
ナビゲーション引数、実行中のブラウザー URL/リクエスト、拡張機能の接続引き継ぎ/Chrome 引数、起動/デバッグログ、初期化および JSON-RPC プロトコルエラー変更なし

この出力ポリシーは、スタンドアロン、CDP、拡張機能、プロバイダー切り替え、VS Code の MCP サーバー機能で適用されます。既存の認証情報ヘッダーとリクエスト/レスポンス本文のマスキングはこれとは独立しており、このオプションを指定しなくても引き続き有効です。除外対象の成果物を、サニタイズ済みであるかのように共有しないでください。別途インストールするブラウザー拡張機能の接続ページは、その拡張機能が管理します。このサーバーは、その外部 UI からトークンを削除したり、認証済みの接続引き継ぎを変更したりしません。

ユーティリティツール
browser_wait_for

テキストの表示/非表示、または指定時間の経過を待ちます。

  • パラメーター:time(任意)、text(任意)、textGone(任意)
  • time の単位は秒です。0 以上を指定する必要があり、上限は 30 秒です。0 は省略時と同じように扱われます。生成コードでは上限が適用された待機時間が使われます。時間のみを指定した場合の結果には秒数が示され、指定した待機時間が上限を超えていた場合はその旨も記載されます。
  • text と textGone の両方を指定した場合、どちらかが先に成立した時点(テキストが表示される、またはもう一方のテキストが消える)で呼び出しが完了し、どちらを待ったかが報告されます。もう一方の待機はキャンセルされ、生成コードでも同様に、負けた側をキャンセルする Promise.race として両方の待機が再現されます。
  • time を text または textGone と組み合わせた場合、別個の遅延としてではなく、これらの待機のタイムアウトとして(上限を適用して)使用されます。time のみを指定した場合は、引き続き指定時間だけ待機します。
browser_handle_dialog

ブラウザーのダイアログ(アラート、確認、プロンプト)を操作します。

  • パラメーター:accept(ブール値)、promptText(任意)
  • セッション外ですでにダイアログが閉じられていた場合(例:ヘッド付きブラウザーで手動で閉じた場合)、呼び出しは成功し、ダイアログがすでに閉じられていたことを報告して残存状態をクリアします。エラーにはなりません。
browser_file_upload

ページにファイルをアップロードします。

  • パラメーター:paths(絶対ファイルパスの配列)
  • setFiles に失敗した場合、ファイル選択ダイアログは次のアップロード試行に備えて開いたままになります。paths: [] を指定すると選択が解除され、ダイアログが完了します。アップロードに成功すると、そのファイル選択ダイアログのみが閉じ、ページのアクティビティと設定された安定待機時間が終わるまで待機します。
browser_verify_element_visible

ARIA ロール/名前で要素を検証します。

  • パラメーター:role、accessibleName
browser_verify_text_visible

テキストの表示状態を検証します。

  • パラメーター:text
browser_verify_list_visible

スナップショット参照でリスト項目を検証します。

  • パラメーター:element、ref、items(配列)
browser_verify_value

要素の値またはチェック状態を検証します。

  • パラメーター:type、element、ref、value

これらの検証ツールを有効にするには --caps verify を使用するか、--allowed-tools で個別の名前を指定します。

ビジョンモードのツール(座標ベースの操作)

これらのツールを有効にするには --caps vision を使用するか、--allowed-tools で個別の名前を指定します。

browser_mouse_move_xy

マウスを指定した座標に移動します。

  • パラメーター:element、x、y
browser_mouse_click_xy

指定した座標をクリックします。

  • パラメーター:element、x、y、button(任意:left/right/middle)、clickCount(任意)、delay(任意、マウスボタンを押してから離すまでの遅延、ミリ秒)
注意

座標ベースのツールでは、権限チェックのために element の説明が必要ですが、操作対象の指定には座標が使用されます。

使用例

基本的なアクセシビリティスキャン
1. Navigate to example.com using browser_navigate
2. Run scan_page with violationsTag: ["wcag21aa"]
色のコントラストチェック
1. Use browser_navigate to go to example.com
2. Run scan_page with violationsTag: ["cat.color"]
複数ステップのワークフロー
1. Navigate to example.com with browser_navigate
2. Take a browser_snapshot to see available elements
3. Click the "Sign In" button using browser_click
4. Type "[email protected]" using browser_type
5. Run scan_page on the login page
6. Take a browser_take_screenshot to capture the final state
ダイアログと検証状態をスキャンする

URL クロールは基本的な確認であり、すべての UI 状態を網羅するものではありません。audit_site は一時タブで URL を移動しますが、現在のタブで開いているダイアログ、入力済みのフォーム、検証エラーを再現することはありません。scan_page はナビゲーションせず、現在選択されているタブに対して実行されるため、同じブラウザーセッション内で関連する操作を行うたびに使用してください。

1. Navigate once, wait for the application to be ready, and run scan_page for the initial state
2. Use browser_snapshot and browser_click to open the dialog or expand the panel
3. Wait for its visible content, take a fresh browser_snapshot, then run scan_page again
4. Submit the form with deliberately invalid test data, wait for the validation message, and run scan_page again
5. Capture browser_take_screenshot and record the state, reproduction steps and findings for each scan
6. Close or reset the UI, then repeat for the next state

HTML の <dialog> 要素やページ内モーダルコンポーネントは、ページコンテンツです。browser_handle_dialog が処理するのは JavaScript の alert、confirm、prompt ダイアログであり、HTML モーダルを開いたり閉じたりすることはありません。

scan_page_matrix で変化させるのはビューポート/メディア/ズームであり、アプリケーションの状態ではありません。一時的な状態を保つには reloadBetweenVariants: false に設定し、レスポンシブ再レンダリングによってその状態が閉じたりリセットされたりしていないことを確認してください。キーボード操作については audit_keyboard を別途実行してください。フォーカスが移動し、スキップリンクが有効になる場合があるため、スキャンを比較する前に目的の状態に戻してください。モーダルで意図的にフォーカスを閉じ込めることは、自動的にキーボードトラップになるわけではありません。アクセシブルな方法で閉じられることと、フォーカスが適切に戻ることを確認してください。

Axe の incomplete 結果、フレームのカバレッジに関する警告、サンプリングされたノード数を確認してください。自動検出された違反がゼロでも、適合性が証明されるわけではなく、開いていない状態を網羅しているわけでもありません。キーボード操作、フォーカスの表示と順序、エラーメッセージが理解しやすく、読み上げられることを手動で確認してください。

ページ分析
1. Navigate to example.com
2. Use browser_snapshot to capture all interactive elements
3. Review console messages with browser_console_messages
4. Check network activity with browser_network_requests
タブ管理
1. Open a new tab with `browser_tabs` and `{"action":"new"}`
2. Navigate to different pages in each tab
3. Switch to a tab with `browser_tabs` and `{"action":"select", "index": 1}`
4. List all tabs with `browser_tabs` and `{"action":"list"}`
動的コンテンツの待機
1. Navigate to a page
2. Use browser_wait_for to wait for specific text to appear
3. Interact with the dynamically loaded content

注意: ほとんどの操作ツールでは、browser_snapshot から取得した要素参照が必要です。ページ要素を操作する前に、必ずスナップショットを取得してください。

開発

ドメイン用語集では、ブラウザーと監査に関する用語を定義しています。リソースの所有権、計測のライフタイム、プロキシリレーの制約については、アーキテクチャ上の決定を参照してください。

プロジェクトをクローンしてセットアップします:

git clone https://github.com/JustasMonkev/mcp-accessibility-scanner.git
cd mcp-accessibility-scanner
npm install

npm 12 以降では、ネイティブ依存関係をアップグレードした後に npm install-scripts list を確認してください。更新された re2 のバージョンが、固定された allowScripts の承認によってブロックされる場合は、npm install-scripts approve re2 を実行してから npm rebuild re2 を実行してください。依存関係の更新とともに、承認内容もコミットしてください。install-scripts コマンドは npm 11 以前では使用できません。これらのバージョンではデフォルトでインストールスクリプトが実行されるため、スクリプトが明示的に無効化されていない限り、バイナリが見つからない場合は npm rebuild re2 を実行して復元してください。Node.js のバージョンを変更した場合も、re2 を再ビルドしてください。

npm run knip は、サーバーのソース、テスト、ベンチマーク、ツールをチェックします。

テストでは happy-dom ではなく Node または Playwright を使用し、Chrome プロトコルの型はローカルで定義しています。削除の理由と検証結果については、依存関係のレビューを参照してください。

Playwright のアップグレードゲート

Linux の test および webkit-regressions CI ジョブでは、各ジョブでブラウザーをダウンロードするのではなく、ブラウザーとシステム依存関係があらかじめインストールされた公式の mcr.microsoft.com/playwright:v1.63.0-noble イメージを使用します。 Firefox が GitHub のユーザー所有ホームディレクトリを使用できるよう、pwuser として実行します。 .github/workflows/ci.yml 内の両方のイメージタグは、固定された playwright および playwright-core のバージョンと一致させてください。ネイティブランナーのブラウザーマトリックスと パッケージの Docker スモークテストは引き続き別個です。また、ブランド版の Chrome と Edge は Playwright イメージに含まれません。Playwright Docker のガイダンスを参照してください。

2026 年 9 月 16 日のレビューでは、playwright と playwright-core を1.63.0で揃えたままにします。この日付時点での 最新の安定版リリースです。ローカルの InputRecorder ハブと既存のファクトリー参照カウントを維持してください。複数の MCP クライアントはクライアント側のブラウザーコンテキストを共有し、ハブはセッションログと明示的な録画を多重化して、兄弟ツールの操作を除外します。依存関係の更新だけで、この所有権モデルを変更してはいけません。

上流の #42627 を含む安定版を採用する前に、ハブを _enableRecorder / _disableRecorder から _startRecording({ language: 'javascript' }, sink) / _stopRecording() に適合させ、インストール済みランタイムに対してクライアントごとのイベント契約を検証してください。プレリリースへの更新や、未テストのメソッド名フォールバックをリリースしてはいけません。#42622 にある個別の接続への移行は別途必要となる所有権の変更であり、同じライフサイクルの確認が必要です。

固定された Chromium ブラウザーをインストールしてから、実際のレコーダーゲートを失敗テストおよび並行処理テストと合わせて実行してください。

npx playwright install chromium
npx vitest run tests/recorder.integration.test.ts tests/context.test.ts tests/browserSessions.test.ts tests/browserContextFactory.test.ts tests/tools-recorder.test.ts tests/sessionLog.test.ts

実ブラウザーのテストでは、同時開始、重複開始の拒否、共有 CDP クライアント、兄弟操作の帰属、停止/切断/再起動、--save-session、およびステートレスな明示的セッションをまたぐ録画を確認します。既存のユニットテストでは、開始失敗後の復旧と、開始/停止の重複も確認します。レコーダーは停止前に最後の入力イベントを受け取る必要があります。バッファーされていない入力は停止開始後に配信されても除外されますが、バッファーされたクリック/ナビゲーションには 500 ms のドレイン時間が設けられます。

アップグレードの動機となった依存関係の修正も再確認してください。1.63.0 の Chromium では、ページ全体と大きな要素の両方のスクリーンショット撮影後に、navigator.maxTouchPoints が 1 から 0 に、(pointer: coarse) が true から false に変化しました。ナビゲーションによってプロパティは復元されました(#42617)。 固定ヘッダー/スムーズスクロールのリトライフィクスチャではクリックは成功しましたが、即時移動ではなくスクロールイベントが 19 回発生しました(#42626)。 アップグレード候補では、ページ全体と要素のスクリーンショット撮影後、およびナビゲーション後もタッチ関連のプロパティが維持され、スムーズアニメーションなしでリトライ時のスクロールが完了することを確認してください。これらは依存関係の制約であり、レコーダーゲートだけでは検証できません。

新たに報告されたブラウザーの制限事項(#251)

2026年9月28日の検証では、Playwright 1.63.0 の2つのピン留めが維持されています。これらを含む安定版リリースはまだありません。アップグレードする前に、プラットフォーム別の結果と再実行コマンドを参照してください。

  • 事前読み込みされた CDP ページ: ネストされたクロスサイトまたはサンドボックス化されたフレームでは、page.url() にトップレベルの URL が表示されていても、評価、ロケーター、スキャンが iframe 内にリダイレクトされることがあります。--cdp-endpoint と --cdp-launch の両方で再現しました。既存のタブ状態が失われても問題ない場合は、新しい分離コンテキストを使用してください。トップレベルの URL だけを、スキャン対象を示す証拠として信頼しないでください。これは #244 のクラッシュしたタブへの接続タイムアウトとは別の問題です。
  • macOS でのフルページスクリーンショット: バンドル版の Chromium ヘッドレスシェルでは、キャプチャ後に実際のフォントとレイアウトが変化しました。Chrome では等幅フォントが変わりましたが、測定されたジオメトリは維持されました。ビューポートのスクリーンショットには、どちらの変化もありませんでした。キーボード監査の問題報告用スクリーンショットと、annotateScreenshot: true を指定した scan_page もフルページキャプチャを使用します。レイアウトに依存するチェックの後に実行するか、screenshotOnIssue: false と annotateScreenshot: false を指定してこれらのスクリーンショットを無効にしてください。サーバーはフォントをリセットしたり、ページを再読み込みしたりしません。
  • macOS での Firefox: Alt+a を指定した browser_press_key では a が入力されましたが、Chromium と WebKit のコントロールでは入力されませんでした。Option キーとフレームフォーカスの動作に対応する Firefox r1553 の変更はマージ済みですが、まだリリースされていません。キーはそのまま渡されます。
  • macOS 14 での WebKit: 固定された r2251 バンドルでは、ページ作成時に Unknown setting: PushAPIEnabled が発生します。ホスト型の macOS 14.8.9 arm64 ランナーで再現しました。macOS 26/r2359 の対照テストでは問題ありませんでした。影響を受ける場合は、Playwright をむやみにダウングレードせず、別途検証済みのブラウザーと OS の組み合わせを使用してください。

WebKit のプロビジョナルロードのイベント順序に関する競合状態も Linux で再現しました。キャンセルされたナビゲーションは、中断をすぐに報告せず、設定済みのタイムアウトまで待機しました。有効なナビゲーションタイムアウトを設定してください。これにより待ち時間は制限されますが、エラーの見落としは修正されません。Linux での Firefox のクラッシュサイクルでは親プロセスの RSS 増加が見られましたが、コンテキストを閉じただけではネイティブウィンドウが解放された証明にはなりません。これらは別個のアップグレード確認項目として残っています。エンジンへのパッチ適用、アルファ版へのアップグレード、ブラウザーのデフォルト変更は行っていません。

MCP ハーネス

npm ラッパーは最初にビルドを行い、その後、直接ハーネスが準備済みのフィクスチャを使って公開されているすべての MCP ツールを呼び出します。

npm run test:mcp
npm run test:mcp:install

Luna ラッパーは、各プロンプトを Codex gpt-6-luna に xhigh 推論で実行します。リポジトリを対象範囲とするスキャナー MCP サーバー、読み取り専用の Codex サンドボックス、構造化された PASS/FAIL の証拠、およびプロンプトごとのタイムアウトを使用します。

npm run test:mcp:luna
npm run test:mcp:luna -- --only browser_snapshot
npm run test:mcp:luna -- --skip-optional --limit 1

プロンプトスイートは、セッション管理、メディアエミュレーション、ネットワークリクエストの詳細、ドロップ操作、スクリーンリーダー監査など、コアおよびインストール関連の全34ツールを対象としています。オプションの browser_install プロンプトはデフォルトで含まれ、そのプロンプトに限りサーバーの install 機能を有効にします。省略するには --skip-optional を使用してください。

結果は test-results/mcp-direct-harness-results/ または test-results/mcp-tool-loop-results/ に書き込まれます。別の出力ルートを使用するには、MCP_HARNESS_RESULTS_DIR を設定してください。 Luna ハーネスは、プロンプトを開始する前に Codex へのログインを確認します。サイト監査プロンプトは公開ウェブサイトではなく、ローカルの HTTP フィクスチャを使用します。 PASS となるには、対象の MCP 呼び出しが完了し、失敗または未完了の MCP 呼び出しがなく、構造化された結果が成功している必要があります。ログが無効な場合、ターンが失敗した場合、またはタイムアウトした場合、実行は失敗となります。形式が不正なローカルエージェントロールが無視されたことを示す、致命的ではない起動時の通知はログに残りますが、ツールの失敗とはみなされません。復旧した Codex 接続再試行は、ターンが正常に完了した場合にのみ許容されます。実行をキャンセルすると、ステータス 130 で終了します。

ツールのレイテンシーをベンチマークする

bench/mcp-bench.mjs は、クライアントが実際に待つ時間を測定します。固定の合成サイトを提供し、stdio 経由でビルド済みサーバーと MCP で通信して、ナビゲーション、操作、スナップショット、すべての監査ツールについて、実際の tools/call の往復時間を計測します。最初にビルドしてください。コンパイル済みのサーバーを lib/ から実行します。

npm run build
npm run bench -- --out after.json --label after

便利なフラグ:--iterations <n> と --warmups <n>(デフォルトはそれぞれ 5 と 1)、スクリーンリーダーのシナリオを選択する --only audit_screen_reader、ブラウザーが Playwright のダウンロード先以外にある場合の --browser/--executable-path、および別のビルドを指定する --server <path/to/cli.js> と --lib <path/to/lib>(両方を指定)。これを使ってリビジョンを比較できます。

git worktree add /tmp/baseline main && (cd /tmp/baseline && npm install && npm run build)
npm run bench -- --server /tmp/baseline/cli.js --lib /tmp/baseline/lib --out before.json --label before
npm run bench -- --out after.json --label after
npm run bench:compare -- before.json after.json

比較に使う合計時間には、両方のレポートに含まれるエンドツーエンドのシナリオのみが使われるため、シナリオを追加または削除しても、報告される速度向上に影響しません。

スクリーンリーダーのシナリオでは、小規模なページ、名前チェックを有効および無効にした 400 個と 2,000 個の要素、30 個の共有祖先、同一オリジンの 3 つのフレームを対象にします。各サンプルでは、計測後に測定が完了していること、想定される検出結果、保存された JSON レポートを検証します。監査が完了しない場合、ベンチマークは失敗します。

読み上げ順序アナライザー単体の時間を計測するには、両方のリビジョンをビルドして、次を実行します。

node bench/reading-order-bench.mjs /tmp/baseline/lib/tools/auditScreenReader.js lib/tools/auditScreenReader.js

このテストでは、400 個と 2,000 個の兄弟要素を固定したレイアウト(整列、逆順、後半で逆転、対角線状、完全に重なった状態、外れ値を含む密集クラスター)で、結果が一致することを確認します。その後、各レイアウトについてリビジョンを交互に実行し、ウォームアップを 10 回、計測を 20 回行います。逆転の検出は線形時間です。帯域のカウントでは同一の軸区間を重複排除しますが、相異なる区間が密集している場合は二次時間がかかることがあります。これらの関数の計測時間には、ブラウザーの計測時間と MCP のレイテンシーは含まれません。

リリース

main に vX.Y.Z タグをプッシュすると、信頼された公開(OIDC)と来歴情報を使用して、.github/workflows/release.yml 経由でパッケージが npm に公開されます。npm の初回セットアップ、リリース手順、npm 12 のインストールスクリプトのルールについては、docs/releasing.md を参照してください。

ライセンス

MIT

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。