Cloudflare WebMCPは、Cloudflareを通っているサイトに「AIエージェント用のツール」をコード変更なしで生やす開発者プレビューです。2026-08-06、Agents Weekの一環として公開されました。エージェントに画面を読ませて操作を推測させるのではなく、サイト側から呼べる関数を渡してしまう——という発想の転換が中心にあります。
www.cloudflare.com が公開中の2ツールの裏側にある実エンドポイントの応答サイズ- ・何ができるか:Cloudflareダッシュボードのトグル1つで、サイトのHTMLに
<script>が1行注入され、ブラウザ内のエージェントに使えるツールが登録される。オリジンのコードは1文字も変えない。 - ・何を解決するか:エージェントがスクリーンショットとDOMから「たぶんこのボタン」と推測する不確実さと、その分のトークン消費。クローラーにコンテンツだけ持っていかれてトラフィックが戻らない問題への対案でもある。
- ・何を代替するか:代替するのは画面を読ませる工程であって、GitHub MCPのようなサーバー側MCPではない。両者は宣言する主体も実行する主体も違うので、置き換え関係にならない。
MCPサーバーそのものの仕組みや、自分でサーバーを書く場合の手順はMCPサーバーの作り方2026年完全ガイド:TypeScript・Python両対応チュートリアルにまとめてあります。本記事は「サーバーを立てる話ではなく、ページ側にツールを持たせる話」として、Cloudflareの実装が実際に何をしているかを一次ソースと手元の実測で確かめます。
Cloudflare WebMCPとは——コード変更なしでサイトにツールを生やす
公式ブログ「Give any website a WebMCP interface」(Will Rowe、2026-08-06)の書き出しは端的です。スイッチを入れればブラウザエージェントがサイトを扱えるようになり、コードは書かず、オリジンには何も変更しない。Cloudflareがページに小さなブリッジを追加し、訪問者のエージェントが使うツール一式を登録する——これがこのプレビューの全体像です。
背景として公式が挙げているのは、Web が「向こう側に人間がいる」前提で作られてきたのに、実際の訪問はどんどんエージェント由来になっているという不一致です。その対処が今まではクローラーで、コンテンツはサーバーへコピーされ、元のサイトにはトラフィックも功績も残らないことが多かった。スクレイピングに依らないもっと良いやり方がある、というのが動機として明示されています。
重要なのは、これが「Cloudflareが新しいプロトコルを作った」話ではないことです。WebMCP自体はブラウザ標準の提案であり、Cloudflareが作ったのはそこに乗るための入り口です。ここを取り違えると記事全体の理解がずれるので、先に用語を3つに分けます。
「WebMCP」と呼ばれる3つの層を切り分ける
同じ「WebMCP」という言葉が、少なくとも3つの別の対象を指して使われています。
・① 標準仕様としてのWebMCP:W3CのWeb Machine Learning コミュニティグループが進めている提案(webmachinelearning/webmcp、スター2,957・2026-08-09時点)。JavaScript関数や<form>要素を、自然言語の説明と構造化スキーマを持つ「ツール」としてエージェントに公開する仕組みを定義する
・② ブラウザの実装:仕様がページから見える形になったものがdocument.modelContext。Cloudflareの公式ブログはChrome 146で実験的に出荷されていると説明している
・③ Cloudflare WebMCP:②が存在するブラウザに対して、③がツールを登録する。サーバーではなく、登録する側
この分離が効いてくる場面は具体的です。「Cloudflareを外したらWebMCPが使えなくなる」わけではない(①は誰でも自前で実装できる)し、「Chromeが対応すれば自動で自分のサイトも使えるようになる」わけでもない(②があっても、③か自前実装がツールを登録しなければページには何も無い)。公式ブログもこの点を正直に書いていて、標準の弱点は「サイト側が実装しないといけないこと」だと明言し、そこを埋めるのがこのプレビューだと位置づけています。
なお仕様側には、JavaScriptで登録する命令的なAPIのほかに、<form toolname="..." tooldescription="...">のように属性でツールを宣言する宣言的なAPIの提案(Declarative API Explainer)もあります。ブラウザがフォームからツール定義を自動合成する、という方向です。
エッジで注入される1行と、bridge.jsがやっていること
公式ブログはこの実装を「オリジンの前に立つ2つの部品」と説明しています。どちらもサイトのコードには触れず、静的サイトでもSPAでも同じように動きます。
1つ目はエッジでの注入です。ダッシュボードでWebMCPをオンにすると、CloudflareはHTMLRewriterを使ってHTML応答に1行だけ追加します。タグもそれが読み込むスクリプトも同一オリジンのエッジから配信されるため、ページの他の部分は何も変わりません。
<!-- Cloudflareがエッジで注入する1行(公式ブログ掲載の形) -->
<script type="module"
src="/.webmcp/bridge.js"
data-packs="c2pa,mcp-server-client"
data-mcp-url="/mcp"></script>
data-packsが有効化するパックのリスト、data-mcp-urlが自前のMCPサーバーを指すパス(既定は同一オリジンの/mcp)です。
2つ目がブリッジ本体です。ページ内で動き、WebMCPの受け口を探します。ブラウザに受け口が無ければ何もせずreturnするので、非対応ブラウザではページの挙動が従来とまったく同じになる——ここは導入判断に直結する重要な仕様です。受け口が見つかれば、data-packsに並んだパックを1つのツールリストに合成し、それぞれを.registerToolで登録します。パックはMCPツール記述子とハンドラの組で、Content Credentialsのような静的パックは最初からツールを宣言し、Site MCP Serverのような動的パックは起動時にツールを発見してから登録します。
そしてプレビュー時点では、すべてのツールが訪問者のブラウザ内で完結します。Cloudflareのサーバーへの往復はありません。ブリッジのコード自体はエッジのWorkerが配信していて、公式は将来的にWorkers AIでサイトマップを要約する、AI Searchのインデックスを引く、といった「ページ単独ではできない仕事」をこのWorkerに任せる余地を残していると書いています。
「Cloudflareがサイトの機能を勝手にツール化する」わけではありません。注入されるのはブリッジ1行で、生えるツールは有効化したパックが持っているツールだけです。検索フォームや購入ボタンが自動でツールになるのではなく、自前のツールを出したい場合は Site MCP Server パック経由で自分のMCPサーバーを用意します。
同梱される2つのツールパックで何ができるか
プレビューに含まれるのは2パックで、どちらも既定でオンです。
Content Credentials(c2pa)——画像の来歴をエージェントに読ませる
C2PAプログラム参加者の資格情報を読むパックです。scan_images_c2paはページ内の全画像を走査して1枚ずつ短い要約を返します。公式が示している戻り値の例では、画像数・走査数・C2PAを持つ枚数に加えて、画像ごとにhasC2pa・format・manifestCount・claimGenerator(例:Adobe Firefly)・title・signedByが並びます。
もう1本のinspect_image_c2paは、1枚の完全なマニフェストを展開します。編集履歴、記載された作者、署名証明書まで読めますが、これは画像本体ではなく先頭数キロバイトのメタデータだけを触るプレーンなTypeScriptリーダーです。
そして署名の暗号的な検証は行いません。公式は「今のところ資格情報を読んで報告するだけ」と書き、結果には必ずsignatureVerified: falseを付けるとしています。理由も明記されていて、エージェントが「デコードできた主張」を「検証済みの事実」と取り違えないためです。プレビュー段階のツールとしては、ここを曖昧にしていないのが誠実な設計だと思います。
Site MCP Server(mcp-server-client)——自前のMCPサーバーをページ側へ橋渡しする
すでにMCPサーバーを持っているサイト向けのパックです。動的パックなので、起動時にサーバーのtools/listを叩いてツールを発見し、1本ずつプロキシとして登録します。公式ブログが載せている登録のコード例が、この仕組みの要点を端的に示しています。
// サイト自身のMCPサーバーが tools/list で広告する各ツールについて、
// 訪問者のオリジン・訪問者のセッションでサイトを呼び返すプロキシを登録する
document.modelContext.registerTool({
name: tool.name, // 例: "search_products"
description: tool.description,
inputSchema: tool.inputSchema, // tools/list の値をそのまま使う
execute: async (args) => {
const res = await fetch(mcpUrl, { // 同一オリジンの /mcp
method: "POST",
credentials: "same-origin",
headers: { "content-type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0", id: 1, method: "tools/call",
params: { name: tool.name, arguments: args },
}),
});
const { result } = await res.json();
return result; // MCPのCallToolResultをそのまま返す
},
});
credentials: "same-origin"が肝です。ツールの実行は訪問者のブラウザから、訪問者が既に持っているセッションで行われます。運営者のAPIトークンをどこかに置く必要がないかわりに、ログイン中のユーザーの権限でツールが動く、ということでもあります。エージェントから見れば、これらはすべて普通のMCPツールです。公式もModel Context ProtocolのTool型とCallToolResult型をそのまま使っていると明言していて、既存のMCPクライアントは特別な対応なしにページを操作できます。
有効化の手順と、動いているか確かめるコマンド
導入手順は驚くほど短いです。Cloudflareダッシュボードの Agent Readiness > Labs を開き、対象ドメインでWebMCPをオンにし、追加するパックを選ぶ。Content Credentials と Site MCP Server は既定で両方オンで、新しいパックが出ればここに増えていきます。デプロイするものも、オリジンで変更するものもありません。次にサイトが返すHTMLからブリッジが入ります。
有効になっているかの確認方法として、公式が案内しているのがこのコマンドです。
# 公式が案内している確認方法:注入された行を探す
curl -s https://your-site.example | grep webmcp
自分のエージェントを用意しなくても動作確認はできます。CloudflareのリモートブラウザBrowserRunを対象URLに向ければ、訪問者のエージェントとまったく同じようにツールを発見して呼び出します。BrowserRunは既にWebMCP対応が入っていて、ツールの挙動は誰かのノートPC上のブラウザでもクラウドのヘッドレスでも同じです。公式ブログはこの往復を「BrowserRunがエージェントに動くためのブラウザを与え、このプレビューがサイトに動かされるためのツールを与え、両者が公開標準の上で出会う」と表現しています。
手元で確かめた——cloudflare.com自身のツールとChrome 151の実測
ここからは公式の説明ではなく、2026-08-09に自分で測った内容です。
cloudflare.com は今、エージェントに2本のツールを見せている
www.cloudflare.comのHTMLを取得してwebmcpで検索すると、注入されたブリッジ……ではないものが1件見つかりました。ページに埋め込まれたJSONのツール宣言ブロックです。
# 実測:cloudflare.com が公開しているツール宣言を取り出す
curl -s https://www.cloudflare.com/ \
| grep -o '<script id="webmcp"[^>]*>[^<]*' | sed 's/.*>//' | python3 -m json.tool
返ってきたのは2本のツールでした。read_llms_txt(引数なし、説明は「アシスタント向けの簡潔なサイト文脈を読む」)と、read_markdown_page(必須の文字列引数pathを取り、Cloudflareページのmarkdown版を読む)です。
裏側のエンドポイントが実在するかも確かめました。/llms.txtはHTTP 200・text/plain・16,884バイトで、Cloudflareが335都市以上で運用するグローバル企業であることから製品群までを要約した文書が返ります。read_markdown_pageが指すmarkdown版も生きていて、/.mdが2,998バイト、/plans/.mdが27,398バイト(いずれもtext/markdown)でした。宣言だけで中身が無い、という状態ではありません。
この2本の裏にあるのは、WebMCPとは別に用意されている Markdown for Agents という機能です。公式ドキュメントによると、有効化したゾーンではエッジでHTMLをMarkdownへリアルタイム変換し、Accept: text/markdownのコンテントネゴシエーションで返します。応答にはx-markdown-tokensとx-original-tokensというヘッダも付き、変換によるトークン削減量が測れるようになっています。つまりcloudflare.comがエージェントに見せている2本は、既存のエージェント向け機能への入口をツールの形にしたもので、ページの機能そのものをツール化したわけではありません。
一方でhttps://www.cloudflare.com/.webmcp/bridge.jsはHTTP 404、developers.cloudflare.comも同じく404でした。少なくともこの2つのホストは、今回のプレビューのブリッジ注入ではなく別の手段でツールを宣言していることになります(radar.cloudflare.comもあたりましたが、こちらはボット対策で403・3,386バイトのチャレンジページが返るため判定できませんでした。なおRadarについては、公式チェンジログが2026-08-07にWebMCP対応を告知しており、URLスキャンやドメイン照会といったツールをブラウザ内エージェントに開放したとしています)。
<script id="webmcp" type="application/json"> という書き方は、確認した範囲——W3Cの仕様リポジトリ(命令的な registerTool と宣言的な form[toolname])、Chrome Labsのポリフィル、そしてCloudflare自身の公式ドキュメント(Browser RunのWebMCPページ、Markdown for Agentsページ、開発者ドキュメント全体の索引 llms.txt)——のいずれにも見当たりませんでした。パラメータの表現も、仕様の inputSchema(JSON Schemaのオブジェクト)ではなく parameters 配列です。文書化されていない独自の記法と読むのが妥当で、これをコピーして自サイトに置いても標準準拠のエージェントが拾う保証はありません。
Chrome 151 に document.modelContext は生えていなかった
公式ブログは「Chrome 146で実験的に出荷」と書いています。では手元のChromeではどうなのか。検証環境は Chrome 151.0.7922.76(headless / macOS) です。
# 実測:document.modelContext の有無を確認する
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--headless --disable-gpu --user-data-dir="$(mktemp -d)" \
--enable-features=WebMCP,DevToolsWebMCPSupport --virtual-time-budget=2000 --dump-dom \
'data:text/html,<body></body><script>document.body.textContent="mc="+(typeof document.modelContext)<%2Fscript>'
結果はmc=undefined。フラグ無しの既定でも、--enable-features=WebMCPや--enable-features=WebMCP,DevToolsWebMCPSupportを付けても、--enable-experimental-web-platform-featuresを付けても、"modelContext" in documentはfalseのままでした。--headless=newでも同じです。
WebMCP,DevToolsWebMCPSupport)は当サイトのChrome DevTools MCP記事で確認したもの念のため断っておくと、これは「Chrome 146でも使えない」という意味ではありません。確かめたのは特定バージョンのheadless Chromeで、指定した数種類のフラグを試した範囲です。
ただ、手元の安定版Chromeを開いてすぐ試せる状態ではないという結論自体は、Cloudflare自身のドキュメントが裏づけています。Browser RunのWebMCPページは「WebMCPは現在Chrome betaで利用可能なので、labセッションが必要」と明記し、安定版Chromeで動く本番プールとは別に、Chrome betaを積んだ実験用プールを用意しています。wrangler browser create --lab --keepAlive 300でlabセッションを取り、DevToolsのコンソールからnavigator.modelContextTesting.listTools()でツール一覧を出す、という手順まで案内されている——つまりベンダー側も「普通のChromeでは動かない」前提で導線を作っているわけです。私の実測はこれと矛盾しません。
代わりに動いたのがポリフィルです。Chrome LabsのGoogleChromeLabs/webmcp-tools(Apache-2.0・スター460)には、ネイティブ非対応のブラウザでWebMCPを動かすためのJavaScriptポリフィル(551行)が入っています。これを読み込んだページでregisterToolを呼ぶとdocument.modelContextがオブジェクトとして生え、getTools()が登録済みツールを1件返しました。
ここで型定義との食い違いが1つ見つかります。公式の型パッケージwebmcp-types(v0.1.3・MIT)を読むと、登録時のModelContextTool.inputSchemaはobjectなのに、getTools()が返すRegisteredTool.inputSchemaはstring(JSON Schemaを文字列化したもの)と定義されています。ポリフィルで実際に確認したところ、確かにtypeof t[0].inputSchemaはstringでした。仕様書の散文だけ読んでいると見落とす非対称なので、ツール一覧を受け取る側を書くときは注意してください。
型定義からはもう2つ、セキュリティ設計に関わる要素が読み取れます。ToolAnnotationsにはreadOnlyHint(状態を変えず読むだけか)とuntrustedContentHint(信頼できない出所の内容を返しうるか)があり、registerToolの第2引数にはexposedTo(このツールを呼べるオリジンのリスト)とsignal(AbortSignalでの登録解除)があります。前掲のCloudflareのコード例ではannotationsもexposedToも設定されていません。あくまで説明用の抜粋なので実装がそうだとは限りませんが、自前のMCPサーバーの書き込み系ツールをそのままページ側へ橋渡しするなら、この2つは意識しておく価値があります。
GitHub MCP・chrome-devtools-mcpとの違いと使い分け
「MCPサーバーが増えるならWebMCPは要らないのでは」と考えたくなりますが、両者は代替関係にありません。軸は3つ、誰がツールを宣言するか・誰のセッションで実行されるか・誰の資格情報を使うかです。
| 観点 | Cloudflare WebMCP | GitHub MCPサーバー | Chrome DevTools MCP |
|---|---|---|---|
| ツールを宣言する主体 | 訪問先のページ(サイト運営者) | サービス運営者(GitHub) | ローカルのMCPサーバー |
| 実行される場所 | 訪問者のブラウザ内 | GitHubのAPI(サーバー側) | 手元で起動したChrome |
| 使われる資格情報 | 訪問者の既存セッション(same-origin) |
運営者/利用者のトークン・OAuth | 手元のブラウザプロファイル |
| エージェントの設定作業 | 不要(ページを開けば出てくる) | MCPホストへの登録が必要 | MCPホストへの登録が必要 |
| ページを閉じたら | 使えない | 使える | 使える |
| 主に代替するもの | スクショ/DOM解析による画面操作 | 手作業でのAPI呼び出し | スクショだけのデバッグ |
| 現在の状態 | 開発者プレビュー | 一般提供 | 一般提供 |
使い分けの整理はこうなります。
・訪問者のログイン状態で、そのサイトの中の操作をさせたい→ WebMCP。カート、検索絞り込み、フォーム入力など「その人としてやる」必要がある操作に向く
・ブラウザを開かずにバックエンドの仕事をさせたい→ サーバー側MCP。Issueの起票やリポジトリ横断の検索は、ページを開く必要がない
・なぜ動かないかを調べさせたい→ Chrome DevTools MCP。コンソール・ネットワーク・トレースという原因側の情報が要る
面白いのは、この3つ目とWebMCPが既に接続していることです。chrome-devtools-mcp には --categoryExperimentalWebmcp というフラグがあり、list_webmcp_tools/execute_webmcp_tool の2本でページが公開しているWebMCPツールを列挙・実行できます。つまり「サイトがWebMCPでツールを出す」側と「エージェントがそれを呼ぶ」側の両方が、既に別々のプロダクトとして存在している状態です。
ダッシュボードでON"] --> B["Cloudflareエッジ
HTMLRewriterで1行注入"] B --> C["ブラウザ
bridge.js が起動"] C --> D{"document.modelContext
はあるか"} D -- "無い" --> E["何もせず終了
ページは従来どおり"] D -- "ある" --> F["registerTool で
パックのツールを登録"] F --> G["エージェント
通常のMCPツールとして呼ぶ"] G --> H["訪問者のセッションで実行
credentials: same-origin"]
導入を検討するときに押さえておくこと
最後に、公開情報と実測から見える判断材料をまとめます。
・開発者プレビューである:公式自身がそう明記し、Cloudflare Developers DiscordとCommunityフォーラムでフィードバックを募っている段階。本番の重要導線を前提にする段階ではない
・今すぐ得られる価値は限定的:同梱2パックのうち即戦力になるのは、自前のMCPサーバーを持っている場合のSite MCP Serverパック。持っていなければ、当面はC2PAメタデータの読み取り2本だけになる
・ブラウザ側がまだ揃っていない:document.modelContextは実験的な段階で、手元のChrome 151(headless)では確認できなかった。「オンにすれば今日からエージェントが使い始める」わけではない
・非対応ブラウザでの影響はほぼ無い:ブリッジは受け口が無ければ何もせず終了する。追加されるのはscript 1行とその読み込みだけで、既存の表示や挙動は変わらない
・権限の考え方が普通のMCPと逆になる:実行は訪問者のセッションで走る。書き込み系ツールをページ側へ出すなら、readOnlyHint/untrustedContentHint/exposedToといった仕様側の制御を前提に設計する
総じて、今日の実利より方向性の宣言として読むべきプレビューだと思います。「エージェント向けに専用APIを用意しろ」でも「クローラーを弾け」でもなく、既存のページにツール層を薄く重ねる。そのコストをトグル1つまで下げてみせた、というのがこの発表の中身です。効くかどうかはブラウザ側の普及と、ページ側が出す価値あるツールが増えるかにかかっています。
参照ソース
・Give any website a WebMCP interface — Cloudflare Blog(Will Rowe、2026-08-06。注入されるscriptタグ、パック構成、registerToolのコード例、確認コマンド、有効化手順の一次ソース)
・webmachinelearning/webmcp — WebMCP Explainer(W3C Web Machine Learning コミュニティグループ。仕様の動機、バックエンド統合との比較、宣言的APIの提案)
・webmcp-types — npm(v0.1.3・MIT。ModelContextTool/RegisteredTool/ToolAnnotationsの型定義。本記事のinputSchemaの非対称の根拠)
・GoogleChromeLabs/webmcp-tools(Apache-2.0。ネイティブ非対応ブラウザ向けポリフィルとデモ)
・WebMCP — Cloudflare Browser Run docs(Chrome betaとlabセッションが必要である旨、wrangler browser create --lab の手順)
・Markdown for Agents — Cloudflare Fundamentals docs(Accept: text/markdown によるエッジ変換。cloudflare.comの2ツールの裏側)
・Radar Researcher beta and WebMCP support now available — Cloudflare Changelog(2026-08-07。RadarのWebMCP対応)