同じ目的、違う渡し方

AIコーディングエージェントに実ブラウザを持たせる——この目的自体はもう新しくありません。 このブログでも以前Chrome DevTools MCPを取り上げましたし、Playwright MCP を使っている人も多いはずです。 いずれも MCPサーバーとしてツール群を公開し、エージェントがツール呼び出しでブラウザを操作するという形をとります。

Vercel Labs が公開した agent-browser は、 同じ目的に対してまずCLIとして答えを出しました。 エージェントは agent-browser click @e2 のようなコマンドを Bash で実行します。 MCPサーバーモードも用意されてはいますが、READMEの主役は明確にCLIの方です。

「ラッパーの形が違うだけでは」と思うかもしれません。私も最初はそう読みました。 ただ、なぜCLIなのかを追うと、そこにはMCPというプロトコルが構造的に払わせているコストへの具体的な診断があります。 本記事はツールの使い方紹介ではなく、その診断の中身を読むことを目的にします。 自分でエージェントにツールを持たせる人にとって、そこがいちばん転用が効く部分だからです。

agent-browser とは何か

リポジトリ作成

vercel-labs/agent-browser が Apache-2.0 で作られる。Rust製のブラウザ自動化CLI。

最初のリリース

v0.6.0。以降リリースが高頻度で続き、コマンド追加とMCPプロファイル整備が進む。

eve 向け拡張

Vercelが @agent-browser/eve を公開。eveエージェントのサンドボックス内にagent-browserを丸ごとマウントできるようになる。

v0.34.0

本記事執筆時点の最新。GitHubスターは約40,700で、Claude Code / Codex / Cursor / Copilot など「Bashが叩けるエージェント」全般から使われる。

実体は Rust製のCLI + 常駐デーモンです。CLIはコマンドをパースしてデーモンに投げるだけで、 デーモンが Chrome DevTools Protocol (CDP) 経由でブラウザを保持し続けます。 デーモンは初回コマンドで自動起動し、以後はコマンド間で生き続ける—— つまり毎回のブラウザ起動コストを払いません(既定では1時間アイドルで終了)。

# インストール(いずれか)
npm install -g agent-browser
brew install agent-browser
cargo install agent-browser

# Chrome for Testing から Chrome を取得
agent-browser install

ナビゲーション、操作、待機、スクリーンショット、ネットワーク傍受、HAR記録、 React のコンポーネントツリー検査、axe-core によるアクセシビリティ監査、iOSシミュレータ、 Browserbase などのクラウドブラウザ接続まで、READMEによればコマンドは100を超えます。 対応プラットフォームは macOS / Linux / Windows のネイティブバイナリです。

診断1: 接続しただけで払う「コンテキスト税」

MCPサーバーをエージェントに繋ぐと、まだ一度もツールを呼んでいない時点で全ツールの定義(名前・説明・JSON Schema)がコンテキストに載ります。これは避けられません。 エージェントがツールを選べるためには、選択肢の一覧が見えている必要があるからです。

問題はその量です。第三者による計測として、次の数字が報告されています。

接続対象ツール定義のトークン数200Kコンテキストに占める割合
Playwright MCP約13,700 トークン約 6.9%
Chrome DevTools MCP約17,000 トークン約 8.5%
agent-browser (CLI)0 トークン0%

CLIがゼロになるのは魔法ではなく、単に定義を先に渡していないだけです。 エージェントは agent-browser --help なり、 スキル/CLAUDE.md に書かれた数行の使い方なりを必要になった時に読みます。 「全機能の完全な仕様を常時載せておく」のをやめ、 「入口だけ教えて詳細は都度引かせる」に変えた、という差です。

診断2: 1アクションあたりの出力が重すぎる

税がゼロでも、1回の操作が数千トークン返してくるなら意味がありません。 そしてこちらの方が、実は効いています。

Playwright MCP は各アクションのレスポンスにページのアクセシビリティツリー全体を含めます。 エージェントが次に何をすべきか判断できるようにするための親切な設計ですが、 複雑なページでは数千ノードが毎回返ります。第三者の計測では、クリック1回のレスポンスが12,891文字だった例が報告されています。 同じ操作で agent-browser が返すのは Done. の6文字です。

