MCP Hub
Chronicle の内部で動作する、実際に機能する集約型 MCP サーバーです。任意の AI ツールを 1 つのエンドポイントに向けるだけで、あらゆるツールにわたって設定したすべての MCP サービスが、ツールごとのポリシー、プロジェクトスコープ、組み込みインスペクター付きで、それを通じて見えるようになります。
多くの開発者は、同じ MCP サーバーを 4 つの異なる設定ファイル(~/.claude.json、~/.cursor/mcp.json、~/.gemini/settings.json、~/.codex/config.toml)へコピー&ペーストして抱え込み、それぞれが同期からずれていきます。MCP Hub は、その乱立を単一のコントロールプレーンに置き換えます。Chronicle は 1 つの Streamable-HTTP エンドポイントを公開し、あなたに代わってすべての上流サービスへ接続し、それらのツールを安定した名前空間付きの名前で再公開します。設定は一度きり、有効化/無効化やスコープの設定は中央で行い、ハブに向けたすべてのツールが同じ統制されたセットを見ます。これは Skills Hub と共有する Takeover → Centralize → Distribute パターンに従います。
Local-first: ハブは設定した上流サーバー(その一部はリモートかもしれません)へ接続しますが、ハブ自体はあなたのマシン上で動作し、localhost にバインドし、リクエストのオリジンを検証します。Chronicle が MCP トラフィックを仲介するために自宅(サーバー)へ通信することはありません。
エンドポイント
ハブは、次の場所で動作する本物の MCP サーバーです。
http://localhost:4173/mcp # npm run dev
http://localhost:41730/mcp # npm run desktop / npm run standaloneこれは 2025-03-26 MCP 仕様に対して Streamable HTTP を話します(server/mcp/hub.js)。
- POST が JSON-RPC を運びます。
initialize、tools/list、tools/call、ping、notifications/*が処理されます。JSON-RPC のバッチは拒否されます。 initialize時、ハブはセッションを発行し、それをMCP-Session-Idレスポンスヘッダーで返します。クライアントはそれ以降のリクエストでそれをエコーバックします。serverInfoはchronicle-mcp-hubとして報告します。- オリジン検証 は、
localhost/127.0.0.1でないブラウザのOriginをすべて拒否します(CSRF 対策)。(Originを送らない)非ブラウザクライアントは通過します。 - DELETE はセッションを終了します。GET は
405を返します。ハブはサーバープッシュ型の SSE ストリームを提供しないため、クライアントは単純に POST のみのモードへフォールバックします。
任意の MCP 対応ツールをその URL に向けてください。ツール自身の MCP 設定で、url がハブのエンドポイントである HTTP サーバーのエントリを追加します。
{
"mcpServers": {
"chronicle": { "type": "http", "url": "http://localhost:4173/mcp" }
}
}名前空間付きツール
すべての上流ツールは service__tool(区切りはダブルアンダースコア)として再公開されます。filesystem サーバーの read_file ツールは filesystem__read_file になり、各ツールの説明には [service] が接頭辞として付くので、由来がモデルにとって明白になります。クライアントが名前空間付きの名前で tools/call を呼び出すと、ハブはそれを分割し、所有するサービスを見つけ、リクエストを適切な上流へルーティングします。上流は、あなたが設定した stdio 子プロセス と リモート HTTP サーバー の混在です。
MCP Hub ページのヘッダーは、ライブなステータスを表示します。エンドポイント、有効なサービス数、接続中のクライアントセッション数、そして接続済みの stdio 子プロセスごとの緑のピル(その PID とツール数)です。
設定の引き継ぎ(Config takeover)
MCP Hub → Config takeover を開くと、すでに設定済みの内容をインポートできます。Chronicle は次をスキャンします(server/mcp/registry.js の scanMcpConfigs())。
| ソース | ファイル |
|---|---|
| Claude Code(ユーザー) | ~/.claude.json |
| Claude Code(プロジェクト) | 各インポート済みプロジェクト内の .mcp.json |
| Cursor | ~/.cursor/mcp.json |
| Gemini CLI | ~/.gemini/settings.json |
| Codex | ~/.codex/config.toml(TOML の [mcp_servers.*] セクション) |
発見された各サーバーは分類されるので(classifyScan())、インポートが何をするのかを正確に把握できます。
- New — まだハブに入っていない。
- Updated — 同じソースからすでにインポート済みだが、その command/args/env/url/headers が変わった。
- Conflict — 同名のサービスが存在するが、別の ツールの設定から来ている(定義が食い違っている)。
- Unchanged — すでに登録済みのものと同一。スキップされる。
Import をクリックすると、Chronicle は何かを書き込む 前に すべてのソースファイルを ~/.chronicle/backups/mcp/<timestamp>/ へバックアップし(直近 5 セットを保持)、その後で New/Updated/Conflict のエントリを登録します。元の設定ファイルが 書き換えられることは決してありません。引き継ぎは Chronicle への 一方向のコピーなので、後でハブを外しても、ツールは元のままの状態で残ります。
サービスの管理
Services タブには、登録済みのすべての上流が、そのトランスポート(stdio / http / sse)、由来する設定、そしてコマンドまたは URL とともに一覧表示されます。
- サービスごとの有効化 / 無効化 — 無効なサービスは
tools/listから隠され、tools/callを拒否します。 - Remove from hub はレジストリのエントリのみを削除します。由来するソース設定には手を触れません。
- シークレットはマスクされます。 キーが認証情報のように見える(
token、key、secret、pass、auth)か、値が長い環境変数、そしてすべてのヘッダー値は、あらゆる API 出力でマスクされます(maskService())。Chronicle は上流呼び出しを行うために実際の値をローカルに保存しますが、それらを生のまま UI へ返すことはありません。
ツールポリシー
サーバー全体を有効にするのは、しばしば粗すぎます。読み取りツールは欲しいが書き込みツールは要らない、という場合です。サービスの ⛭ policy をクリックすると、そのツールパネルが開きます。任意のツールのチェックを外すと、それは tools/list から隠される と同時に tools/call でブロックされます。ブロックされた呼び出しは、黙って破棄されるのではなくインスペクターのログに記録されるので、クライアントが何に到達しようとしたかを確認できます。ポリシーはサービスごとに保存されるため(setDisabledTools())、同じ統制された表面が、ハブを通じて接続するすべてのツールに適用されます。
プロジェクトスコープ(MCP Roots)
サービスを プロジェクトパスにスコープ して、そのプロジェクト内で作業しているクライアントにのみ表示されるようにできます。クライアントが接続すると、ハブはその root を(明示的な x-chronicle-root ヘッダー、または initialize パラメータ内の rootUri / workspaceFolders から)読み取り、最長プレフィックス一致(servicesForRoot())で tools/list をルーティングします。
- スコープされたプロジェクト内に root を持つクライアントは、最も深く一致する スコープ済みサービスに加えて、すべてのスコープなし(グローバル)サービスを見ます。
- root を持たない、あるいはどのスコープにも属さない root を持つクライアントは、グローバルサービスのみを見ます。
これにより、リポジトリごとに別々の設定ファイルを維持することなく、プロジェクト固有のデータベースやデプロイサーバーを無関係なセッションから遠ざけられます。
サービスごとの認証情報
リモート HTTP サービスについては、サービスに ベアラートークン を紐づけられます(setCredential())。ハブは上流呼び出し時にそれを Authorization: Bearer … ヘッダーとして適用し、UI ではどこでもマスクします。トークンはサービス定義とともにローカルに保存されます。
インスペクター
Inspector タブは、Chronicle を離れずにハブをデバッグするための組み込み MCP クライアントです。
- 手動でのツール呼び出し — ライブ一覧から任意の名前空間付きツールを選び、JSON の引数を与えて呼び出します。結果はインラインでレンダリングされます。上流サービスの接続に失敗した場合は、そのエラーがサービスごとにここへ表示されます。
- JSON-RPC ログ —
/mcpを通過した直近のリクエストとレスポンス(受信、送信、ポリシーによるブロック、通知)の、新しい順のリングバッファです。ブロックされたtools/callやあらゆるルーティングエラーが表面化するのはここです。
これを使って、引き継ぎがうまくいったことの確認、ツールポリシーが正しくフィルタリングしていることの検証、あるいは接続中の AI ツールが見ているものの再現ができます。
パターンの全体像
- Takeover — ツール設定に散らばった MCP サーバーを、自動バックアップとともにインポートします。
- Centralize — 有効化/無効化、プロジェクトへのスコープ、ツールポリシーの設定、認証情報の紐づけを 1 箇所で行います。
- Distribute — Claude Code、Cursor、Gemini、あるいは任意の MCP クライアントを
http://localhost:4173/mcpに向けます。それらはすべて同じ統制された名前空間付きツールセットを共有し、ポリシーの変更が一度にどこにでも適用されます。
上流接続がどのようにプールされるか、tools/list の集約とエラー処理がどう動くかといったワイヤーレベルの詳細については、以下のアーキテクチャノートを参照してください。
関連項目
- Skills Hub — エージェントスキルに適用された、同じ Takeover → Centralize → Distribute パターン。
- セキュリティと共有 — リダクション、pre-tool-use ガード、そしてセッションの安全な共有リンク。
- MCP と Skills の内部構造 — レジストリ、上流接続レイヤー、そして Streamable-HTTP の実装。
- API リファレンス —
/mcpエンドポイント仕様と/api/mcp/*管理ルート(両者は互いに別物です)。