MCPサーバー追加の実践
入門コースのMCPで能力を広げる(入門)では、信頼できるサーバーかを判定し、最小構成で1つ接続するところまでを扱いました。このレシピはその先 ─ 実務でMCPを運用するときに効く設定を、目的別にまとめます。MCPの仕組みとリスクの全体像はMCPとは何か、なぜ慎重に扱うかを、各キーの完全な一覧はMCPを前提とします。
考え方の軸は一貫しています。外部に頼るほど、できることと同時にリスクが増える。だから「広げる」設定ほど、範囲を絞る設定とセットで使います。
公開するツールを絞る(tools.include / exclude)
サーバーが多くのツールを持っていても、使うものだけ登録するのが基本です。エージェントに見せる候補を減らすと、意図しないツール選択を防げます。
{ "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed"], "env": {}, "tools": { "include": ["read_file", "list_directory"] }}include を指定すると、挙げたサーバー固有ツールだけが登録されます。逆に「これだけ外したい」場合は exclude を使います。両方書いた場合は include が優先します。リソースやプロンプトを使わないなら tools.resources / tools.prompts を切ることもできます。MCPタブでは、接続済みサーバーのツール名チップをクリックしても同じ include / exclude が書き換わります。
指定する名前はサーバー固有名のまま
エージェントに登録されるMCPツール名は mcp__<サーバー名>__<ツール名> 形式です(MCP)。ただし tools.include / exclude に書く名前はサーバーが公開する素のツール名(例: read_file)です。プレフィックス付きの登録名(mcp__filesystem__read_file など)を書いても一致しません。エージェントから見えるツール名やログ上の名前はプレフィックス付き形式で現れるため、両者を混同しないよう注意してください。
認証情報を安全に渡す
認証情報をJSONに直書きすると漏えいリスクになります。環境変数参照かOAuthを使います。
{ "url": "https://mcp.example.com/mcp", "headers": { "Authorization": "Bearer ${MCP_TOKEN}" }}${MCP_TOKEN} のように環境変数を参照すれば、トークンそのものを設定に残さずに済みます。サーバーがOAuthに対応していれば、"auth": "oauth" でPKCEを使うのがさらに安全です。
HTTP接続では
ssl_verify: false(証明書を検証しない)を実サービスで使わないでください。プライベートCAを使う場合は、ssl_verifyにCA bundleのパスを指定します。
OAuthを実務で運用する
"auth": "oauth" の初回接続では、ブラウザで認可し、ローカルのコールバックポートで完了を受け取ります。両方のGUI(デスクトップ・Webダッシュボード)と特殊環境向けに、次の機能が用意されています。
- GUIでフローを完了できる ─ デスクトップのMCPタブでは、「認証が必要です」状態のサーバーに「認証」ボタンが表示され、クリックするとブラウザでの認可待ち(「ブラウザを待機中…」)を経て「認証済み」になります。Webダッシュボード側にも同じOAuthフローが実装されています。
- プロキシ経由のコールバック(
redirect_uri/redirect_port) ─ ゲートウェイをリモートで動かしているなど、ブラウザからループバックポートへ直接届かない環境では、公開HTTPSエンドポイント(公式ドキュメントはTailscale Funnelを例示)でコールバックポートへ転送し、oauth.redirect_uriにその転送元URLを設定します。あわせてoauth.redirect_portでローカルのコールバックポートを固定してください。省くと空きポートが自動で選ばれ(既定は0= 自動選択)、プロキシの転送先を一定に保てなくなるためです。 - WAFが
127.0.0.1を拒否する場合(redirect_host) ─ 一部プロバイダのWAFは、authorizeリクエストのクエリに127.0.0.1が含まれると403で拒否します。oauth.redirect_hostに"localhost"を設定するとhttp://localhost:<ポート>/callbackを使えます(リスナーのbindは127.0.0.1のまま変わりません)。
{ "url": "https://mcp.example.com/mcp", "auth": "oauth", "oauth": { "redirect_port": 8765, "redirect_uri": "https://oauth.example.ts.net/callback" }}CLIと併用して
config.yamlを直接編集する場合の注意 ─ 設定変更の自動再読み込みは30秒でタイムアウトするため、対話的なOAuthフローには足りません(公式ドキュメント記載)。OAuthサーバーを追記したら、別ターミナルでhermes mcp login <サーバー名>を実行してください。こちらは認可完了を5分まで待ちます。
stdioの環境とパスを最小化する
stdioサーバーはあなたのマシンで子プロセスとして起動し、渡したパスや環境変数にアクセスできます。env には子プロセスへ明示的に渡す変数だけを書きます(ホストの全環境は渡されません)。許可するディレクトリも必要最小限にします。
{ "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects/this-one"], "env": {}}作業対象のフォルダだけを引数で許可し、ホームディレクトリ全体のような広いパスは渡さないようにします。
常駐stdioサーバーを自動リサイクルする
Playwrightのようなブラウザ自動化系のstdioサーバーは、Chromiumを抱えたまま常駐するため、長く使うほどメモリが肥大しやすくなります。idle_timeout_seconds / max_lifetime_seconds で子プロセスを自動リサイクル(再起動)できます。公式ドキュメントのPlaywright向け設定例をJSONにするとこうなります。
{ "command": "npx", "args": ["-y", "@playwright/mcp@latest", "--headless"], "idle_timeout_seconds": 900, "max_lifetime_seconds": 86400}idle_timeout_seconds─ 最後のツール呼び出しからこの秒数を超えたらリサイクルする(例は15分)。max_lifetime_seconds─ 起動からの総経過時間でリサイクルする(例は1日)。- どちらも
0は無効で、既定は未設定(リサイクルしない)。再起動は透過的で、次のツール呼び出し時に自動で立ち上がり直します。両キーはlifecycle: {...}の下にまとめて書くこともできます(MCP)。
sampling を制御する
MCPには、サーバー側からHermesのモデル推論を要求する sampling 機能があります(SDK対応時は既定で有効)。未信頼サーバーには止めるのが安全です。
{ "url": "https://mcp.example.com/mcp", "sampling": { "enabled": false }}使わせる場合でも、max_tokens_cap・max_rpm・max_tool_rounds・allowed_models で上限と範囲を絞れます。log_level を上げておくと、何が要求されたかを監査できます。
確実に無効化する(enabled: false)
実行時にサーバーを止める正式なキーは enabled: false です。これで接続・検出・登録がすべて停止します。
デスクトップのMCPタブの有効/無効スイッチは
enabledキーそのものを操作します(オフでenabled: falseを書き込み、オンでenabledキーを削除)。UI表示もランタイムの停止判定も同じenabledフラグを読むため、スイッチの見た目と実際の停止状態は一致します。disabledは正式な停止キーではありません。
一時的に外したいサーバーは、削除せず enabled: false にしておくと、設定を残したまま無効化できます。
反映と検証
設定変更は原則として自動で反映されます。
- MCPタブで変更を保存する。保存が成功すると実行中のセッションへ自動で再読み込みされ、手動の「MCP を再読み込み」は不要になった(ボタン自体は手動更新用に残っている)。有効/無効スイッチやツール名チップの操作も同様に即時反映される。
config.yamlを直接編集した場合も、mcp.auto_reload_on_config_change(既定true)のファイルウォッチャーがmcp_serversセクションの変更を検知し、自動で再読み込みする。- どちらの場合も、新しいツールスキーマが使われるのは次の新しいターンから。新しいターンで、狙ったツールが使えるか・余計なツールが増えていないかを確認する。
- サーバー側の警告・エラーは、MCPタブ下部のログペイン(
stdio/agent切替)か~/.hermes/logs/agent.logで確認する。MCPサーバーが送るログ通知(notifications/message)は、サーバー名タグ付きでagent.logに記録される。
自動再読み込みは毎回エージェントのツール一覧を再構築し、プロバイダーのプロンプトキャッシュを無効化します(次のメッセージで入力プレフィックスを再送します)。外部ツールが config.yaml を頻繁に書き換える環境では、mcp.auto_reload_on_config_change: false にして /reload-mcp で明示的に適用する運用も選べます。false でもウォッチャーは変更を検知し、適用方法を案内します。
approvals.mcp_reload_confirm(安全性)をオンにしておくと、再読み込み時にサーバー名・実行コマンド・URL・公開ツールを確認できます。安全のためオンを推奨します。
複数サーバーを運用するときの勘所
- サーバーは用途ごとに分け、各サーバーで
tools.includeを絞る。1つのサーバーに何でも積まない。 - 書き込み系ツールを持つサーバーで
supports_parallel_tool_callsを安易に有効化しない(同時実行は副作用の順序が読みにくくなる)。 - ブラウザ自動化系など常駐でメモリを抱えるstdioサーバーには
idle_timeout_seconds/max_lifetime_secondsを設定して肥大を防ぐ。 - 用途ごとに使うサーバーが違うなら、プロファイル(プロファイル管理)で構成を分けると、不要なサーバーを常時起動せずに済む。
前提・操作・期待結果・つまずいたら
- 前提: 入門の最小1接続ができる。接続候補の配布元・実行方法を把握している。
- 操作:
tools.includeで公開ツールを絞り、認証情報は環境変数参照かOAuthで渡し、未信頼サーバーはsampling.enabled: false、停止はenabled: false。保存すると自動で再読み込みされるので、新しいターンで検証する。 - 期待結果: 必要なツールだけが登録され、認証情報を設定に残さず、止めたいサーバーは確実に停止し、変更が新しいターンに反映される。
- つまずいたら:
- 追加したツールが使えない: 保存が成功しているか(無効なJSONは保存できない)と、新しいターンで試したかを確認する。
config.yaml直接編集の場合はmcp.auto_reload_on_config_changeをオフにしていないか確認する。 tools.includeの指定が効かない: プレフィックス付きのmcp__サーバー名__ツール名を書いていないか確認する。指定はサーバー固有の素のツール名で行う。- 無効化したのに動く: 停止キーは
enabled: false。UIスイッチはこのキーを直接書くため、スイッチ操作でも確実に止まる。 - HTTP接続が失敗する: URL・ホスト名・認証方式を確認する。
ssl_verify: falseで回避しない。 - OAuthの認可が403 Forbiddenで弾かれる: WAFが
127.0.0.1のコールバックを拒否している可能性がある。oauth.redirect_hostに"localhost"を設定する。 - 再読み込みできない: ゲートウェイが切断中だと再読み込みできない(ゲートウェイ)。
- ツールが多すぎて挙動が読みにくい:
tools.includeで絞る。サーバーを分ける。 - サーバー側で何が起きたか見えない: MCPタブ下部のログペインか
agent.logでサーバーログを確認する。
- 追加したツールが使えない: 保存が成功しているか(無効なJSONは保存できない)と、新しいターンで試したかを確認する。
関連
- 概念解説: MCPとは何か、なぜ慎重に扱うか
- 入門コース: MCPで能力を広げる(入門)
- リファレンス: MCP / 安全性 / ツールとキー / 安全に設定するための確認事項
- 実践レシピ: 自分のスキルを作る
© 2026 Hermes Desktop ガイド(非公式)。引用・部分転載は、出典として本ページへのリンクを添えていただければ歓迎します。記事全文の無断複製・転載はご遠慮ください。