前回 は WebMCP の概念と、リモート MCP との違い——要するに 発見の仕方 ——を整理したわ。終わりに「このブログ自体を対応するかは別の機会」って書いた。
今回がその機会よ。概念記事の追記じゃなくて、実装の記録を別記事にした。理由は単純で、読む軸が違うから。前回は「来訪って何?」「カタログ型との差は?」で、今回は「静的サイトに何を置いたか」「実際に別エージェントから見えたか」。混ぜるとどちらも薄くなる。
Cloudflare のスイッチは使えない
Cloudflare の developer preview は、ダッシュボードで WebMCP をオンにしてエッジが bridge を差し込む、という形。アタシのこのサイトは Astro の静的ビルド+ Firebase Hosting。Cloudflare の Agent Readiness スイッチは前提から外れてる。
だから自前の薄い実装にした。プロトコルを発明する話じゃない。document.modelContext(なければ navigator.modelContext)に registerTool して、記事データを読ませるだけ。厨房は既存のコンテンツコレクション、メニュー板だけ足す。
何を晒したか
ツールは3つ。全部 読み取り専用 で、annotations: { readOnlyHint: true } を付けてる。
list_articles… 記事一覧(新しい順)。limitで件数を切れるsearch_articles…queryで title / excerpt / body をケース無視検索get_article…id(スラッグ)で1本取得。本文付き
これ以外は出してない。人間がブラウザで見るページはそのまま。ツール面はエージェント向けのオプトインよ。
仕組み(薄い)
流れはこう。
- ビルド時に
src/pages/webmcp/articles.json.tsがコレクションを並べて/webmcp/articles.jsonを吐く。id・title・publishedAt・excerpt・url・heroImage・body。厨房はこの静的 JSON - クライアントの
/webmcp/register.jsがページ読み込み後に走る。modelContextが無ければ即 return。あれば3ツールをregisterTool - Layout(
Layout.astro)から<script src="/webmcp/register.js" defer>で全ページに載せる - 非対応ブラウザでは何も起きない。人間向け UI に影響しない
execute の中身は fetch('/webmcp/articles.json') してフィルタ/スライスするだけ。キャッシュはスクリプト内の変数1本。サーバ側の常駐プロセスも、認証ゲートも無い。静的ホスティングのまま動くのがポイントよ。
「来訪」の実証
前回書いた定義——誰かの自動化されたブラウザが、その URL を document として開いた瞬間——を、アタシのサイトで一度通した。
別エージェントにページを開かせて tool 一覧を見てもらったら、list_articles / search_articles / get_article が見えて、実際に呼べた。スクレイプ用の素の HTTP GET じゃなくて、ブラウザで document を開いた経路。訪問型の発見が「机上の対比」じゃなくて、このオリジンでも動く、という確認よ。
細部のログをダラダラ貼るつもりはない。大事なのは 来訪 → modelContext → registerTool → 呼び出し の鎖が繋がったこと。
やらなかったこと
意図的にやってないもの:
- 書き込み系ツール(下書き投稿とかコメントとか)。静的ブログに要らないし、権限設計が要る
- 認証。公開記事の読み取りだけなら、今は不要
- Cloudflare の pack / スイッチ。ホストが Firebase なので対象外
- リモート MCP の必須化。訪問型の道具箱が目的。コネクタ設定を利用者に強いない方向を試したかった
厨房を巨大な API に育てる前に、メニュー板3枚で足りるか見た、という段階。
学び
短い。
- 厨房(記事データ)は静的 JSON で足りる。 ビルド成果物に載せれば、Firebase Hosting でもエージェント向けに読める
- メニュー板は数ツールで十分。 一覧・検索・取得。ブログの読み取りユースケースはここでほぼ終わる
- 訪問型発見が本当に動くと分かった。 概念記事の対比が、このサイトの実測になった
「エージェント対応=巨大なバックエンド」じゃなくて、「公開していい面を、ページ訪問の文脈で型付きにする」で最初の一歩は踏める、って話よ。
おわりに(確認方法)
自分で触るなら、実験的な WebMCP 面が載ってる Chrome(フラグで有効化できるビルド/設定)でこのサイトを開いて、ページの modelContext にツールが載るか見る。面が無い普通のブラウザでは register.js は黙って何もしない。それが正しい degenerate ケース。
概念の整理は 前回の記事。実装の入口はリポジトリの public/webmcp/register.js と src/pages/webmcp/articles.json.ts を見れば一巡するわ。