Works
Blog Recruit Contact 無料でAI診断する
WebMCP 2026.03.19 [WebMCP:Webサイトがアクションを話す時代 Vol.2]

WebMCP:Webサイトがアクションを話す時代 第2回:WebMCPの技術構造 ― 2つのAPIとTool Contractの設計思想

WebMCPの2つのAPI——HTMLフォームに属性を追加するだけのDeclarative APIと、JavaScriptで動的にツールを登録するImperative API。Tool Contractの設計思想とhuman-in-the-loopの仕組みを技術的に解説。

WebMCP:Webサイトがアクションを話す時代 第2回:WebMCPの技術構造 ― 2つのAPIとTool Contractの設計思想

はじめに

前回(第1回)では、WebMCPが「なぜ必要なのか」を概念レベルで解説しました。AIエージェントがスクリーンショットを撮って推測クリックする「ピクセルの時代」から、構造化されたTool Contractに基づいてツールを呼び出す「プロトコルの時代」への転換です。

第2回の今回は、WebMCPの技術的な中身に踏み込みます。

WebMCPは開発者に対して2つの実装パス(API)を提供しています。Declarative API(宣言的API)とImperative API(命令的API)です。また、AIエージェントが操作を勝手に実行しないよう、ブラウザが「仲介者」として安全性を担保するhuman-in-the-loopの仕組みが組み込まれています。

これらを理解すれば、「自社サイトのどの機能を、どのAPIで、どのレベルの安全策とともにAIに公開するか」という実務判断ができるようになります。

なお、本記事で解説するAPI名・属性名・メソッド名は、2026年3月時点のW3Cドラフト仕様およびChrome 146 Canaryの実験的実装に基づいています。WebMCPはまだ標準化の途上にあり、正式リリースまでに名称や挙動が変更される可能性があります。実装時には最新のChrome Developersドキュメントを参照してください。

Tool Contractとは何か — Webサイトの「メニュー表」

技術的な詳細に入る前に、WebMCPの中心概念であるTool Contract(ツール契約)を整理しましょう。

Tool Contractは、Webサイトが「自分のサイトで何ができるか」をAIエージェントに伝えるための構造化されたデータです。レストランのメニュー表に例えるとわかりやすいでしょう。

メニュー表には「料理名」「説明」「必要な注文オプション(サイズ、トッピングなど)」が書かれています。お客(AIエージェント)はメニューを見て、「この料理を、このオプションで注文する」と明示的に伝えます。厨房(Webサイト)はその注文に基づいて調理(処理)し、結果を返す。お客が厨房に入り込んで「たぶんこの鍋がパスタだろう」と推測する必要はありません。

