Declarative API は、属性を介して標準の HTML <form> 要素を WebMCP ツールに変換します。ブラウザは、フォーム入力から JSON スキーマを合成し、エージェントのインタラクションを処理します。
Angular Signal Forms: @angular/forms/signals の form() で構築されたフォームに toolname/tooldescription を追加しないでください。代わりに、provideExperimentalWebMcpForms() をアプリ プロバイダに追加し、experimentalWebMcpTool: { name, description } オプションを form() に渡します。Angular は、Imperative API を介してフォームを登録し、シグナルモデルからスキーマを構築して、検証と送信に接続します。両方のアプローチを使用すると、同じフォームが 2 回登録されます。
フォームの属性
toolname: ツールの一意の名前。tooldescription: ツールの機能と、エージェントがツールを使用するタイミング。フォームのフィールド、オプション、制限はリストしないでください。ブラウザは、フォーム コントロールから作成するスキーマにこれらをすでに含めています。toolautosubmit: (省略可)存在する場合、エージェントはユーザーの操作を待たずにフォームを送信できます。toolparamdescription:(省略可)JSON スキーマ内でプロパティの説明を定義する方法を指定します。コントロールのオプションや制限を繰り返すのではなく、値の意味を説明するために使用します(サンプル値など)。- 解決順序: ブラウザは、
toolparamdescriptionが存在する場合はそれを使用します。存在しない場合は、関連付けられた<label>のtextContentを使用します(ラベル付け可能な子孫はスキップされます)。ラベルが存在しない場合は、aria-descriptionにフォールバックします。 - グループ化(フィールドセット): 関連する要素のグループ(
<input type="radio">ボタンなど)に説明を添付するには、最も近い親<fieldset>要素にtoolparamdescriptionを配置して、パラメータ グループ全体に適用されるようにします。
- 解決順序: ブラウザは、
例
<form toolname="search-cars"
tooldescription="Perform a car make/model search"
toolautosubmit>
<label for="make">Vehicle Make</label>
<input type="text" id="make" name="make" required>
<label for="model">Vehicle Model</label>
<input type="text" id="model" name="model" toolparamdescription="e.g., 330i, F-150" required>
<button type="submit">Search</button>
</form>
JavaScript での送信の処理
エージェントがフォームを送信すると、SubmitEvent に agentInvoked(ブール値)と respondWith(promise) が含まれます。
document.querySelector('form').addEventListener('submit', (event) => {
event.preventDefault();
// Validate the form
const formValidationErrors = myFormIsValid();
if (formValidationErrors.length > 0) {
if (event.agentInvoked) {
const errorString =
'Validation failed: ' +
formValidationErrors
.map((err) => `${err.field} (${err.message})`)
.join(', ');
event.respondWith(Promise.resolve(errorString));
}
return;
}
const resultPromise = performAsyncSearch(new FormData(event.target));
// Return the result directly to the agent without navigation
if (event.agentInvoked) {
event.respondWith(resultPromise);
}
});
ライフサイクル イベント
document.modelContext は、エージェントがツールとのやり取りを開始または停止したときにイベントを発生させます。toolactivated はツールの実行開始時に発生し、toolcancel はキャンセル時に発生します。
// Starting in Chrome 156, these events are dispatched on `document.modelContext`.
// Older versions dispatch them on `window`. Feature-detect the event handler
// property to pick the right target for backward compatibility.
const targetFor = (type, listener, options) =>
(`on${type}` in (document.modelContext ?? {}) ? document.modelContext : window)
.addEventListener(type, listener, options);
targetFor('toolactivated', ({ toolName }) => {
console.log(`Tool "${toolName}" started execution.`);
});
targetFor('toolcancel', ({ toolName }) => {
console.log(`Tool "${toolName}" execution is cancelled.`);
});
視覚的なフィードバック(CSS)
エージェントがフォームを操作するときに、疑似クラスを使用してフォームをハイライト表示します。
:tool-form-active: エージェントがアクティブに使用している<form>要素に適用されます。:tool-submit-active: ブラウザがユーザーの確認のために一時停止したときに、送信ボタンに適用されます(toolautosubmitが省略されている場合)。
form:tool-form-active {
outline: 2px dashed blue;
background-color: rgba(0, 0, 255, 0.05);
}
button:tool-submit-active {
outline: 2px dashed red;
animation: pulse 2s infinite;
}
フォームの適合性(回避すべき場合)
Declarative API は、自己完結型の標準フォームに最適です。次のシナリオには適していません。
- 依存度の高いフィールド: 入力内容に応じてオプションや表示が変化するフォーム。合成スキーマでは、これらの依存関係を適切に表現できません。
- カスタム UI コンポーネント: 値を自動シリアル化しない非標準の入力(キャンバス、リッチテキスト エディタなど)に依存するフォーム。
- 複数ステップのウィザード: 複数のフォーム送信を必要とする複雑なワークフロー。この場合は、命令型 API または標準の DOM 操作の方が適しています。
toolautosubmit を使用するケース
- 読み取り専用のオペレーションとクエリ: 検索、フィルタ、詳細の取得、ステータスの確認(例: 車のモデルの検索、ディレクトリの検索、在庫状況の確認)。
- リスクが低く、元に戻せるアクション: ユーザーが手動で簡単に元に戻したり、調整したりできるフォーム アクション(カートへの商品の追加、クーポンコードの適用、下書きの保存、一時的なレイアウト オプションの設定など)。
toolautosubmit を省略するタイミング
- 破壊的または不可逆的なアクション: レコードの削除、システム構成のリセット、データベースのクリア。
- 金融取引や商取引に関するアクション: 購入手続きフォームの送信、送金、定期購入の支払いの承認、最終的な注文。
- ユーザーへの影響が大きいコミュニケーション: 最終的な求人応募の送信、他の実際のユーザーへのメールやメッセージの送信、一般公開コンテンツの公開。
- 機密性の高いアカウント設定: パスワードの変更、ユーザーのロールや権限の変更、お支払い情報やプロフィール情報の更新。
代替戦略
WebMCP Declarative API は、すべてのブラウザで安全に使用できます。WebMCP をサポートしていないブラウザでは、tool* 属性は無視され、<form> は通常の HTML フォームとして機能します。機能検出は必要ありません。