1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Web標準仕様を AI に教える ─ w3c-mcp の設計と実装

1
Last updated at Posted at 2026-01-25

はじめに

Web開発をしていて、こんな経験はないでしょうか?

  • 「Service Worker の waitUntil() って、どんな引数を取るんだっけ...」
  • display: grid のプロパティ、何があったか全部思い出せない」
  • 「PWA を作りたいけど、関連する仕様が多すぎて何から読めばいいかわからない」

MDN や仕様書を検索すれば答えは見つかります。でも、AI アシスタントと一緒にコーディングしているとき、毎回ブラウザに切り替えて検索するのは面倒ですよね。

そこで、AI が直接 Web 標準仕様にアクセスできる MCP サーバーを開発しました。

これで Claude に「Service Worker の API 定義を教えて」と聞くだけで、公式仕様から正確な情報を取得できるようになります。

TL;DR

  • W3C/WHATWG/IETF の公式 Web 仕様データにアクセスする MCP サーバーを開発・公開
  • WebIDL 定義CSS プロパティHTML 要素PWA 関連仕様を構造化データとして取得可能
  • 11 個の専用ツールで、仕様の検索・閲覧・依存関係分析を実現
  • 275 ダウンロードを達成(公開3日時点)
# すぐに試せます
npx @shuji-bonji/w3c-mcp

背景: なぜ Web 仕様への直接アクセスが必要か

AI アシスタントの「知識の壁」

ChatGPT や Claude などの AI アシスタントは、Web 開発の質問に答えることができます。しかし、その知識には限界があります。

課題 説明
知識のカットオフ 学習データ以降に追加された仕様を知らない
曖昧な記憶 細かい API シグネチャを正確に覚えていないことがある
情報源の不明確さ どの仕様書のどのバージョンに基づいているか不明

「公式仕様」という唯一の真実

Web 標準の正確な情報は、W3C/WHATWG/IETF の公式仕様書にあります。そして、これらの仕様は機械可読なデータとしても公開されています。

W3C は webref というプロジェクトで、仕様から抽出した構造化データを提供しています:

┌─────────────────────┐
│  Web Specifications │  人間が読む仕様書
├─────────────────────┤
│  webref データ       │  機械可読な構造化データ ← ここにアクセス
├─────────────────────┤
│  w3c-mcp            │  AI と人の共通理解基盤 ← このプロジェクト
├─────────────────────┤
│  AI アシスタント     │  正確な仕様に基づいた回答
└─────────────────────┘

使用するデータソース

この MCP サーバーは、W3C が公式にメンテナンスしている以下のパッケージを使用しています:

パッケージ 説明 用途
web-specs 全 Web 仕様のメタデータ 仕様一覧・検索
@webref/idl WebIDL 定義 JavaScript API 定義
@webref/css CSS プロパティ・値 CSS プロパティ検索
@webref/elements HTML 要素定義 HTML 要素情報

つまり、MDN よりも上流の、仕様書そのものから抽出されたデータを使用しています。

提供するツール

w3c-mcp は 11 個のツールを提供します。用途別に整理すると:

仕様の検索・取得

ツール 説明
list_w3c_specs W3C/WHATWG/IETF 仕様一覧(組織・カテゴリでフィルタ可能)
get_w3c_spec 特定の仕様の詳細情報
search_w3c_specs キーワードで仕様を検索

WebIDL(JavaScript API 定義)

ツール 説明
get_webidl 仕様の WebIDL インターフェース定義
list_webidl_specs WebIDL がある仕様一覧

CSS

ツール 説明
get_css_properties CSS プロパティ定義(仕様別 or 全体)
list_css_specs CSS プロパティ定義がある仕様一覧

HTML 要素

ツール 説明
get_html_elements HTML 要素定義
list_element_specs 要素定義がある仕様一覧

PWA

ツール 説明
get_pwa_specs PWA 関連仕様一覧(コア仕様のみ取得も可能)
get_spec_dependencies 仕様の依存関係