では判断材料はどこから得るのか。必要な時に明示的に取りに行くのが agent-browser の答えで、 それが snapshot + refs です。

$ agent-browser snapshot
- heading "Example Domain" [ref=e1] [level=1]
- button "Submit" [ref=e2]
- textbox "Email" [ref=e3]
- link "Learn more" [ref=e4]

$ agent-browser click @e2
Done.

返ってくるのはロール + アクセシブルネーム + 参照IDだけ。 HTMLでもDOMツリーでもありません。そして @e2 という参照は次のsnapshotまで有効なので、クリックのたびにDOMを引き直す必要がない。-i を付ければ操作可能な要素だけに絞れます。

graph LR
  subgraph MCP["Playwright MCP 型"]
    M1["click 実行"] --> M2["a11y ツリー全体<br/>約 8,000 文字"]
    M2 --> M3["エージェントが<br/>毎回読む"]
  end
  subgraph AB["agent-browser 型"]
    A1["snapshot<br/>約 280 文字"] --> A2["@e1 @e2 @e3 ..."]
    A2 --> A3["click @e2"]
    A3 --> A4["Done. 6 文字"]
    A4 --> A3
  end
判断材料を「毎回押し付ける」か「必要な時だけ取りに行く」か

この差が積み上がると効きます。10ステップのワークフローでの比較として、 Playwright MCP が約114,000トークン、agent-browser が約7,000トークン——94%減という数字が報告されています。 Vercel自身の公称は「Playwright MCP比で93%減」です。

なぜCLIだと安くなるのか — 構造の話

ここまでの2つは、実はどちらもCLIであること自体から出てくるわけではありません。 「ツール定義を先出ししない」も「出力を絞る」も、原理的にはMCPサーバー側でもできます。 では何がCLIを有利にしているのか。3つあります。

1. 出力の粒度を呼び出し側が選べる

CLIはコマンドが分かれているので、click は結果だけ、snapshot は構造だけ、と用途ごとに返す量を分離できます。 MCPでも同じことは可能ですが、「ツール数を増やすとツール定義の税が増える」という 逆向きの圧力がかかるため、1ツールに機能と情報を詰め込みたくなる力学が働きます。

2. シェルで合成できる

これがいちばん大きい。CLIは && やパイプで複数手順を1回のツール呼び出しに畳めるのです。

# ログインフローを1回の Bash 呼び出しで完結させる
agent-browser open example.com/login && \
  agent-browser wait --load networkidle && \
  agent-browser snapshot -i

agent-browser fill @e1 "user@example.com" && \
  agent-browser fill @e2 "pass" && \
  agent-browser click @e3

MCPのツール呼び出しは1回につき1往復です。5ステップなら5往復、 そのたびにモデルの推論とレスポンスの読解が挟まります。 シェルなら5コマンドが1往復に畳まれ、中間の出力を捨てられる。 トークンだけでなくレイテンシにも効きます。

3. デーモンが状態を持つ

CLIプロセスは毎回死にますが、ブラウザセッションはデーモン側に残ります。 だから「コマンドが独立している」ことと「セッションが継続している」ことが両立する。 起動は初回のみで、以後のコマンドは数十〜100ms程度で返るとされています。

graph TB
  AGENT["AI エージェント<br/>Claude Code / Codex / Cursor"]
  CLI["agent-browser CLI<br/>Rust・毎回起動して終了"]
  DAEMON["常駐デーモン<br/>Rust・セッションを保持"]
  CHROME["Chrome<br/>CDP 接続"]
  AGENT -->|"Bash で1行実行"| CLI
  CLI -->|"Unix ソケット IPC"| DAEMON
  DAEMON -->|"Chrome DevTools Protocol"| CHROME
  DAEMON -.->|"snapshot の ref 表を保持"| DAEMON
  CLI -->|"標準出力は最小限"| AGENT
使い捨てのCLIと生き続けるデーモンを分けたことで、状態とステートレス性が同居する

「CLIの勝ち」ではない — agent-browser 自身が示している

ここで話を止めると「MCPは筋が悪い」という結論になりますが、それは行き過ぎです。 最良の反証は agent-browser 自身が MCPサーバーモードを持っていることです。