WebMCPのTool Contractは、以下の要素で構成されます。

  • name — ツールの名前(例:searchFlightsaddToCart
  • description — ツールの説明文。AIエージェントはこの説明を読んで「このツールをいつ使うべきか」を判断する
  • inputSchema — 入力パラメータの定義。JSONスキーマ形式で型・必須/任意・説明を指定する
  • execute — ツールが呼び出されたときに実行される関数(Imperative APIの場合)
  • annotations — ツールの性質を示すヒント(読み取り専用かどうか等)

このTool Contractを定義する方法が2つある——それがDeclarative APIとImperative APIです。

Declarative API — HTMLフォームに2つの属性を追加するだけ

Declarative API(宣言的API)は、既存のHTMLフォームをそのままWebMCPツールにする最もシンプルな方法です。JavaScriptの記述は不要で、HTMLの<form>要素に属性を追加するだけでAIエージェントから利用可能になります。

追加する属性

W3C仕様およびChrome 146 Canaryの実装で提案されている属性は以下のとおりです。

toolname(必須)。フォームをWebMCPツールとして登録するための名前です。この属性が<form>要素に付与されていると、ブラウザはそのフォームをAIエージェント向けのツールとして認識します。

tooldescription(必須)。ツールが何をするかの自然言語による説明です。AIエージェントはこの説明文を読んで「いつ、なぜこのツールを使うべきか」を判断します。toolnameと合わせて付与しないと、ツールとして認識されません。

toolautosubmit(任意)。AIエージェントがフォームを埋めた後、自動的に送信するかどうかを指定します。この属性がない場合、エージェントはフォームを埋めるところまでで止まり、最終的な送信はユーザー自身がボタンをクリックする必要があります。ここにhuman-in-the-loopの設計思想が表れています。

さらに各入力フィールドにはtoolparamdescription属性を追加して、そのフィールドが何を期待しているかをAIに説明できます。

注: toolnametooldescriptionはW3Cドラフト仕様に明記されていますが、toolautosubmittoolparamdescriptionは現時点ではChrome Canaryの実験的実装およびExplainerドキュメントで提案されている段階の属性です。正式リリースまでに属性名が変更される可能性があります。

実装例:不動産サイトの内覧予約フォーム

既存のHTMLフォームをWebMCP対応にする具体例を見てみましょう。

変更前(通常のHTMLフォーム):

HTML
<form action="/booking" method="POST">
  <label for="name">お名前</label>
  <input type="text" id="name" name="name" required />

  <label for="email">メールアドレス</label>
  <input type="email" id="email" name="email" required />

  <label for="property_id">物件ID</label>
  <input type="text" id="property_id" name="property_id" required />

  <label for="date">希望日</label>
  <input type="date" id="date" name="date" required />

  <button type="submit">内覧を予約する</button>
</form>

変更後(WebMCP対応):

HTML
<form action="/booking" method="POST" toolname="bookPropertyViewing" tooldescription="不動産物件の内覧予約を行う。物件ID、希望日、お名前、メールアドレスを指定する">

  <label for="name">お名前</label>
  <input type="text" id="name" name="name" required toolparamdescription="予約者のフルネーム" />

  <label for="email">メールアドレス</label>
  <input type="email" id="email" name="email" required toolparamdescription="予約確認メールの送信先アドレス" />

  <label for="property_id">物件ID</label>
  <input type="text" id="property_id" name="property_id" required toolparamdescription="内覧したい物件の一意な識別子(例:PROP-2026-001)" />

  <label for="date">希望日</label>
  <input type="date" id="date" name="date" required toolparamdescription="内覧希望日(YYYY-MM-DD形式)" />

  <button type="submit">内覧を予約する</button>
</form>

変更箇所は、<form>タグへのtoolnametooldescriptionの追加、そして各<input>へのtoolparamdescriptionの追加です。CSSやJavaScriptの変更は一切不要で、人間がブラウザで見た場合の表示も全く変わりません。

ブラウザはこのフォームを検出すると、内部的にJSONスキーマを自動生成します。AIエージェントから見ると、以下のようなツール定義が公開されていることになります。

JSON
{
  "name": "bookPropertyViewing",
  "description": "不動産物件の内覧予約を行う。物件ID、希望日、お名前、メールアドレスを指定する",
  "inputSchema": {
    "type": "object",
    "properties": {
      "name": { "type": "string", "description": "予約者のフルネーム" },
      "email": { "type": "string", "description": "予約確認メールの送信先アドレス" },
      "property_id": { "type": "string", "description": "内覧したい物件の一意な識別子" },
      "date": { "type": "string", "description": "内覧希望日(YYYY-MM-DD形式)" }
    },
    "required": ["name", "email", "property_id", "date"]
  }
}

HTMLのrequired属性、type属性(emaildateなど)、pattern属性(入力パターン制約)もスキーマに反映されます。つまり、フォームのバリデーションルールがそのままAIエージェント向けのパラメータ仕様になるのです。

エージェント起動を検知するイベント

Declarative APIには、フォーム送信がAIエージェント経由かどうかを判別するための仕組みも提案されています。

SubmitEvent.agentInvoked — フォーム送信がエージェントによるものかを示す真偽値。これにより、バックエンドは「人間からのリクエスト」と「AIエージェントからのリクエスト」を区別して処理できます。

SubmitEvent.respondWith(Promise) — エージェントに対して構造化されたレスポンスを返すためのメソッド。preventDefault()と組み合わせて使うことで、通常のフォーム送信をキャンセルしつつ、エージェントには成功/失敗の結果をJSON形式で返せます。

さらにCSS擬似クラスとして*:tool-form-active(エージェントがフォームにアクセス中)や*:tool-submit-active(エージェントが送信直前)が提案されており、ユーザーに「AIがこのフォームを操作しています」と視覚的に伝えるUIを実装できるようになる見込みです。

注: SubmitEvent.agentInvokedrespondWith()、CSS擬似クラスtool-form-active等は、現時点ではブラウザの実験的実装およびExplainerドキュメントに基づく情報です。正式リリースまでにプロパティ名や挙動が変更される可能性があります。

Imperative API — JavaScriptで動的にツールを登録する

Declarative APIがHTMLフォームを対象とするのに対し、Imperative API(命令的API)はJavaScriptを使って任意の機能をツールとして登録できる、より柔軟な方法です。

フォームで表現しにくい複雑なワークフロー——複数ステップの購入フロー、状態に依存する操作(ログイン後にしか使えない機能)、動的に変化するツールセット——はImperative APIで実装します。

なお、WebMCP非対応ブラウザでの実験を可能にする実装としてMCP-Bが登場しています。@mcp-b/globalパッケージによるnavigator.modelContextのポリフィルに加え、React向けフックやブラウザ拡張向けトランスポートなどのSDK群を提供しています。Chrome Canary以外でプロトタイプを試したい場合の選択肢として覚えておくとよいでしょう。

APIの全体像

W3Cドラフト仕様(2026年2月12日版)のIDL(Interface Definition Language)では、navigator.modelContextに以下の2メソッドが定義されています。

registerTool(tool) — 1つのツールを登録する。既存のツールには影響しない。

unregisterTool(name) — 指定した名前のツールを削除する。

加えて、Explainerドキュメントでは以下のメソッドも提案されています。

provideContext({ tools: [...] }) — ツールセット全体を一括で置き換える。アプリケーションの状態が変わったとき(ログイン/ログアウト、ページ遷移など)に便利。

注: provideContextは実装・解説記事で広く言及されていますが、W3Cドラフト仕様のIDLにはregisterTool/unregisterToolのみが定義されています(2026年3月時点)。メソッド名やシグネチャは仕様の更新に伴い変更される可能性があります。

実装例:ECサイトの商品検索ツール

JavaScript
if ('modelContext' in navigator) {
  navigator.modelContext.registerTool({
    name: 'searchProducts',
    description: 'キーワード、カテゴリ、価格上限で商品を検索する',
    inputSchema: {
      type: 'object',
      properties: {
        query: {
          type: 'string',
          description: '商品名やキーワード'
        },
        category: {
          type: 'string',
          description: '商品カテゴリ(例:electronics, clothing)'
        },
        maxPrice: {
          type: 'number',
          description: '価格の上限(円)'
        }
      },
      required: ['query']
    },
    annotations: {
      readOnlyHint: true
    },
    async execute(input) {
      const results = await fetch(
        `/api/products?q=${input.query}&cat=${input.category || ''}&max=${input.maxPrice || ''}`
      );
      const data = await results.json();
      return {
        products: data.items,
        totalCount: data.total
      };
    }
  });
}

ここで注目すべき要素をいくつか解説します。

'modelContext' in navigatorのチェック。WebMCPはセキュアコンテキスト(HTTPS)でのみ利用可能であり、対応ブラウザ以外ではnavigator.modelContextが存在しません。この分岐を入れることで、非対応環境でもエラーにならず、通常のWebサイトとして機能し続けます。現時点ではChrome 146 Canaryでchrome://flagsから「WebMCP for testing」フラグを有効にする必要があります。

inputSchemaのJSON Schema定義。これはOpenAI、Anthropic、Googleなど主要AIプラットフォームのツール定義フォーマットと同じJSON Schema仕様です。MCPのツール定義とも互換性があります。つまり、AIモデルにとって「見慣れた形式」でパラメータが定義されているため、解釈の精度が高くなります。

annotations.readOnlyHint: true。このツールがデータを変更しない「読み取り専用」であることをエージェントとブラウザに伝えるヒントです。W3C仕様では「このヒントはエージェントがツールを安全に呼び出せるかどうかの判断を助ける」と記載されています。ただし、readOnlyHintはあくまでヒントであり、ユーザー確認プロンプトを完全にスキップすることが仕様上保証されているわけではありません。実際の挙動はブラウザやエージェントの実装に依存します。

実装例:購入ツール(human-in-the-loopあり)

次は「データを変更する」操作の例です。W3Cの提案ドキュメントに掲載されている購入ツールのパターンを見てみましょう。

JavaScript
navigator.modelContext.registerTool({
  name: 'buyProduct',
  description: '商品IDを指定して購入を実行する',
  inputSchema: {
    type: 'object',
    properties: {
      product_id: {
        type: 'string',
        description: '購入する商品のID'
      }
    },
    required: ['product_id']
  },
  async execute({ product_id }, agent) {
    // ユーザーに確認を求める
    const confirmed = await agent.requestUserInteraction(async () => {
      return new Promise((resolve) => {
        const result = confirm(
          `商品 ${product_id} を購入しますか?\nOKで確定、キャンセルで中止します。`
        );
        resolve(result);
      });
    });

    if (!confirmed) {
      throw new Error('購入がユーザーによってキャンセルされました');
    }

    await executePurchase(product_id);
    return { message: `商品 ${product_id} を購入しました` };
  }
});

ここで登場するagent.requestUserInteraction()がhuman-in-the-loopの核心部分です。次のセクションで詳しく解説します。

human-in-the-loop — ブラウザが「仲介者」として安全を守る

WebMCPの設計で最も重要な原則の一つが、AIエージェントは勝手に行動しないということです。

VentureBeatの分析によれば、WebMCPは完全自律型のエージェントパラダイムではなく、「協調的でhuman-in-the-loopのワークフロー」を中心に設計されています。GoogleのWebMCP仕様は、Context(エージェントに必要なデータ)、Capabilities(エージェントが実行できるアクション)、Coordination(エージェントと人間の間の引き継ぎ制御)の3つの柱をこの設計の基盤としています。

具体的に、WebMCPは以下のメカニズムで安全性を確保しています。

readOnlyHintによるツールの分類

ツール登録時にannotations.readOnlyHintを指定することで、ツールの性質をブラウザとエージェントに伝えます。

  • readOnlyHint: true — データを読むだけで変更しないツール。商品検索、在庫確認、価格照会など。エージェントやブラウザが確認フローを簡略化する判断材料になりうる
  • readOnlyHint: false(デフォルト) — データを変更する可能性があるツール。購入、予約確定、投稿、削除など。ブラウザがユーザーに確認を求める

なお、AnthropicのMCP仕様ではさらに詳細なアノテーション(destructiveHintidempotentHintopenWorldHintなど)が定義されています。WebMCPの現在のW3C仕様ではreadOnlyHintのみですが、将来的に拡充される可能性があります。

requestUserInteraction()によるユーザー確認

前セクションの購入ツール例で示したとおり、agent.requestUserInteraction()はツールの実行を一時停止し、ユーザーにUIを表示して確認を求めるためのメカニズムです。

AIエージェントがツールを呼び出すと、execute関数にagentModelContextClientインターフェース)が渡されます。このagentオブジェクトのrequestUserInteraction()メソッドを呼ぶと、エージェントの処理が一時停止し、開発者が定義した確認UI(ダイアログ、モーダル、カスタムUIなど)がユーザーに表示されます。ユーザーが承認すれば処理が続行し、拒否すればエージェントにキャンセルが通知されます。

