mcpField
A
autorouter

autorouter

ローカル
github.comAI・エージェント01 週間前に更新

autorouter について

autorouterは、設定済みサーバー、スキル、プラグインの機能を索引し、検索を通じて少数の候補を提示するMCPサーバーです。多くの機能を扱うコーディングエージェント環境向けに、常時読み込むツールスキーマを減らし、選んだ呼び出しを元のサーバーへ転送します。

主な機能

  1. 01機能の検索と再ランク付け
  2. 02下流サーバーへの呼び出し転送
  3. 03ツール、プロンプト、リソースの索引
  4. 04スキル、コマンド、エージェントの検索
  5. 05ホスト設定のインポート

活用シーン

  1. 01エージェントのコンテキストに読み込むスキーマの削減
  2. 02タスクの説明からツールを検索
  3. 03選択した呼び出しを該当サーバーへ転送
  4. 04auditとdoctorによるコンテキスト使用量の確認

MCP 対応

検索、説明、呼び出しのツールを提供し、設定済みの下流MCPサーバーに接続します。各サーバーのツール、プロンプト、リソースを索引し、選択した機能をルーター経由で呼び出します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"webb-ventures-autorouter": {
"command": "npx",
"args": [
"-y",
"autorouter-mcp"
],
"env": {
"AUTOROUTER_CONFIG": "<AUTOROUTER_CONFIG>",
"AUTOROUTER_IMPORT": "<AUTOROUTER_IMPORT>",
"AUTOROUTER_SELECTOR_MODE": "<AUTOROUTER_SELECTOR_MODE>",
"AUTOROUTER_SELECTOR_MODEL": "<AUTOROUTER_SELECTOR_MODEL>"
}
}
}
}
起動コマンドnpx -y autorouter-mcp
設定が必要な環境変数
AUTOROUTER_CONFIGPath to autorouter.json. Defaults to the standard lookup chain (./.autorouter.json, ~/.config/autorouter/config.json, …).
AUTOROUTER_IMPORTComma-separated harness configs to import: claude, codex, cursor, vscode, plugins.
AUTOROUTER_SELECTOR_MODEReranker backend: auto | sampling | cli | api | off.
AUTOROUTER_SELECTOR_MODELModel the selector reranks with, e.g. haiku.

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmautorouter-mcp0.3.1

ツール

4

掲載時のツール一覧 · 1 週間前に更新

パラメーター型必須説明
kindenumいいえ任意:結果を特定の種類の機能に限定します。tool | skill | prompt | resource | command | agent
limitnumberいいえ結果の最大数(デフォルトは 8)。
querystringはい達成したいことを平易な言葉で記述します。推測したツール名ではなく、目標を説明してください。
serverstringいいえ任意:結果を 1 つのプロバイダーに限定します。

詳細

autorouter

CI npm licence: MIT

あらゆるツールの代わりに、ひとつのツールを。

登録した各 MCP サーバーは、ツールの一覧全体(名前、説明、JSON スキーマ)を、毎回のターンでシステムプロンプトに注入します。5 つのサーバーといくつかのスキルだけでも、タスクで使うかどうかにかかわらず、常に 20~30k トークンものオーバーヘッドが発生するのが一般的です。また、ツールの選択も 悪化 します。候補が増えるほど、選択を誤りやすくなるためです。

autorouter は、安定した少数のツールを公開し、それ以外を検索の背後に隠す MCP サーバーです。モデルは自然言語で必要なものを尋ね、スキーマ付きの候補を少数、ランキング順に受け取って、そのうちの 1 つをルーター経由で呼び出します。実際に使われたツールは実際のツール一覧に昇格されるため、コンテキストは、使うかもしれないツールではなく、セッションで必要なものに使われます。

find_capabilities({ query: "inspect recent deployment errors" })
  → mcp:deployments/get_logs       (tool)
  → mcp:monitoring/search_events   (tool)
  → skill:incident-triage          (skill)

describe_capability({ id: "mcp:deployments/get_logs" })
call_capability({ id: "mcp:deployments/get_logs", arguments: { lines: 50 } })

インストール

npm install -g autorouter-mcp        # or: npx autorouter-mcp <command>
autorouter init --target claude      # claude | codex | cursor | vscode
autorouter adopt --target claude     # ← the step that actually saves context

これは、すでに設定済みの内容を一度だけ移行するためのものです。新しいサーバーには必要ありません。MCP サーバーの追加をご覧ください。

adopt は必須です。 既存のサーバーと並行してルーターを登録すると、スキーマは引き続き読み込まれ、ルーターがさらに4つのツールを追加するため、合計は 増加 します。adopt は下流のエントリーをハーネスの設定からルーター自身の設定に移すため、ハーネスが読み込むサーバーは1つになり、ルーターは引き続きすべてのサーバーにアクセスできます。

MCP サーバーだけがコンテキストを消費するわけではありません。スキルとプラグインはまったく別の仕組みで読み込まれます。すべての SKILL.md は、その名前と説明をシステムプロンプトに追加します。また、有効になっているプラグインは、インストールされているだけで、独自のスキル、コマンド、_および_サーバーを追加します。Claude Code では、adopt はハーネスが公開している2つの手段を使って、これらも処理します。