agent-browser mcp                             # core プロファイル(既定)
agent-browser mcp --tools core,network,react  # 必要な領域だけ足す
agent-browser mcp --tools all                 # CLI と同等の全ツール

そして --toolstool profiles を選べる。core(ナビゲーション・snapshot・操作)、networkstatedebugtabsreactmobileall。 これは「MCPを使うなら、せめて定義の量を自分で選ばせろ」というコンテキスト税に対するMCP側からの回答です。

観点CLI モードMCP モード
ツール定義のコンテキスト0(都度 --help 等で引く)プロファイル選択で調整可能
複数手順の合成&& やパイプで1往復に畳める1ツール = 1往復
利用条件エージェントがBashを実行できることMCPクライアントであること
ツールの発見性エージェントが存在を知っている必要接続すれば自動的に見える
権限制御Bash実行権限に依存(粒度が粗い)ツール単位で許可・拒否できる
向く場面コーディングエージェントの検証ループBash不可の環境、細かい権限管理が要る場面

関連して、ツールを絞ること自体が精度に効くという報告もあります。 Vercel が自社のデータエージェントでツールの8割を削った結果、消費トークンが37%減ったという 2025年12月の知見が二次情報として引かれており、 同様に「17個の専門ツールより2個のツールの方が成功率が高かった」という比較も紹介されています。 いずれも一次資料での確認は取れていないので数値そのものは参考程度ですが、選択肢を減らすと判断が良くなる方向は、日々エージェントを使っていれば体感と合うはずです。

実際に使うときの勘所

基本の型

agent-browser open example.com
agent-browser snapshot -i                  # 操作可能な要素だけ取得
agent-browser click @e2
agent-browser fill @e3 "test@example.com"
agent-browser get text @e1
agent-browser screenshot page.png
agent-browser close

@eN 以外に CSS セレクタ(#id, .class)、テキスト、XPath、 そして find role button click --name "Submit" のようなセマンティックロケータも使えます。 ただしREADMEが推すのは一貫して @eN です。 オーバーレイに遮られてクリックできない場合、エラーが遮っている要素を教えてくれるので、 それを閉じてからリトライできます。

エージェントに渡すときに効くフラグ

フラグ効果
--json機械可読な出力。エージェントに解釈させるならこれ
--session 独立したブラウザインスタンス。並列作業やユーザー切り替えに
--profile 実Chromeのログイン状態を再利用。認証を毎回やり直さない
--restoreCookie / localStorage の自動保存・復元
--allowed-domainsナビゲーション先を許可ドメインに限定
--confirm-actionseval やダウンロードなど破壊的操作にゲートをかける
--headedブラウザウィンドウを表示。人間が見て確認したいとき

わかっている弱点

@eN 参照は「snapshot時点のスナップショット」なので、動的にDOMが書き換わるページでは参照がずれる——この安定性の問題は第三者レビューで指摘されています。 対策は単純で、DOMが変わるアクションの直後には snapshot を取り直すこと。wait --load networkidle や要素待機を挟んでから撮る、を型にしておくと事故が減ります。

まとめ

agent-browser は「Playwright MCP の速いやつ」ではありません。エージェントにツールを渡すという行為のコストを、2つに分解して測り直したプロダクトです。

  1. 接続コスト——まだ何もしていない時点で載るツール定義。MCPでは1万〜1.7万トークン、CLIではゼロ
  2. 実行コスト——1アクションが返す量。全a11yツリーか、Done. の6文字か

そして agent-browser 自身がMCPモードとtool profilesを持っている以上、 結論は「CLIに乗り換えろ」ではありません。自分のエージェントが今どちらのコストを多く払っているかを、一度実測してみる—— 持ち帰るべきはそこです。 MCPサーバーを3つ繋いだだけでコンテキストの2割が消えている、という状況は珍しくありません。

参考リンク

理解度チェック

問題 0 / 50%
Q1

agent-browser が採用している、アクセシビリティツリー全体ではなく操作可能な要素だけを @e1 / @e2 のような参照付きで返す仕組みを何と呼びますか?(英語表記)