RSSAmplifier

Rick Cogley · Mar 23, 2026

SvelteKit移行リファレンスにWebMCPツールを実装する

0
Sign in to vote or save

Rick Cogley · Rick Cogley

AIエージェントが「Svelte 5でのuseEffect相当は?」と質問するとします。現状では2つの方法があります。ページのHTMLをスクレイピングしてパースするか、api/data.jsonを取得して100以上の項目からコンテキスト内でフィルタリングするか。どちらも動作しますが、トークンの無駄遣いです。

WebMCPを使えば、AIエージェントに第3の選択肢が生まれます。get_svelte_equivalent({ framework: 'react', concept: 'Side Effects' })を呼び出すだけで、構造化された回答が直接返ってきます。データは同じ。インターフェースがエージェント向けに最適化されています。

WebMCPとは

WebMCPはW3Cコミュニティグループのドラフトで、ブラウザにnavigator.modelContextを追加する仕様です。ウェブサイトがMCPツールをウェブページ上に直接登録できるようになります。Claudeのツール利用やCursorのコンテキストなど、エージェントフレームワークで使われるのと同じプロトコルです。サイトを閲覧するAIエージェントは、スクレイピングなしでツールを発見・呼び出せます。

Chrome Canary(146+)ではフラグ付きで利用可能、Microsoft EdgeはフラグやSettingsの操作は不要で、すぐに動作します。他のブラウザではMCP-Bプロジェクト@mcp-b/globalがポリフィルとして機能します。AnthropicのMCPサーバープロトコルとは別物で、WebMCPはクライアントサイドのブラウザAPIです。たまたま同じメッセージ形式を使っているだけです。

アプリの概要

svelte.cogley.jpは、React、Vue、Angular、そしてSvelte 4の概念がSvelte 5にどう対応するかを示す移行リファレンスです。概要、構文、アーキテクチャ、エコシステムの4カテゴリにわたる120以上の構造化マッピングがあります。各マッピングには概念名、ソースフレームワークのコード、Svelteの対応コード、注釈、ドキュメントリンク、そして日英バイリンガルサポートが含まれています。

データにはすでに機械向けインターフェースがあります。/api/data.jsonのJSON API、Accept: text/markdownによるコンテンツネゴシエーション、サイトを説明するllms.txtです。WebMCPはもう一つのレイヤーを追加します。エージェントがページ内で発見・呼び出せる型付きツールで、フェッチやパースが不要になります。

ロード戦略

ポリフィルは約285KB。ほとんどの訪問者は移行カードを閲覧する人間であり、ツールを呼び出すAIエージェントではないため、初期バンドルに含めるのは無駄です。ダイナミックインポートで対応します:

onMount(async () => {
  theme.init();
  language.init(data.lang);

  // ポリフィルモードを強制
  // Chrome Canaryのネイティブ modelContext は不完全
  //(listTools/registerTool が欠落)でクラッシュするため
  const win = window as unknown as Record<string, unknown>;
  win.__webModelContextOptions = { autoInitialize: false };
  const { cleanupWebModelContext, initializeWebModelContext } =
    await import('@mcp-b/global');
  cleanupWebModelContext();
  try {
    Object.defineProperty(navigator, 'modelContext', {
      value: undefined, configurable: true, writable: true,
    });
  } catch { /* non-configurable: 既にクリーン済み */ }
  initializeWebModelContext();

  const { registerMigrationTools } = await import('$lib/webmcp');
  registerMigrationTools();
});

Viteがポリフィルを独自のチャンクにコード分割します。__webModelContextOptionsフラグにより、ネイティブのnavigator.modelContextが存在するが不完全なブラウザ(Chrome Canaryなど)でのクラッシュを防ぎます。不完全なネイティブAPIを消去した後、initializeWebModelContext()が完全なポリフィルをインストールします。EdgeやネイティブAPIのないブラウザでは、cleanupWebModelContext()はno-opでポリフィルが通常通りインストールされます。

ツールの設計

6つの読み取り専用ツールが、AIエージェントの「XのSvelte版は?」といった質問に答えます。

search_mappings

概念、コード、注釈全体のフルテキスト検索。UIの検索ボックスと同じフィルタロジックです:

mc.registerTool({
  name: 'search_mappings',
  description: 'キーワードで移行マッピングを検索...',
  inputSchema: {
    type: 'object',
    properties: {
      query: { type: 'string', description: '検索キーワード' },
      framework: { type: 'string', enum: ['react', 'vue', 'angular', 'svelte4'] },
      category: { type: 'string', enum: ['overview', 'syntax', 'architecture', 'ecosystem'] },
      lang: { type: 'string', enum: ['en', 'ja'] },
    },
    required: ['query'],
  },
  annotations: { readOnlyHint: true },
  execute: async (args) => {
    // framework/categoryでプールをフィルタし、queryで部分文字列マッチ
    // マッチごとにframework/categoryコンテキスト付きの構造化JSONを返す
  },
});

「useState」で検索するとReactのエントリが、「routing」で検索すると4つのフレームワーク全体の結果が返ります。オプションのframeworkcategoryフィルタにより、エージェントは対象を絞り込めます。

get_svelte_equivalent

直接ルックアップ:フレームワークと概念名を与えると最適なマッチを返します。完全一致を優先し、部分文字列にフォールバックします。{ framework: 'react', concept: 'Reactive State' }を指定すると、コード例と注釈付きの$stateマッピングが得られます。

