アーキテクチャ詳解
Svelte MCPの内部アーキテクチャを詳しく解説します。公式リポジトリ sveltejs/mcp のコードを基に、処理フローや技術スタックを図解します。
リポジトリ構成
Svelte MCPは pnpm workspace による monorepo 構成を採用しています。この構成により、複数のパッケージを単一のリポジトリで効率的に管理し、コードの共有と依存関係の管理を簡素化しています。
モノレポ構成の主なメリットは、パッケージ間でコードを共有しやすいこと、一貫したバージョン管理ができること、そしてCI/CDパイプラインを統一できることです。Svelte MCPでは、スキーマ定義(mcp-schema)をサーバー実装(mcp-server)と stdio 通信層(mcp-stdio)で共有することで、型安全性を保ちながら効率的な開発を実現しています。
ディレクトリ構造
sveltejs/mcp/
├── apps/
│ └── mcp-remote/ # Remote版サーバー(Vercelデプロイ)
├── packages/
│ ├── mcp-schema/ # スキーマ定義
│ ├── mcp-server/ # サーバー実装
│ └── mcp-stdio/ # stdio通信
├── plugins/
│ └── svelte/ # Svelteプラグイン
├── docs/ # ドキュメントサイト
├── documentation/docs/ # MCPドキュメント(Markdownソース)
├── scripts/ # ビルド・同期スクリプト
├── .mcp.json # MCP設定
├── pnpm-workspace.yaml # ワークスペース設定
└── CLAUDE.md # AI向けプロンプト Local版 vs Remote版
Svelte MCPには2つのバージョンがあり、それぞれ異なるアーキテクチャと用途を持っています。
Local版は @sveltejs/mcp パッケージとして npm で配布され、開発者のローカルマシン上で動作します。MCP クライアント(Claude Code など)とは標準入出力(stdio)を介して通信し、ドキュメントデータはパッケージに同梱されたローカルファイルから読み込みます。このため、インターネット接続なしでも動作し、レスポンスも高速です。
Remote版は mcp.svelte.dev で提供されるサーバーレスサービスです。Vercel Edge Functions 上で動作し、PostgreSQL データベースに保存された最新のドキュメントを参照します。Voyage AI による Embeddings を活用した意味検索も可能で、常に最新の情報を提供できます。
比較表
| 項目 | Local版 | Remote版 |
|---|---|---|
| パッケージ | @sveltejs/mcp | mcp.svelte.dev/mcp |
| 通信方式 | stdio(標準入出力) | HTTP + SSE |
| データソース | ローカルファイル | PostgreSQL + Voyage AI |
| デプロイ | ローカル実行 | Vercel Edge |
| オフライン | ✅ 対応 | ❌ 要インターネット |
| 最新性 | パッケージ更新時 | 常に最新 |
Local版の利点
- オフラインで動作 - インターネット接続が不安定な環境でも安定して使用可能
- レスポンスが高速 - ネットワーク遅延がないため、即座に応答
- プライバシー保護 - ユーザーのコードがサーバーに送信されないため、機密性の高いプロジェクトでも安心
Remote版の利点
- インストール不要 - URL を設定するだけで即座に利用開始
- 常に最新のドキュメント - Svelte の公式ドキュメントが更新されると自動的に反映
- Embeddings による意味検索 - キーワードだけでなく、意味的に関連するドキュメントも検索可能
どちらを選ぶかは、オフライン対応の必要性、最新情報の重要度、プライバシー要件によって判断してください。日常的な開発には Local版、試用や CI/CD 統合には Remote版が適しています。
レイヤーアーキテクチャ
Svelte MCPは典型的なレイヤードアーキテクチャを採用しています。この設計パターンにより、各層の責務が明確に分離され、テスタビリティと保守性が向上しています。
各レイヤーは下位レイヤーにのみ依存し、上位レイヤーを参照しません。これにより、例えばデータベースの実装を変更しても、アプリケーション層以上のコードに影響を与えずに済みます。
各レイヤーの責務
| レイヤー | 責務 | 主要コンポーネント |
|---|---|---|
| プレゼンテーション | MCPプロトコル処理 | MCP SDK, HTTP Handler |
| アプリケーション | ツール・リソース定義 | Tools, Resources, Prompts |
| ドメイン | ビジネスロジック | Document/Analyze/Playground Service |
| インフラ | 外部サービス連携 | DB, Parser, ESLint, Voyage AI |
ドキュメント同期フロー
Remote版では、Svelteの公式ドキュメントを定期的に同期しています。
同期プロセスの詳細
ドキュメント取得(1時間ごと)
- GitHub の sveltejs/svelte リポジトリから Markdown を取得
- 変更があったファイルのみ処理
メタデータ抽出
- タイトル、説明、パスを抽出
use_casesフィールドを生成(LLMが検索しやすいように)
要約処理(Distillation)
- 完全なドキュメント(約800KB)をLLM用に要約
- コード例とキーコンセプトは保持
- 冗長な説明を削減
Embeddings生成
- Voyage AI で各セクションをベクトル化
- 意味検索を可能に
データベース保存
- Drizzle ORM で PostgreSQL に保存
- 古いバージョンは上書き
svelte-autofixer の内部処理
svelte-autofixer ツールは、eslint-plugin-svelte と svelte-eslint-parser を内部で使用しています。
処理フローの詳細
// 簡略化した擬似コード
async function svelteAutofixer(
code: string,
options: { async?: boolean; version?: number }
): Promise<{ issues: Issue[]; suggestions: Suggestion[] }> {
// 1. パーサー設定
const parserOptions = {
parser: svelteParser,
svelteFeatures: {
runes: options.version >= 5,
experimentalAsync: options.async
}
};
// 2. 構文解析
const ast = svelteParser.parse(code, parserOptions);
// 3. ESLint ルール適用
const linter = new ESLint({
plugins: { svelte: eslintPluginSvelte },
rules: {
'svelte/valid-compile': 'error',
'svelte/no-reactive-reassign': 'warn',
// ... その他のルール
}
});
const results = await linter.lintText(code);
// 4. 結果をフォーマット
return {
issues: results.filter(r => r.severity === 2),
suggestions: results.filter(r => r.severity === 1)
};
} 検出される問題の例
| カテゴリ | 例 | 重要度 |
|---|---|---|
| 構文エラー | 不正なRunes使用 | error |
| レガシー構文 | $: の使用 | warning |
| アンチパターン | on:click (Svelte 5) | warning |
| ベストプラクティス | 型注釈の欠如 | suggestion |
リクエスト処理フロー
MCPクライアントからのリクエストがどのように処理されるかを示します。
MCPプロトコルの主要メソッド
| メソッド | 用途 |
|---|---|
tools/list | 利用可能なツール一覧を返す |
tools/call | ツールを実行 |
resources/list | 利用可能なリソース一覧 |
resources/read | リソースの内容を取得 |
prompts/list | 利用可能なプロンプト一覧 |
prompts/get | プロンプトの内容を取得 |
データフロー
システム全体のデータの流れを示します。
データの種類
| データ | ソース | 処理 | 出力 |
|---|---|---|---|
| ドキュメント | GitHub | 要約 + Embedding | クエリ結果 |
| ユーザーコード | クライアント | 静的解析 | issues/suggestions |
| Playground | 生成コード | URLエンコード | Playground URL |
技術スタック
主要技術
| カテゴリ | 技術 | 用途 |
|---|---|---|
| 言語 | TypeScript | メイン言語(85%) |
| フレームワーク | SvelteKit | Webサーバー・サイト |
| MCP | MCP SDK | MCPプロトコル実装 |
| ORM | Drizzle | データベースアクセス |
| DB | PostgreSQL | ドキュメント保存 |
| パーサー | svelte-eslint-parser | Svelte構文解析 |
| Linter | eslint-plugin-svelte | 静的解析ルール |
| AI | Voyage AI | Embeddings生成 |
| デプロイ | Vercel | Edge Functions |
依存関係(主要パッケージ)
{
"dependencies": {
"@modelcontextprotocol/sdk": "^1.x",
"drizzle-orm": "^0.x",
"eslint-plugin-svelte": "^3.x",
"svelte-eslint-parser": "^0.x"
}
} スケーラビリティ
Remote版のスケーリング戦略
┌─────────────────────────────────────────────────────────┐
│ Vercel Edge Network │
├─────────────────────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Edge 1 │ │ Edge 2 │ │ Edge 3 │ │ Edge N │ │
│ │ (Tokyo) │ │ (SF) │ │ (London)│ │ (...) │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │ │
│ └────────────┴─────┬──────┴────────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ PostgreSQL │ │
│ │ (Neon) │ │
│ └───────────┘ │
└─────────────────────────────────────────────────────────┘ - Edge Functions: 世界中のエッジロケーションで実行
- コネクションプーリング: データベース接続の効率化
- キャッシュ: ドキュメントクエリ結果のキャッシュ
独自MCPサーバー構築への応用
Svelte MCPのアーキテクチャを参考に、独自のMCPサーバーを構築できます。
基本構造
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new Server({
name: 'my-mcp-server',
version: '1.0.0'
}, {
capabilities: {
tools: {},
resources: {},
prompts: {}
}
});
// ツール定義
server.setRequestHandler('tools/list', async () => ({
tools: [
{
name: 'my-tool',
description: 'My custom tool',
inputSchema: {
type: 'object',
properties: {
input: { type: 'string' }
}
}
}
]
}));
// ツール実装
server.setRequestHandler('tools/call', async (request) => {
const { name, arguments: args } = request.params;
if (name === 'my-tool') {
// カスタムロジック
return { content: [{ type: 'text', text: 'Result' }] };
}
});
// サーバー起動
const transport = new StdioServerTransport();
await server.connect(transport); 参考リソース
次のステップ
アーキテクチャを理解したら、 開発環境との統合 でプロジェクトへの導入方法を確認してください。