MINARA

MCP サーバーの接続

`mcp/servers.json` 経由で外部 MCP サーバーを Agent に接続する

Agent は起動時に Model Context Protocol サーバーへ接続します。それらのツールは組み込みツールと同じ ToolRegistry に入り、デフォルトで defer_loading: true が付与され ます(schema はモデルが tool_search を呼んだときに初めて取得されます)。

2 つのファイル位置

サーバー設定は 2 か所から読み取られ、マージされます:

  • ユーザーグローバル: <dataDir>/mcp/servers.json、デフォルトは ~/.minara/mcp/servers.json。ディレクトリは MINARA_DATA_DIR で 上書きできます。個人の認証情報や、すべてのリポジトリで使えるように したいサーバーを置きます。mcp/servers.json が無い場合は旧パス <dataDir>/mcp.json も読み取られるので、既存の設定はそのまま動きます。
  • プロジェクトローカル: <repo>/.minara/mcp/servers.jsoncwd から上に辿って最も近い .minara/ ディレクトリ(.git/ と同階層) を解決します。単一リポジトリで開発用 URL やテナント別 token を ピンしたい場合に使用。旧パス <repo>/.minara/mcp.json も同じ フォールバックです。

id が衝突したらプロジェクト側が勝つので、リポジトリはグローバル定義の サーバーの authTokenEnvurl を上書きできます。

両ファイルは同じスキーマを共有します:

{
  "mcpServers": {
    "slack": {
      "url": "https://mcp.example.com/slack/",
      "authTokenEnv": "SLACK_MCP_TOKEN",
      "headers": { "X-Tenant": "acme" }
    },
    "etherscan": {
      "url": "https://mcp.example.com/etherscan/",
      "timeoutMs": 60000,
      "subagent": {
        "systemPrompt": "EVM ブロックエクスプローラのクエリ専門。",
        "maxSteps": 10
      }
    }
  }
}

JSON のキーがサーバー id(mcp_<id>_* ツール名のプレフィックスとして 使われる)になります。同じサーバーを別エイリアスで複数登録したいとき は、エントリ内に "id" フィールドを明示するとキーより優先されます。

フィールド

フィールド必須備考
urlはいStreamable-HTTP の MCP エンドポイント。SSE のみのエンドポイントは未対応。
authTokenEnvいいえbearer token を保持する環境変数名。接続時に環境から解決し、Authorization: Bearer <token> として送出。secret をディスクに残さないため authToken より優先。
authTokenいいえbearer token のリテラル値。存在すれば読み取られるが、このファイルを書くツール(minara mcp add、chat 内インストール経路)は inline token を拒否し authTokenEnv を要求する。信頼できるホストでの手書きファイルなら使用可。
headersいいえ全リクエストにマージされる追加 HTTP ヘッダ。secret 系のヘッダ値(AuthorizationX-Api-Key)は環境変数を参照する必要がある。例: "Authorization": "Bearer ${SLACK_MCP_TOKEN}"
timeoutMsいいえ単一呼び出しのタイムアウト。デフォルト 30000。
labelいいえログ表示名。デフォルトは id。
maxToolsいいえ1 サーバーあたりの登録ツール数の上限。デフォルト 64。
includeいいえリモートツール名の許可リスト。それ以外は破棄。
subagentいいえ設定すると、そのサーバーのツール群は単一の mcp_<id>_query ツールにラップされ、内部 agent ループで駆動されます。ツール数が多いサーバーで、人格 + ステップ予算により本ループをスッキリ保つのに有効。

不正なエントリ(url 欠落、型違い)はログを残してスキップ :: 1 件 壊れていても他のサーバー接続は止まりません。

優先順位

  1. MCP_SERVERS 環境変数 : サーバー設定の JSON 配列。両方のファ イル位置をショートサーキットします。テストや、secrets manager がブロブを直接注入するコンテナデプロイで使用。
  2. マージされたサーバー設定 : グローバル <dataDir>/mcp/servers.json とプロジェクトローカル <repo>/.minara/mcp/servers.json をマージ (それぞれ同階層の旧パス mcp.json にフォールバック)。id 衝突は プロジェクト側が上書きし、id が異なる項目は和集合になります。
  3. v1 サーバー個別の URL 環境変数MCP_EVM_RPC_URLMCP_ETHERSCAN_URLMCP_SOLSCAN_URLMCP_GOPLUS_URL。それ ぞれ独立に有効化されますが、上 2 階層が空のときだけ参照されます。

ディスクに設定ファイルがあっても MCP_SERVERS=… は常にファイル層を ショートサーキットするため、再現性は保たれます。

セキュリティ

secret を設定ファイルに書かないでください。鍵は authTokenEnv(環境 変数名)で表現し、token は接続時に環境から解決されます。このファイルを 書くツール(minara mcp add と chat 内インストール経路)がこれを強制 します。inline authToken も、リテラル値を持つ secret ヘッダも拒否する ので、token が Agent 経由でディスクに到達することはありません。

信頼できるホストでの手書きファイルなら、なおリテラル値の authToken を 持てます。loader はそれを読み取ります。共有ホストでは authTokenEnv を 優先してください。どうしてもリテラル token を保存する場合:

  • chmod 600 ~/.minara/mcp/servers.jsonchmod 600 <repo>/.minara/mcp/servers.json
  • もしくは MCP_SERVERS 経由で secrets manager(Vault、AWS Secrets Manager、doppler など)から流し込み、設定ファイルを空のままにする。
  • プロジェクトローカルのファイルはリポジトリ協力者と token を共有 したくない場合、.minara/.gitignore に追加する。

可観測性

起動ログは module: "app"action: mcp_initialized 行で接続済み サーバー + ツール数を出力します。サーバー単位の失敗は mcp_server_connect_failed として上がります。

REPL の pnpm dev -- status(もしくは対応する HTTP gateway エンドポ イント)で MCP の現在状態配列を確認できます。

目次