MicrosoftのEdgeチームでWebMCPの策定に参加しているPatrick Brossetは、自身のブログでこう述べています。requestUserInteraction()はhuman-in-the-loopを維持し、AIエージェントがユーザーに確認なく購入を完了するのを防ぐために存在する、と。

Declarative APIにおけるhuman-in-the-loop

宣言的APIでは、toolautosubmit属性がhuman-in-the-loopの制御弁になります。

  • toolautosubmit属性なし(デフォルト) — エージェントはフォームの各フィールドを埋めるが、送信ボタンはクリックしない。ユーザーが内容を確認し、自分で送信する
  • toolautosubmit="true" — エージェントがフォームを埋めた後、自動的に送信まで行う

データの読み取り(検索フォームなど)にはtoolautosubmit="true"を、データの書き込み(予約、購入、問い合わせなど)にはデフォルト(toolautosubmitなし)を使うのが基本方針です。

ブラウザプラットフォームとしてのセキュリティ境界

WebMCPのセキュリティは、ブラウザが長年培ってきたWebセキュリティモデルの上に構築されています。

Same-Origin Policy — ツールはそのツールが登録されたオリジン(ドメイン)のセキュリティ境界を継承します。あるサイトのツールが別のサイトのデータにアクセスすることはできません。

Content Security Policy(CSP) — WebMCPのAPIはCSPの制約を遵守します。サイトのセキュリティポリシーに反するツール実行はブロックされます。