実際の出力例

get_webidl: Service Worker API

「Service Worker の API 定義を見せて」と聞くと:

// get_webidl({ shortname: "service-workers" })

interface ServiceWorker : EventTarget {
  readonly attribute USVString scriptURL;
  readonly attribute ServiceWorkerState state;
  void postMessage(any message, sequence<object> transfer);
  void postMessage(any message, optional PostMessageOptions options = {});
  attribute EventHandler onstatechange;
};

interface ServiceWorkerRegistration : EventTarget {
  readonly attribute ServiceWorker? installing;
  readonly attribute ServiceWorker? waiting;
  readonly attribute ServiceWorker? active;
  readonly attribute NavigationPreloadManager navigationPreload;
  readonly attribute USVString scope;
  readonly attribute ServiceWorkerUpdateViaCache updateViaCache;
  
  [NewObject] Promise<void> update();
  [NewObject] Promise<boolean> unregister();
  // ...
};

これで「update()Promise<void> を返す」「scopeUSVString 型」といった正確な型情報がわかります。

get_css_properties: CSS Grid

// get_css_properties({ spec: "css-grid-1" })

{
  "spec": "css-grid-1",
  "properties": {
    "grid": {
      "name": "grid",
      "value": "<'grid-template'> | <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? | ...",
      "initial": "see individual properties",
      "appliesTo": "grid containers",
      "inherited": "no",
      "percentages": "see individual properties",
      "computedValue": "see individual properties"
    },
    "grid-template-columns": { ... },
    "grid-template-rows": { ... },
    "grid-auto-flow": { ... },
    // ... 全18プロパティ
  }
}

get_pwa_specs: PWA 関連仕様

「PWA に必要な仕様を教えて」と聞くと:

// get_pwa_specs({ coreOnly: true })

{
  "category": "PWA Core Specifications",
  "count": 4,
  "specs": [
    {
      "shortname": "service-workers",
      "title": "Service Workers",
      "url": "https://w3c.github.io/ServiceWorker/",
      "organization": "W3C"
    },
    {
      "shortname": "appmanifest",
      "title": "Web Application Manifest",
      "url": "https://w3c.github.io/manifest/",
      "organization": "W3C"
    },
    {
      "shortname": "push-api",
      "title": "Push API",
      "url": "https://w3c.github.io/push-api/",
      "organization": "W3C"
    },
    {
      "shortname": "notifications",
      "title": "Notifications API Standard",
      "url": "https://notifications.spec.whatwg.org/",
      "organization": "WHATWG"
    }
  ]
}

さらに coreOnly: false にすると、Background Sync、Web Share、Badging API など関連する全仕様を取得できます。

アーキテクチャ

モジュール構成

src/
├── index.ts              # MCP サーバーエントリポイント
├── data/
│   └── loader.ts         # データロード(キャッシュ付き)
├── tools/                # ツール実装
│   ├── list-specs.ts
│   ├── get-spec.ts
│   ├── search-specs.ts
│   ├── get-webidl.ts
│   ├── get-css.ts
│   ├── get-elements.ts
│   └── get-pwa-specs.ts
├── schemas/
│   └── index.ts          # Zod バリデーションスキーマ
├── errors/
│   └── index.ts          # カスタムエラークラス
├── utils/
│   └── logger.ts         # デバッグログ
└── types/
    └── index.ts          # TypeScript 型定義

データフロー

┌────────────────┐
│  Claude/Cursor │  MCP クライアント
└───────┬────────┘
        │ MCP Protocol
        ▼
┌────────────────┐
│   w3c-mcp      │  MCP サーバー
├────────────────┤
│  Zod Validation│  入力検証
├────────────────┤
│  Tool Handlers │  ツール実行
├────────────────┤
│  Data Loader   │  キャッシュ付きローダー
└───────┬────────┘
        │
        ▼
┌────────────────┐
│  webref data   │  W3C 公式データ(npm パッケージ)
└────────────────┘

技術的なポイント