list_ecosystem_gaps

toフィールドに「No equivalent」や「⚠️」を含む項目。JSONフィルタリングでは表現しにくいが、ツール呼び出しとしては自然なクエリです。「Reactでできて Svelteでできないことは?」に対応します。

その他の3つのツール

  • get_site_info:概要情報。フレームワーク、カテゴリ、総数、API URL。いわゆる「Hello World」ツール。
  • get_changelog:最近の更新、バイリンガル対応、件数制限可能。
  • compare_frameworks:横並び比較。React、Vue、Angular、Svelte 4がそれぞれ同じ概念をどう扱うか。「Reactive State」を比較すると、useState vs ref() vs signal() vs let count = 0$stateが一発で返ります。

ツール登録モジュール

モジュール全体で約180行のTypeScript。共有ヘルパーがフィルタリングとマッチングを処理します:

function applyFilter(pool: MappingItem[], query: string): MappingItem[] {
  if (!query.trim()) return pool;
  const q = query.toLowerCase();
  return pool.filter(
    (item) =>
      item.concept.toLowerCase().includes(q) ||
      item.concept_ja?.toLowerCase().includes(q) ||
      item.from?.toLowerCase().includes(q) ||
      item.to?.toLowerCase().includes(q) ||
      item.notes?.toLowerCase().includes(q) ||
      item.notes_ja?.toLowerCase().includes(q) ||
      item.checklist?.some((s) => s.toLowerCase().includes(q)) ||
      item.checklist_ja?.some((s) => s.toLowerCase().includes(q))
  );
}

+page.svelte$derivedブロックと同じロジックです。UIとツールは同一のフィルタ関数で同一の検索を行います。1つの関数、2つの消費者。

すべてのツールはMCPの標準コンテンツ形式({ content: [{ type: 'text', text: JSON.stringify(...) }] })を返し、annotations: { readOnlyHint: true }を設定しています。クエリのみ、ミューテーションなし。

テスト

Microsoft Edgeはそのまま動作します。Chrome CanaryWebMCPフラグが必要です(chrome://flags → 「WebMCP for testing」)。またはMCP-B拡張機能をインストール。コンソールを開いて:

// ツール一覧
navigator.modelContext.listTools()
// → 名前、説明、入力スキーマを持つ6つのツールの配列

// useStateを検索
await navigator.modelContext.callTool({
  name: 'search_mappings',
  arguments: { query: 'useState' }
})

// 直接ルックアップ
await navigator.modelContext.callTool({
  name: 'get_svelte_equivalent',
  arguments: { framework: 'react', concept: 'Reactive State' }
})

// フレームワーク間比較
await navigator.modelContext.callTool({
  name: 'compare_frameworks',
  arguments: { concept: 'Reactive State' }
})

ネイティブサポートのないブラウザでは、ポリフィルがUIの変化やコンソールエラーなしにサイレントにロードされます。

Chrome CanaryでWebMCPツールをテストしている画面。Svelte 5移行ガイドとコンソール出力が表示されている。

llms.txtの更新

llms.txtにWebMCPセクションを追加し、6つのツール全てとそのパラメータを記載しました。llms.txt経由でサイトを発見したエージェントは、WebMCPをサポートしているかどうかを推測したりJSONフェッチにフォールバックしたりする必要がなく、ツールを直接呼び出せることがわかります。

アップデート:Svelte 4 → 5 アップグレードデータ

2026年2月22日追記。 4番目のソースフレームワークとしてSvelte 4を追加しました。他の3つとは異なり、クロスフレームワーク移行ではなく、すでにSvelteを使っている開発者がv4からv5へ移行するためのアップグレードガイドです(runes、snippets、新イベント構文、stores → リアクティブクラス)。

25の新しいマッピングを含みます。概要4件、構文12件、アーキテクチャ5件、エコシステム4件。概要カテゴリには新しいカードタイプ、ChecklistCardがあり、通常の2カラムコード比較の代わりにステップバイステップの移行チェックリストを表示します。

4つの機械可読インターフェースすべてを更新しました:

  • WebMCPツールsearch_mappingsget_svelte_equivalentframework: 'svelte4'を受け付け、チェックリストテキストを検索対象に含み、localizeItemがチェックリスト配列を返すようになりました
  • llms-full.txt:Svelte 4セクションがチェックリストステップを番号付きリストとして表示
  • llms.txt:フレームワーク一覧とツール説明を更新
  • data.json:svelte4データ構造を自動的に含む

エージェントはget_svelte_equivalent({ framework: 'svelte4', concept: 'Props' })export let proplet { prop } = $props()を学んだり、search_mappings({ query: 'stores', framework: 'svelte4' })でstores → リアクティブクラスの移行パスを見つけたりできます。

コスト

登録モジュールは約200行のTypeScript、6つのツール。https://svelte.cogley.jp の初期ページバンドルへの追加バイトはゼロです。すべてがダイナミックにロードされるため、ポリフィルチャンク(429KB)はブラウザがまだネイティブサポートしていない場合にのみ起動します。

移行データはすでに構造化されクエリ可能でした。いまや4つのフレームワークとSvelte 4 → 5アップグレードパスを含む120以上のマッピングにより、AIエージェントがスクレイピングなしで使えるインターフェースを備えたサイトになりました。

Read the original on cogley.jp

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.