HTTPS必須navigator.modelContextはセキュアコンテキストでのみ利用可能です。HTTPのサイトではAPIが存在しません(ローカル開発のlocalhostは例外)。

セッション継承 — WebMCPのツールはユーザーの既存ブラウザセッションを継承します。これは大きなメリットで、別途認証を構築する必要がありません。ユーザーがログイン済みであれば、エージェントもそのセッションの権限でツールを実行できます。

Declarative vs Imperative — どちらをいつ使うか

2つのAPIの使い分けは、対象となる操作の性質で判断します。

判断基準Declarative APIImperative API
対象既存のHTMLフォームフォームに収まらない操作
実装コスト極めて低い(HTML属性追加のみ)中程度(JavaScript記述が必要)
動的なツール変更不可可能(registerTool/unregisterTool)
状態依存の操作困難容易(ログイン状態に応じてツールを出し入れ等)
戻り値の制御respondWith()経由execute()の戻り値で自由に定義
推奨ユースケース検索、問い合わせ、予約フォーム複数ステップのチェックアウト、ダッシュボード操作、動的設定

実務的な指針として、Codelyが提唱するベストプラクティスが参考になります。「すべてのフォームはWebMCPとして宣言すべきだ。実装コストは極めて低く、対応しなかった場合の代償はエージェントがサイトを使わないことではなく、エージェントがサイトをより悪い方法で使うことだ」という考え方です。