1. Promise-based シングルトンキャッシュ

データの読み込みは一度だけ行い、以降はキャッシュを返します。さらに、同時リクエスト時の重複ロードを防止しています。

// src/data/loader.ts
let specsPromise: Promise<SpecDetail[]> | null = null;
let specsIndex: Map<string, SpecDetail> | null = null;

export async function loadSpecs(): Promise<SpecDetail[]> {
  if (!specsPromise) {
    specsPromise = (async () => {
      const specs: SpecDetail[] = await import('web-specs').then(m => m.default);
      
      // インデックス構築(O(1) 検索用)
      specsIndex = new Map(specs.map(s => [s.shortname, s]));
      
      return specs;
    })();
  }
  return specsPromise;
}

// O(1) で仕様を検索
export function findSpec(shortname: string): SpecDetail | undefined {
  return specsIndex?.get(shortname);
}

これにより:

  • 同時リクエストでの重複ロード防止
  • findSpec が O(1) で検索可能(Map インデックス)

2. 起動時の並列プリロード

MCP サーバー起動時に、必要なデータを並列で事前ロードします。

// src/index.ts
async function main() {
  // サーバー起動時に並列でデータをプリロード
  await preloadAll();
  
  const transport = new StdioServerTransport();
  await server.connect(transport);
}

// src/data/loader.ts
export async function preloadAll(): Promise<void> {
  await Promise.all([
    loadSpecs(),
    loadWebIDLRaw(),
    loadCSS(),
    loadElements()
  ]);
}

これにより、起動時間約 70ms で全データがメモリに展開され、ツール呼び出し時のレスポンスが高速化されます。

3. Zod による入力バリデーション

すべてのツール引数を Zod でバリデーションし、型安全性とエラーメッセージの品質を両立しています。

// src/schemas/index.ts
import { z } from 'zod';

export const ListSpecsSchema = z.object({
  organization: z.enum(['W3C', 'WHATWG', 'IETF', 'all']).optional(),
  keyword: z.string().optional(),
  category: z.string().optional(),
  limit: z.number().min(1).max(500).optional().default(50)
});

// 使用時
const validation = validateInput(ListSpecsSchema, args);
if (!validation.success) {
  throw new ValidationError(validation.error);
}
const result = await listSpecs(validation.data);

不正な引数が渡された場合、エラーメッセージで何が問題かを明確に伝えます。

4. 構造化エラーレスポンス

エラー発生時も、構造化された JSON で応答します。さらに、仕様が見つからない場合はサジェストを提供します。

// src/errors/index.ts
export class SpecNotFoundError extends W3CMCPError {
  public suggestions?: string[];

  constructor(shortname: string, suggestions?: string[]) {
    const message = suggestions?.length
      ? `Specification "${shortname}" not found. Did you mean: ${suggestions.join(', ')}?`
      : `Specification "${shortname}" not found.`;
    super(message);
    this.suggestions = suggestions;
  }
}

出力例:

{
  "error": "SpecNotFoundError",
  "message": "Specification \"service-worker\" not found. Did you mean: service-workers?",
  "suggestions": ["service-workers"]
}

タイポしても、正しい shortname を教えてくれるので便利です。

5. 検索アルゴリズムの最適化

仕様検索では、スコアリングによる関連度順ソートを実装しています。

// src/tools/search-specs.ts
function calculateScore(spec: SpecDetail, query: string): number {
  const lowerQuery = query.toLowerCase();
  const lowerTitle = spec.title.toLowerCase();
  const lowerShortname = spec.shortname.toLowerCase();
  
  let score = 0;
  
  // 完全一致は最高スコア
  if (lowerShortname === lowerQuery) return 100;
  if (lowerTitle === lowerQuery) return 95;
  
  // 前方一致
  if (lowerShortname.startsWith(lowerQuery)) score += 50;
  if (lowerTitle.startsWith(lowerQuery)) score += 40;
  
  // 部分一致
  if (lowerShortname.includes(lowerQuery)) score += 30;
  if (lowerTitle.includes(lowerQuery)) score += 20;
  
  return score;
}