対象方法効果
スキルskillOverrides[name] = "name-only"説明をコンテキストから除外します。Claude は引き続き呼び出すことができ、/name も引き続き機能します
プラグインenabledPlugins[id] = falseプラグインのスキル、コマンド、サーバーがすべて読み込まれなくなります

ルーターは引き続きこれらすべてを検出できます。ハーネスで有効になっているものではなく、_インストールされている_ものを記録した ~/.claude/skills と installed_plugins.json を直接読み取るためです。これにより、プラグインを無効にする操作は削除ではなく移動になります。

黙って処理するのではなく、処理を拒否するケースが2つあります。ルーターがアクセスできない MCP サーバーを持つプラグイン(通常は OAuth を使うプラグインで、トークンを保持しているのはハーネスであり、ルーターではありません)は有効なままにします。無効にすると、現在動作しているサーバーが使えなくなるためです。また、ルーターがサーバーを把握していないプラグインも同様です。これは import から "plugins" を削除した場合に発生します。どちらも理由を添えた skip 行として報告されます。

以前の動作を維持するには --servers-only を、スラッシュコマンドも削除するには --skill-mode off を使います。また、個別に対象外にするには --keep-skill / --keep-plugin を使います。Codex、Cursor、VS Code にはスキルやプラグインの概念がないため、それらに対して追加の作業は必要ありません。

違いを確認するには、autorouter doctor を実行します。

## Context cost
  exposing everything: ~87,524 tokens
  router surface:      ~752 tokens
  best case:           ~86,772 tokens saved (99%)

  per harness (a session only ever runs in one):
    codex   still loaded ~35,500 → saves ~51,272 (59%)
    claude, cursor, vscode: fully adopted → saves ~86,772 (99%)

## Not yet adopted
  codex
    servers: project-tools, docs-search, issue-tracker
    → autorouter adopt --target codex

「引き続き読み込み中」と表示されるものが、移行によって取り除かれる項目です。合計ではなく、ハーネスごとに報告されます。1つのセッションが実行されるハーネスは常に1つなので、Codex にサーバーが登録されたままでも、Claude Code のセッションには影響しません。削除する内容は、書き込みの前にすべて ~/.autorouter/adopted/ にそのままバックアップされます。autorouter restore --target claude を実行すると、1バイトも変えずに元に戻せます。

Doctor は、コンテキストを消費するものの adopt では移動できない項目も報告します。報告と提案のみを行い、これらを編集することはありません。

  • フック:出力がコンテキストに追加される SessionStart フック。中央値はトランスクリプトから測定されます。マッチャーが空のフックは、コンパクション、/clear、再開のたびに再実行されます。
  • 古いツール参照:~/.claude/CLAUDE.md、CLAUDE.md、または AGENTS.md にある、サーバーが現在ルーターの背後にあるにもかかわらず、ツールを mcp__<server>__<tool> として指定している行です。モデルは存在しないツールを探すことになります。ルーター独自のプライマーブロックは対象外です。
  • 注入されたサーバー:ランチャーがコマンドラインで渡すサーバー(cmux が cmux-cua に対して行うように、claude --mcp-config ... を指定するものなど)です。これらは設定ファイルには存在しないため、adopt では移動できません。Doctor は、ルーターが同じサーバーをインポートしている場合も警告します。
セッションで実際にかかるコスト:autorouter audit