つまり、まずDeclarative APIですべてのフォームをカバーし、フォームでは表現できない操作をImperative APIで補完するという段階的アプローチが推奨されます。

Tool Contract設計のベストプラクティス

ここまでの技術的知識をもとに、良いTool Contractを設計するためのポイントを整理します。

説明文(description)の品質がツールの「発見可能性」を決める

GEO(Generative Engine Optimization)の文脈で言えば、tooldescriptionはWebMCP時代の「新しいメタディスクリプション」と言えるでしょう。AIエージェントは説明文を読んで「このツールを使うべきか」を判断します。

「フォームを送信する」のような曖昧な説明では、エージェントはツールの用途を判断できません。「キーワード、カテゴリ、価格上限を指定して商品カタログを検索する」のように、何ができて、どんなパラメータが必要かを具体的に書くべきです。

1フォーム = 1ツールの原則

1つのフォームは1つの意味的なアクションに対応させます。「検索と予約を1つのフォームでやる」のではなく、検索ツールと予約ツールを分離します。これにより、エージェントのインタラクションモデルが明確になり、エラーハンドリングもシンプルになります。

read/writeの明確な分類

ツールを登録する際は、それが読み取り操作か書き込み操作かを明確に分類します。読み取り専用にはreadOnlyHint: trueを設定し、書き込み操作にはrequestUserInteraction()による確認を組み込みます。awesome-webmcpリポジトリのセキュリティガイドラインは、「delete」「remove」を含む名前のツールにreadOnlyHintが設定されていると警告を出す仕組みを推奨しています。

入力は信頼しない

エージェントから渡されるパラメータは、公開APIのリクエストと同じレベルで検証すべきです。JSONスキーマによるクライアントサイドの型チェックだけでなく、サーバーサイドでの入力バリデーションも必須です。

まとめ — 「契約」の設計が新しい専門性になる

WebMCPの2つのAPIは、その設計思想の根底に「Web開発者が主導権を持つ」という原則があります。

Declarative APIは、既存のHTMLフォームに2つの属性を追加するだけで、そのフォームをAIエージェントのツールに変換する。実装コストの低さは驚異的です。

Imperative APIは、JavaScriptによるフルコントロールで、複雑な業務ロジックをツールとして公開する。SPAやダッシュボードのような動的アプリケーションに対応します。

そしてhuman-in-the-loopの設計——readOnlyHintrequestUserInteraction()toolautosubmitの制御——が、AIエージェントの利便性とユーザーの安全性を両立させます。

次回の第3回では、これらの知識を使って実際にWebサイトをAgent-Readyにする手順を、Chrome Canaryのセットアップからツール設計、テスト・デバッグまで、ハンズオン形式で解説します。

参考情報

この記事は「WebMCP:Webサイトがアクションを話す時代」シリーズの第2回です。

AI技術のビジネス活用やWebサイトのAIエージェント対応について、具体的なご相談はunTypeまでお気軽にお問い合わせください。

山下 太郎

山下 太郎

代表取締役 / CEO

2000年、Webデザイナーとしてこの世界に飛び込み、フリーランスを経て2007年に株式会社アンタイプを創業。AI時代の到来とともに、効率だけを追うAI活用に違和感を覚えながら、それでも最前線でツールを使い続ける。企業のWebとコミュニケーションを設計する仕事を通じて、「人間らしさとは何か」を問い直す視点を発信し続けている。

View Profile arrow_outward

Related

あわせて読みたい