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.json。cwdから上に辿って最も近い.minara/ディレクトリ(.git/と同階層) を解決します。単一リポジトリで開発用 URL やテナント別 token を ピンしたい場合に使用。旧パス<repo>/.minara/mcp.jsonも同じ フォールバックです。
id が衝突したらプロジェクト側が勝つので、リポジトリはグローバル定義の
サーバーの authTokenEnv や url を上書きできます。
両ファイルは同じスキーマを共有します:
{
"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 系のヘッダ値(Authorization、X-Api-Key)は環境変数を参照する必要がある。例: "Authorization": "Bearer ${SLACK_MCP_TOKEN}"。 |
timeoutMs | いいえ | 単一呼び出しのタイムアウト。デフォルト 30000。 |
label | いいえ | ログ表示名。デフォルトは id。 |
maxTools | いいえ | 1 サーバーあたりの登録ツール数の上限。デフォルト 64。 |
include | いいえ | リモートツール名の許可リスト。それ以外は破棄。 |
subagent | いいえ | 設定すると、そのサーバーのツール群は単一の mcp_<id>_query ツールにラップされ、内部 agent ループで駆動されます。ツール数が多いサーバーで、人格 + ステップ予算により本ループをスッキリ保つのに有効。 |
不正なエントリ(url 欠落、型違い)はログを残してスキップ :: 1 件
壊れていても他のサーバー接続は止まりません。
優先順位
MCP_SERVERS環境変数 : サーバー設定の JSON 配列。両方のファ イル位置をショートサーキットします。テストや、secrets manager がブロブを直接注入するコンテナデプロイで使用。- マージされたサーバー設定 : グローバル
<dataDir>/mcp/servers.jsonとプロジェクトローカル<repo>/.minara/mcp/servers.jsonをマージ (それぞれ同階層の旧パスmcp.jsonにフォールバック)。id 衝突は プロジェクト側が上書きし、id が異なる項目は和集合になります。 - v1 サーバー個別の URL 環境変数 :
MCP_EVM_RPC_URL、MCP_ETHERSCAN_URL、MCP_SOLSCAN_URL、MCP_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.jsonとchmod 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 の現在状態配列を確認できます。