使い方

Claude Desktop での設定

Claude Desktop の設定ファイルに追加:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "w3c": {
      "command": "npx",
      "args": ["-y", "@shuji-bonji/w3c-mcp"]
    }
  }
}

Claude Code での設定

プロジェクトの .claude/settings.json に追加:

{
  "mcpServers": {
    "w3c": {
      "command": "npx",
      "args": ["-y", "@shuji-bonji/w3c-mcp"]
    }
  }
}

Cursor での設定

.cursor/mcp.json に追加:

{
  "mcpServers": {
    "w3c": {
      "command": "npx",
      "args": ["-y", "@shuji-bonji/w3c-mcp"]
    }
  }
}

Claude への依頼例

Service Worker の WebIDL 定義を見せてください。
CSS Grid のプロパティ一覧を取得してください。
PWA を作るのに必要な仕様を教えてください。
「storage」に関連する仕様を検索してください。

MCP 連携のユースケース

w3c-mcp は単体でも便利ですが、他の MCP サーバーと組み合わせるとさらに強力になります。

rfcxml-mcp との連携

┌─────────────────┐     ┌─────────────────┐
│  w3c-mcp        │     │  rfcxml-mcp     │
│  Web標準仕様     │ ──▶ │  RFC 仕様       │
│  (WebIDL/CSS)   │     │  (MUST/SHOULD)  │
└─────────────────┘     └─────────────────┘
         │                       │
         └───────────┬───────────┘
                     ▼
           プロトコル実装の完全ガイド

例えば:

  1. w3c-mcp で Fetch API の WebIDL 定義を取得
  2. rfcxml-mcp で HTTP/2 (RFC 9113) の MUST 要件を取得
  3. 両方を組み合わせて、仕様準拠のコードを生成

deepl-mcp との連携

WebIDL の日本語コメント付きコード生成:

  1. w3c-mcp で WebIDL 定義を取得
  2. deepl-mcp でコメントを日本語化
  3. 日本語コメント付きの TypeScript 型定義を生成

開発の振り返り

実際に作ってみて感じたこと

正直なところ、最初は「MDN 見ればいいじゃん」と思っていました。でも実際に MCP サーバーとして実装してみると、AI との協調作業の効率が明らかに変わりました

ブラウザに切り替えて検索する手間がなくなるだけで、コーディングの「フロー状態」が途切れにくくなります。小さなことですが、積み重なると大きな違いになります。

工夫した点

  1. データソースの選択: MDN ではなく webref を選んだのは、仕様からの直接抽出データだから
  2. 起動時プリロード: 初回リクエストの遅延をなくすため
  3. サジェスト機能: shortname のタイポでハマらないように
  4. PWA ツールの追加: 自分が PWA 開発中だったので、関連仕様をまとめて取得したかった

今後の課題

  • 日本語検索対応: 現在は英語のみ
  • 仕様の diff 表示: バージョン間の変更点を見たい
  • より詳細なフィルタリング: ステータス(Draft/Recommendation)でのフィルタ

まとめ

w3c-mcp は、AI アシスタントが Web 標準仕様に直接アクセスするための MCP サーバーです。

  • WebIDL、CSS、HTML 要素の定義を構造化データとして取得
  • PWA 関連仕様をまとめて取得
  • 高速なレスポンス(起動時プリロード + Map インデックス)
  • 親切なエラーメッセージ(サジェスト付き)

「あの API の引数なんだっけ?」という質問に、公式仕様に基づいた正確な回答が得られるようになります。

リンク

おわりに

Web 開発において、「仕様を正確に理解する」ことは非常に重要です。でも、膨大な仕様書を読み込むのは大変ですよね。

w3c-mcp を使えば、AI アシスタントが仕様書を代わりに読んで、必要な情報を整理してくれます。

ぜひ、日々の Web 開発に活用してみてください!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?