スキーマはコストの一部にすぎません。Claude Code はすでに MCP スキーマの読み込みを名前のみに限定しており、API 呼び出しのたびにウィンドウ内に残っている内容をすべて再読み込みするため、実際のコストはコンテキストサイズ × 呼び出し回数です。autorouter audit は Claude Code のトランスクリプト(~/.claude/projects/*/*.jsonl)を読み込み、各呼び出しについて記録された使用量を使用します。

## Context bill
  avg context per call   181k
  input processed        4.79B (96% cache reads)
  compactions            269 (median 317k before → 90k after)

## What fills it (tokens × calls each stays in context)
   30.1%   1.44B  startup overhead (system prompt, tools, skills, CLAUDE.md)
   23.2%   1.11B  carried over through compaction (kept turns, re-attached files)
   15.4%  735.5M  Claude's thinking (kept in context)
   13.9%  666.0M  Bash output
   ...

## Compaction window (replay, API-equivalent cost)
  autoCompactWindow: 350000 (~/.claude/settings.json)
     window    change  compactions  avg context
       140k    -26.9%          834         102k
       170k    -25.9%          559         116k  ← recommended
       350k      0.0%          173         196k  ← current

帰属計算では、次の圧縮まで、後続の呼び出しで再読み込みされるたびに、コンテンツの各ブロックにコストを一度ずつ割り当てます。ウィンドウの表では、トランスクリプト内の圧縮に合わせて調整し、各 autoCompactWindow の設定で実際のセッションを再現します。コストは API 価格比(キャッシュ読み取り ×0.1、キャッシュ書き込み ×1.25、出力 ×5)で重み付けされ、サブスクリプションの使用量の目安になります。パーセンテージは正確な値ではなく、相対値としてご覧ください。最安値から1.5ポイント以内のウィンドウが複数ある場合は、最大のものを推奨します。圧縮のたびに一部の詳細が失われるためです。 --days N(デフォルトは14、または all)と --project DIR で対象範囲を絞り込めます。--json を指定すると、レポート全体が出力されます。

対象の検索方法

取得してから、再ランク付けします。

  1. BM25:すべての機能を対象とし、常に有効で、依存関係はありません。トークナイザーはキャメルケースとスネークケースを分割します(get_user → get、user、getuser)。また、フィールドごとに重み付けします:名前 ×3、キーワード ×2、説明 ×1、スキーマ ×0.5。
  2. 埋め込み:オプションです。Voyage または OpenAI を使用します。スコアは最小最大正規化され、0.5 × bm25 + 0.5 × cosine で統合されます。プロバイダーが設定されていない、または到達できない場合もエラーにはならず、純粋な語彙検索に切り替わります。
  3. セレクターモデル:候補リストを再ランク付けします。使用中のハーネスで最も安価なモデルを使う必要があります。そのため、init はモデルを特定できない場合にどのモデルを使うか尋ね、回答をそのハーネス独自のサーバーエントリに保存します。
セレクターバックエンド

"mode": "auto" の場合、モデルにアクセスする方法を次の順で試します。

バックエンド方法実行される条件
samplingホストに sampling/createMessage を返すホストがこの機能を宣言している場合。宣言するホストはほとんどなく、Claude Code も対応していません
apiAnthropic / OpenAI / Ollama に直接 HTTPS 接続するselector.apiKeyEnv が、実際に設定されている環境変数を指定している場合
cliヘッドレスで claude -p または codex exec を実行するハーネスの CLI が PATH 上にある場合

通常実行されるのは CLI バックエンドです。他の 2 つが通常使えないために存在しています。sampling はプロトコル自体が用意する方法ですが、ほとんど実装されていません。次に API バックエンドは ANTHROPIC_API_KEY を要求しますが、Claude Code のサブスクライバーがこれを持っている理由はありません。ログインはしていても、キーを購入したわけではないからです。そのためルーターは、生のインデックス順にフォールバックし、すでに料金を支払っているモデルへのアクセスを購入するよう案内することになります。一方、claude はすでに認証済みで PATH 上にあります。これをサブプロセスとして実行すれば、設定も追加料金もなしに、そのログインを再利用できます。

代わりにかかるのはプロセスの起動コストであり、CLI セレクターは直接 HTTPS リクエストより遅くなります。そのため、API キーが設定されている場合は引き続きこちらが優先されます。選択結果は、プロセスが存続する間、クエリと候補セットごとにメモ化されます。そのため、コストがかかるのは検索のたびではなく、検索内容が異なる場合に一度だけです。

ハーネスは再ランキングに必要な機能だけに絞っています。通常のヘッドレスエージェントは、短いランキングタスクでは不要なフック、言語サーバー、プラグインの同期、プロジェクト指示の検出を起動することがあります。そのため、サブプロセスは --bare --tools "" --setting-sources "" と MAX_THINKING_TOKENS=0(Codex の場合は --ephemeral -s read-only)を指定して実行します。ツール一覧を空にするのは、コスト削減の前に正確性を保証するためです。ファイルを編集できるセレクターは、別のプログラムになってしまいます。

"selector": {
  "mode": "auto",          // auto | sampling | cli | api | off
  "provider": "cli",
  "cliCommand": "claude",  // only needed if the binary is not under its usual name
  "model": "haiku",
  "candidates": 30,
  "maxResults": 8,
  "timeoutMs": 20000       // raised automatically to the backend's own floor
}

空の MCP 設定(--strict-mcp-config、mcp_servers={})でも起動します。ルーター自身の設定を引き継ぐと、ルーターがコンテキストから除外するために存在するカタログそのものが読み込まれ、最悪の場合、ルーター自身を再帰的に呼び出すことになります。

model は、設定した場合にのみ引き渡されます。Codex はアカウントのプランで利用できないモデル名を拒否するため、それ以外の場合はアカウントのデフォルトモデルが使用されます。

mode: "off" にすると、再ランキングを完全にスキップし、生のインデックス順を返します。高速で無料ですが、結果の質は明らかに低下します。

下流のサーバーは起動時には起動されません。カタログは一度だけ構築され、~/.cache/autorouter/catalog.json に保存されます。サーバーは、その機能が初めて呼び出されたときにのみコールドスタートされます。

インデックス対象

種類ソース
tool, prompt, resource設定されているすべての MCP サーバー(nextCursor のページネーションに従います)
skillスキルパスおよびプラグインの skills/ ディレクトリ内にある **/SKILL.md
command, agentプラグインの commands/*.md と agents/*.md

プラグインのコマンドとエージェントは、スラッシュコマンドとしても再公開されます。 スキルは検索できますが、デフォルトでは再公開されません。スキルを載せるプロンプトリストは 恒久的なコンテキストになるためです。詳しくはスラッシュコマンドを参照してください。

ハーネスの設定は複製せずにインポートされます。~/.claude.json(グローバルおよび プロジェクトごとの設定)と、リポジトリの .mcp.json(リポジトリのスキルとサーバーを参照)、~/.codex/config.toml、~/.cursor/mcp.json、 ~/.vscode/mcp.json、およびインストール済みの Claude Code プラグインです。cmux ターミナルの実行中は、cmux が設定ファイルに書き込まずセッションごとに挿入するため、 Computer Use サーバー(cmux-cua)も検出されます。ハーネスで無効にされているサーバー (disabled: true、または Codex の enabled = false)はスキップされます。また、MCP サーバーを 起動せずデスクトップアプリを開くだけのコマンドが実行されることはありません。

リポジトリのスキルとサーバー

リポジトリ内、またはその配下で Claude Code を開くと、ルーターはそのリポジトリの .mcp.json サーバーと .claude/skills を検出し、そのリポジトリ内に限定します。 そのため、別のプロジェクトに表示されることはありません。また、Claude Code はそれらを 事前に読み込まなくなります。

  • 対象のリポジトリ。 ホストの roots/list(Claude Code は起動ディレクトリと --add-dir を指定したディレクトリを返し、変更も通知します)、次に CLAUDE_PROJECT_DIR、最後にルーター自身の作業ディレクトリが使われます。
  • 対象のスキル。 Claude Code の読み込み方法に合わせて、作業ディレクトリ内と git ルートまでの各親ディレクトリにある .claude/skills に加えて、ルート配下にある すべてのネストされた <subdir>/.claude/skills が対象です。Claude Code はその サブディレクトリ内のファイルに触れて初めてスキルを読み込みますが、ルーターは モノレポ内のアプリごとのスキルをトップから検索できます。
  • コンテキストからの除外方法。 リポジトリ固有の非公開ファイル .claude/settings.local.json を通じてのみ除外します。ルーティングされたサーバーには disabledMcpjsonServers、スキルには skillOverrides: "name-only" を使います (Claude は引き続き名前で呼び出せるため、/name も引き続き動作します)。以前の バージョンが "user-invocable-only" として書き込んだエントリ(Skill ツールを ブロックします)は、次回の検出時に "name-only" に変更されます。ルーターがこの ファイルを作成する場合は、.git/info/exclude に追加します。コミット済みの内容が 編集されることはなく、ユーザー自身が設定した値("on" も含む)は変更されません。
  • 対象のサーバー。 .mcp.json はチェックインされているため、ルーターは Claude Code が実行するサーバーのみを起動します。フォルダーが信頼済みであり、サーバーが HTTP サーバーであるか、承認済みである必要があります。承認は Claude Code の enabledMcpjsonServers、または正確なコマンドを固定する autorouter approve <name> で 行います。信頼設定と承認は、同じリポジトリのすべての git worktree に適用されます。 未承認のものは Claude Code に引き続き任され、通常どおり確認を求められます。
autorouter adopt --project [dir]     # the same thing by hand (--dry-run to preview)
autorouter restore --project [dir]   # take back exactly what that added
autorouter approve playwright        # let the router launch a .mcp.json stdio server

この動作を手動にするには、"autoAdoptProject": false を設定してください。

以前のバージョンからアップグレードする場合は? 以前は、adopt がリポジトリの コミット済み .mcp.json を空にし、サーバーをルーターのグローバル設定に移動していました。 autorouter repair は adopt 時のバックアップから移動した内容を一覧表示します。 --apply を指定すると、エントリを元に戻し(バックアップがあればバイト単位で復元)、 非公開のプロジェクトごとのサーバーをそれぞれのプロジェクトに限定したうえで、各 リポジトリを新しい方法で取り込みます。修復が必要な場合は doctor が警告します。

MCP サーバーの追加

ルーターに直接登録します。どのクライアントのコンテキストにも追加されません。

autorouter add linear --url https://mcp.linear.app/mcp
autorouter add foo -- npx -y foo-mcp            # stdio, like `claude mcp add`
autorouter add --json '{"mcpServers":{"linear":{"url":"…"}}}'   # paste the vendor snippet
autorouter remove linear

接続を確認する前にエントリーを保存します。新しいサーバーが応答しない通常の理由は、まだ OAuth の許可を得ていないことだからです。autorouter login <name> で認可するには、先にエントリーが存在している必要があります。

ハーネスを使うこともできます。 claude mcp add foo … は引き続き動作します。実行中のルーターはハーネスの設定変更を検知し、通常どおりバックアップを作成してエントリーを自身の設定に移し、次回の検索時に通知します。そのため、覚える必要のあるコマンドが増えることも、この設定を忘れて毎ターンそのサーバーのスキーマに料金を支払う期間が生じることもありません。手動での取り込みを維持するには、"autoAdopt": false を設定します。

セッション内からは、"allowAddServer": true を設定し、言葉で追加を依頼します。するとルーターが add_server ツールを公開します。ツール定義はリクエストごとにコンテキストに含まれ、autorouter add でも同じことができるため、デフォルトでは無効になっています。stdio サーバーを登録すると、その後このマシンで該当コマンドが実行されるようになるため、最初の呼び出しでは登録される内容だけが報告されます。実際に書き込むには、confirm: true を指定してもう一度呼び出す必要があります。

設定

autorouter.json は次の場所から検索されます:$AUTOROUTER_CONFIG、./.autorouter.json、./autorouter.json、~/.config/autorouter/config.json、~/.autorouter.json。

{
  "import": ["claude", "codex", "cursor", "vscode", "plugins", "cmux"],
  "servers": { "custom": { "command": "…", "args": [] } },
  "skillPaths": ["~/.claude/skills", ".claude/skills"],
  "exclude": ["media.generate_video"], // never surfaced at all
  "alwaysExpose": ["code-search.search"], // stays first-class, never adopted
  "confirm": ["database.execute_statement"], // first call is rejected, must re-issue
  "autoAdopt": true, // move servers added to a harness behind the router
  "autoAdoptProject": true, // route the current repo's .mcp.json servers and skills
  "allowAddServer": false, // expose the add_server tool to the model
  "promptMode": "commands", // slash commands: "all" | "commands" | "none"
  "activation": "lazy", // promote to a real tool: "eager" | "lazy" | "off"
  "spillOverTokens": 3000, // larger results are saved, not inlined
  "spillOverrides": { "mcp:linear/*": 8000 }, // per-id thresholds; 0 = never
  "resultsMode": "auto", // "auto" | "file" | "page" | "off"
  "resultsDir": "", // default <cache>/results; never inside the working tree
  "selector": { "mode": "auto" },
  "embeddings": {
    "provider": "voyage",
    "model": "voyage-3-lite",
    "apiKeyEnv": "VOYAGE_API_KEY",
  },
}

環境変数による上書き(AUTOROUTER_IMPORT、AUTOROUTER_SELECTOR_MODEL、AUTOROUTER_SELECTOR_MODE、AUTOROUTER_PROMPT_MODE、AUTOROUTER_ACTIVATION、AUTOROUTER_AUTO_ADOPT、AUTOROUTER_ALLOW_ADD_SERVER、AUTOROUTER_EMBEDDINGS_PROVIDER、AUTOROUTER_RESULTS_MODE、AUTOROUTER_SPILL_OVER_TOKENS、…)を使うと、共有のグローバルファイルなしで、各ハーネスに独自の動作を指定できます。AUTOROUTER_HOME は、テストやコンテナー向けにホームディレクトリ基準のすべてのパスを変更します。

スラッシュコマンド

プラグインをルーターに取り込むと、そのスラッシュコマンドを利用できなくなるはずです。Claude Code はディスク上の commands/*.md を読み込みますが、MCP 経由でそのリストに追加する方法はありません。一方、スラッシュコマンドとして公開できるのは MCP プロンプトです。そのため、カタログにあるプラグインのコマンドとサブエージェントは、プロンプトとして再公開されます。

/mcp__autorouter__find <what you want to do>
/mcp__autorouter__plugin_name_command_name

スキルはデフォルトでは再公開されません(promptMode: "commands")。プロンプトリストは永続的なコンテキストです。ホストは一度取得すると、セッション全体を通じて保持します。その大部分を占めるのがスキルです。たとえば、あるプラグインが141個のスキルを提供すると、毎ターン約11.5kトークンを消費します。これは、そのプラグインを取り込んで節約できる量を上回ります。また、adopt はローカルスキルを name-only として隠すため、ネイティブの /name と Skill ツールの呼び出しは引き続き機能し、プラグインのスキルは注入されずにハーネスから必要に応じて公開されるため、別名もほとんどの場合不要です。どちらの場合もスキルは引き続きすべて検索できます。"promptMode": "all" を設定すると /mcp__autorouter__skill_name が再び使えるようになり、"none" を設定すると find だけが公開されます。

本文の置換方法はネイティブローダーと同じです。入力した内容全体が $ARGUMENTS に、各引数が順に $1〜$9 に置き換えられるため、Claude Code 用に書かれたコマンドファイルはルーター経由でも同じように動作します。argument-hint のフロントマターは引数の説明として引き継がれます。名前には所有するプラグインの接頭辞が付くため、複数のプラグインが setup コマンドを提供していても、一方がもう一方を暗黙に隠すことなく、どちらも引き続き利用できます。

ツールは意図的にここでは公開されません。プロンプトはモデルが処理するテキストを返しますが、ツールの実行結果は返せません。そのため、database_write のスラッシュコマンドを用意しても、呼び出せるように見えるだけで何も起こりません。ツールは検索を通じてモデルに提供されます。

ハーネスのサポート

検索結果には、要約ではなく、完全な説明と入力スキーマが付いたツールが返されます。これはネイティブのツール一覧に含まれるものと同じ情報です。説明が省略されると、モデルは引数名を推測することになり、引数を推測するかどうかが、おおむね信頼できる状態と信頼できる状態を分ける要因になります。

さらに、クライアントが notifications/tools/list_changed に対応している場合、使用したツールは、実際のファーストクラスツールに昇格します。それ以降、モデルは通常のツール呼び出しを行います。ホストは実際のスキーマに照らして引数を検証し、権限確認プロンプトには call_capability ではなく実際のツール名が表示され、ルーターは実行経路から完全に外れます。これにより、すべての呼び出しに介在する仲介役ではなく、ツール一覧に含めるものを決めるローダーになります。

昇格は最初の呼び出しが成功するまで保留されます(activation: "lazy")。昇格したツールは永続的にコンテキストを占めますが、検索結果に出たからといって必要である証拠にはならず、検索に一致するもののほとんどは呼び出されないためです。以前のように検索結果に一致するすべてのツールを昇格するには "activation": "eager" を設定し、すべてを call_capability 経由でルーティングしてツール定義を一切持たないようにするには "off" を設定します。

listChanged に対応プロキシのみ
Claude Code ≥ 2.1.232、GitHub Copilot、opencodeCodex、Gemini CLI、Claude Desktop、Vercel AI SDK

対応していない場合、スキーマは検索結果にインラインで含められます。また、モデルが使用できないツールを知らされないよう、activate_capabilities(off: true でピン留め解除も可能)は提示されません。検出結果は AUTOROUTER_DYNAMIC=on|off|auto で上書きできます。 ターンの途中で登録されたツールは、Claude Code では次のターンまで呼び出せないことがあります。そのため、call_capability は常に同じターン内でのフォールバックとして残り、同一の結果を返します。

検索して1ステップで実行

find_capabilities({ query, arguments, auto: true }) は、曖昧さがない場合に限り、同じリクエスト内で検索結果の最上位ツールを実行し、往復を1回分省きます。条件は次のとおりです。

  • ツールであり、
  • 次点のスコアを、正規化されたインデックススコアで少なくとも0.25上回ること。または、セレクターモデルが検索結果に順位を付けた場合、信頼度が0.7以上で、次点より0.25以上高いこと。
  • 引数がスキーマに適合すること(必須プロパティ、基本的な型、列挙値、スキーマで禁止されている未知のキーがないこと)。
  • confirm ゲートの対象ではないこと。自動実行で確認を回避することはできません。

それ以外の場合は、実行しなかった理由を示す1行を添えて、通常の検索結果を返します。

トークン予算

コンテキストを漏らすルーターは、すべてを読み込む方法を遅くしただけです。そのため、保持または蓄積される3つの領域には、それぞれ項目数ではなくトークン数で上限を設けています。項目数による制限は上限のように見えますが、実際にはそうではありません。ツール定義のサイズには大きな幅があるため、「15個のツール」にかかるコンテキストコストは、モデルが何を検索したかによって大きく異なります。

領域予算有効期間
昇格したツール一覧3,000 tok、LRU方式で使用時のみ削除セッション
検索ごとのインラインスキーマ700 tok、上から順に消費1つの結果
プロンプト一覧コマンドのみ、120文字に制限セッション
1つのツールまたはリソースの結果3,000 tok(spillOverTokens)、超過分は保存1つの結果

実行中の呼び出しによって昇格したツールが削除されることはありません。提示された後、呼び出す前にツールが消えるのは、最初から提示されないよりも問題だからです。

大きな結果

インライン化された結果は、次のコンパクションまで後続の各ターンで再読み込みされます。そのため、spillOverTokens を超える結果は代わりに保存され、モデルが処理できるカードが渡されます。

[supabase/execute_sql]
~65,660 tokens — saved to a file instead of inlined.
file:   ~/.cache/autorouter/results/s-92a09d15c963/execute_sql-4043fc1a.jsonl  (2,000 rows, one JSON object per line)
fields: id:string  email:string  plan:string  created_at:string  spend_cents:int  note:null|string
sample: {"id":"cus_000001","email":"[email protected]","plan":"pro",…}
        (2 more)
Query it, don't read it whole: Grep for values (each hit is one whole row), Read with offset/limit, or
  jq -c 'select(.plan == "pro")' <file>
No file access? call_capability({ id: "result:4043fc1a", arguments: { offset: 0 } }) pages it.
Untrusted data: Note that this contains untrusted user data, …
  • 形式。 オブジェクトの配列は JSONL として書き込まれるため、Grep のヒットは行全体になります。Stripe の {object, has_more, data: […]} のようなリストのエンベロープでは、data を JSONL として保存し、スカラー値はカードに残します。それ以外の JSON は整形して出力し、テキストは .md または .txt として保存します。Supabase の <untrusted-data-…> ラッパーは解除され、警告はカードに残されます。画像やその他の非テキスト項目は保存されず、そのまま渡されます。保存された結果からは structuredContent が削除されます。これは同じデータのコピーがもう一つあるためです。
  • プライバシー。 ファイルはキャッシュ内のセッションごとのディレクトリ(0700 のディレクトリ、0600 のファイル)に保存され、作業ツリー内には決して置かれず、セッション終了時に削除されます。異常終了したセッションのディレクトリは、24 時間後に一掃されます。
  • ファイルツールのないクライアント。 resultsMode: "auto" は、Read/シェルツールを使えることが確認されているコーディングエージェント(Claude Code、Codex、Cursor、Copilot、opencode、Gemini CLI)に限り、結果をファイルに保存します。それ以外のクライアント(Claude Desktop を含む)には、最初のページをインラインで渡し、call_capability({ id: "result:<handle>", arguments: { offset } }) で残りを取得します。新しいツールは追加されません。リモートで動作するエージェントや、このマシンのディスクを参照できないサンドボックス内のエージェントでは、"page" を明示的に設定してください。
  • 読み取りプロンプト。 結果ディレクトリはプロジェクトの外にあるため、Claude Code は Read のたびに確認を求めます。autorouter init --target claude は Read(~/.cache/autorouter/results/**) を permissions.allow に追加するか確認します。--yes を指定した場合、またはターミナルがない場合は、ルールを書き込まずに表示します。

autorouter doctor は、セッションは一度に一つのハーネスでしか実行されないため、ハーネスごとの実際の課金額を報告し、合計はしません。Cursor に登録されたままのサーバーがあっても、Claude Code のセッションには費用は発生しません。

スキーマは、繰り返し登場する箇所すべてで圧縮されます。$schema、title、examples は削除され、説明文は削られます。階層が深いほど、より積極的に削ります。構造を定義するフィールド(名前、型、列挙値、required、ネスト、additionalProperties: false)はすべて変更せずに残します。これらのいずれかを削除すると、有効な呼び出しが推測に頼るものになってしまうためです。これにより、呼び出し可能な内容を変えずに、繰り返されるスキーマのサイズを削減できます。

例外は describe_capability で、スキーマをそのまま返します。これは、予算の都合で結果から省かれた情報を復元するためのものです。

CLI

MCP はなくてもシェルが使えるエージェントは、同じエンジンを直接利用できます。

autorouter search "chart a csv"
autorouter search "query a database" --raw --limit 5
autorouter describe skill:dataviz
autorouter call mcp:deployments/get_logs --args '{"lines":50}'
autorouter list --kind skill
autorouter doctor
autorouter audit --days 14                          # the per-call bill from transcripts
autorouter reindex

autorouter add linear --url https://mcp.linear.app/mcp
autorouter add foo -- npx -y foo-mcp
autorouter remove linear

autorouter adopt --target claude --dry-run          # preview, change nothing
autorouter adopt --target claude --servers-only     # skip skills and plugins
autorouter adopt --target claude --keep project-tools --keep-plugin ui-toolkit
autorouter restore --target claude                  # undo the most recent adopt
autorouter adopt --project                          # route this repo's .mcp.json servers and skills
autorouter restore --project                        # take that back
autorouter approve playwright                       # let the router launch a repo stdio server
autorouter repair                                   # what older adopts moved out of repos (--apply)

autorouter update                                   # upgrade in place
autorouter update --check                           # is there a newer version?

autorouter login                                    # which servers need a grant
autorouter login remote-server                      # authorize one (opens a browser)
autorouter login remote-server --device             # headless: enter a code elsewhere
autorouter login remote-server --no-reindex         # authorize, index later
autorouter logout remote-server                     # forget a stored grant

更新

autorouter update は、実行中のコピーをインストールしたパッケージマネージャーを使って、既存のインストールをそのままアップグレードします。

autorouter update            # detect, then upgrade
autorouter update --check    # report the available version, install nothing
autorouter update --dry-run  # print the command, do not run it

使用するパッケージマネージャーは、実行中のファイルがディスク上のどこにあるかで決まり、PATH に何があるかでは決まりません。pnpm 管理のグローバル環境に対して npm i -g を実行すると、先にあるコピーを覆い隠す別のコピーがインストールされます。その場合、一方を実行しながら、もう一方をアップグレードすることになります。

パッケージマネージャーを実行せず、その理由を報告するケースが三つあります。npx/bunx/pnpm dlx で展開されたコピー(アップグレード対象はありません。実行のたびに再取得されます)、git チェックアウト(git pull && bun install && bun run build)、そして識別できない構成です。いずれの場合も、新しいバージョンがあるかどうかは報告します。

ルーターは長時間稼働する stdio サーバーであるため、すでに起動しているハーネスでは、再起動されるまで古いビルドが使われ続けます。更新後は、ハーネスを再起動するか、MCP サーバーに再接続してください。

OAuth サーバー

一部のリモート MCP サーバーでは、表示される設定に認証情報が含まれていません。 使用するトークンは、ハーネスが取得する OAuth グラントであり、 ハーネスの認証情報ストアに保存され、そのハーネス専用に発行されます。

ルーターはそのトークンを読み取りません。独自の認可コードフローを実行して 独自のグラントを保持するため、借用できるトークンがない Codex や Cursor でも 動作します。

autorouter login remote-server

新しいグラントを取得すると、自動的に再インデックスが行われます。グラントが あっても、カタログに反映されるまでは、その背後にある機能を検索できないためです。 グラントを取得しただけでは、ルーターがアクセスできるものは何も変わりません。 複数のサーバーを続けて認証し、最後にまとめてインデックス化したい場合は、 --no-reindex で再インデックスをスキップできます。

新しいグラントが実際に保存されたログインのみが再インデックスを実行します。 --list-scopes や、すでにグラントを持っているサーバーでは何も変わらないため、 インデックスの再構築も行われません。

登録には RFC 7591 の動的クライアント登録を使用するため、事前にアプリを 作成する必要はありません。トークンは ~/.autorouter/oauth/<server>.json に 0600 で保存され、自動的に更新されます。logout を実行すると削除されます。 ループバックリダイレクトには固定ポートを使用します(33418。変更するには --port または $AUTOROUTER_OAUTH_PORT を使用)。リダイレクト URI は プロバイダーに保存される登録情報に組み込まれるため、あるポートで取得した グラントを別のポートから更新することはできません。

ヘッドレスマシン

ブラウザーフローは SSH 経由では動作しません。ループバックリスナーをバインドし、 同じホスト上のブラウザーがリダイレクトしてくることを前提としているためです。 代わりに使えるフローが 2 つあります。ディスプレイのないマシンでは、開くはずのない ブラウザーを待ってタイムアウトするのではなく、autorouter がどちらかを自動で選びます。

autorouter login remote-server --device   # RFC 8628: enter a code on your phone
autorouter login remote-server --manual   # paste the redirect URL back

プロバイダーが対応している場合は、--device の方が適しています。マシン側に アクセスする必要はありません。短いコードと URL が表示されるので、別のデバイスの ブラウザーで入力すると、ヘッドレス側が完了するまでポーリングします。対応状況は プロバイダーのメタデータにある device_authorization_endpoint で判定します。

--manual は RFC 8628 を実装していないプロバイダー向けのフォールバックです。 認可 URL が表示されるので、別の場所で開きます。その後、ブラウザーは http://localhost:33418/callback にリダイレクトされますが、リスナーが存在しないため ページは読み込まれません。これは想定どおりです。アドレスバーから URL をコピーして 貼り付けてください。コードだけではなく URL 全体を貼り付けることをおすすめします。 URL に含まれる state が、コードの取得元が開始したログインであることを証明するためです。

どちらのフローもポートをバインドしません。デバイスログインでは、同じマシンから 後でブラウザーログインする場合にも使えるクライアントが登録されるため、マシンに ディスプレイを追加しても再設定は不要です。判定を誤るマシンで検出を強制するには、 AUTOROUTER_ASSUME_HEADLESS=1 を設定してください。

権限の選択

動的に登録されたクライアントは、プロバイダーが提示するすべてのスコープをデフォルトで要求することがあります。書き込み権限や管理者権限も含まれる可能性があります。その結果、検索ツールが破壊的な操作を実行できるトークンを保持してしまうことがあります。プロンプトインジェクションを受けても残る制限はスコープだけなので、慎重に選択してください。

autorouter login remote-server --list-scopes
autorouter login remote-server --read-only
autorouter login remote-server --scopes "projects:read,data:read"

--read-only は、名前から変更権限を付与しないと判断できるスコープを維持します。これは命名規則(:write、admin、manage、all)に基づくヒューリスティックであり、不透明なスコープ名の背後にある権限は推測できません。このヒューリスティックで判断できない場合は、--scopes を使って正確に指定してください。プロバイダーに読み取り専用のスコープがない場合、--read-only は空のスコープを要求するのではなく、エラーを明示して終了します。多くのプロバイダーは空のスコープを「デフォルトをすべて付与」と解釈するためです。

スコープは認可が発行された時点で固定されるため、既存の認可を絞り込むには --force を指定して再認可する必要があります。再ログインでは、別の指定を渡さない限り、以前の絞り込みが引き継がれます。また、引数なしで autorouter login を実行すると、保存されている各認可が実際にどの権限をカバーしているかが表示されます。

サーバーに認可がない場合、adopt はそのサーバーの移動も、そのサーバーを提供するプラグインの無効化も拒否します。ルーターが接続できないサーバーを移動すると、正常に機能している能力が失われるため、doctor と adopt はどちらも正確な login コマンドを表示します。

トレードオフを率直に説明します

ルーティングを行うと、ホストの権限プロンプトに表示されるのは database.execute_statement ではなく call_capability です。これは実際に粒度が粗くなることであり、このツールもその事実を隠しません。緩和策は3つあります。exclude を指定すると、その能力は一切公開されません。confirm は、解決済みのターゲットを明示したうえで最初の試行を拒否し、モデルに confirm: true を付けて再度リクエストさせます。また、すべての結果には解決済みの server/tool が先頭に付加されるため、トランスクリプトを監査できます。

スキルとプラグインを取り込むと、手動でも編集するファイルである ~/.claude/settings.json が変更されます。サーバーの移動と併せてファイル全体がそのままバックアップされ、restore によってバイト単位で書き戻されますが、共有ファイルであることは把握しておく価値があります。同じ理由から、非表示のスキルはデフォルトで name-only になります。Claude は引き続きスキルを呼び出せ、/name も引き続き動作するため、能力は削除されるのではなく移動されます。--skill-mode user-invocable-only を指定すると名前も削除されますが、その場合 Claude Code はそのスキルへの Skill ツール呼び出しを拒否します(「モデルによる呼び出しは無効」)。off を指定すると /name も削除されます。

開発

bun install
bun test
bun run src/cli.ts doctor
bun run build          # bun build src/cli.ts --target=node --outfile dist/cli.js

ビルドのターゲットは Node なので、Bun をインストールしていない人も npx を使用できます。

変更を加える前に把握しておくべき不変条件については、CONTRIBUTING.md を参照してください。特に、起動時に何も生成されないこと、adopt が行うすべての書き込みはバイト単位で元に戻せること、セレクターのサブプロセスは意図的にツールなしで実行されることが重要です。

ライセンス

MIT です。セキュリティに関する報告は、公開のイシュートラッカーではなく SECURITY.md を通じてお寄せください。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。