デスクトップ版から複数の Hermes につなぐ
目次
自分が持っている Hermes のバックエンド — 手元のランタイム、LAN や VPS にある リモートのゲートウェイ、SSH でつなぐホスト、Hermes Cloud のインスタンス — を 1つのデスクトップアプリにまとめて登録し、そのすべてのエージェントを並べて使えます。 接続は保たれたままです。登録した各ゲートウェイは必要になったときに自分のバックエンドと WebSocket をつなぎ、別のゲートウェイを表示しているあいだも、裏で動いている エージェントは応答を返し続けます。
これは ゲートウェイを同時に複数動かすの デスクトップ側の対になる説明です。あちらは1つのマシンで複数のゲートウェイを動かす話で、 こちらは1つのデスクトップアプリが複数のマシンと話す話です。
どこにあるか
設定はすべて Settings → Gateways のページにまとまっています(古いビルドでは Gateway と Connections が別ページでした。従来の Connections へのリンクは このページに転送されます)。たどり着く道は3つあります。
- Settings → Gateways — ページそのものです(Cmd/Ctrl+, を押し、設定の
ナビゲーションから Gateways を選びます)。接続の一覧はこのページの一部で、 マシン単位の接続モードの設定より下に並んでいます。
- サイドバーのプロファイル列 — 列の右端にあるプラグのボタン(ツールチップは
「Connect another Hermes gateway…」)から、Gateways ページへ直接飛べます。 2つめのプロファイルや2つめの接続をまだ作っていなくても、いつでも表示されています。
- コマンドパレット — Cmd/Ctrl+K を押して *Gateways* と入力します(*connections*、
*add gateway*、*remote*、*ssh*、*instances* でも見つかります)。
ゲートウェイの一覧
Settings → Gateways の Registered gateways の節では、名前を付けた Hermes ゲートウェイの一覧を管理します。冒頭の説明にはこう書かれています。*「Manage this device and every Hermes gateway it can reach through remote, SSH, or Cloud connections.」* 1つ1つの項目が *接続* にあたります。
| 種類 | 何を指すか | 認証 |
|---|---|---|
| Local | 「The Hermes runtime managed by this app.」(このアプリが管理する Hermes ランタイム) | 自動 |
| Remote gateway | 「A Hermes gateway reachable over HTTP(S) — LAN, Tailscale, or the internet.」(HTTP(S) で届く Hermes ゲートウェイ。LAN、Tailscale、インターネット経由) | セッショントークンまたは OAuth |
| SSH | 「A Hermes install reached over SSH.」(SSH 越しに届く Hermes)。アプリがトンネルを開き、ダッシュボードを起動します | SSH 鍵と引き継いだトークン |
| Hermes Cloud | 「A hosted instance discovered through your Hermes Cloud account.」(Hermes Cloud アカウントから見つかるホスト型インスタンス) | ポータルへのサインイン |
知っておきたい決まりごとがあります。
- どの接続にも重複しないデバイス名が必要です(「Homelab」「Work laptop」など)。
この名前は、そのインスタンスが登場するあらゆる場所 — 一覧のバッジ、ハンドル、 更新結果 — に出てきます。大文字と小文字は区別しないので、Homelab と homelab を 同時に持つことはできません。
- local の項目はアプリが管理していて(App-managed のラベルが付きます)、
削除できません。それ以外の接続を削除すると、その接続が使っていたバックエンドと トンネルは片付けられますが、インスタンス自体には手を触れません。
- どれか1つの接続が必ず Primary になります(その行にラベルが付きます)。
ゲートウェイを名指ししない複数ゲートウェイ向けの呼び出しは、この接続に落ちてきます。 Make primary を押しても、いま開いている Sessions の作業場所は切り替わりません。 Primary を削除すると local の項目に戻ります。
- At startup, return to Sessions on the last-used gateway は、アプリを完全に
再起動したあと Sessions がどのゲートウェイで開くかを決めます。初期状態では オフなので、Sessions は Primary で開きます。オンにすると、最後に接続に成功した ゲートウェイを開き直します。切り替えに失敗したものは記憶されず、保存されたゲートウェイが 削除されていたり届かなかったりする場合は Primary に戻ります。
- Test はその接続の HTTP と WebSocket の両方を試します。つまり合格すれば
(*「Reachable」* のトーストが出れば)、ホストに ping が通っただけでなく、 チャットが実際に動くという意味になります。
- 保存時に重複は弾かれます。local の項目は常に1つだけです。remote と
cloud の項目は正規化した URL(前後の空白を削り、末尾のスラッシュを外し、 小文字にしたもの)で重複を判定します。しかも両方の種類にまたがって判定するので、 cloud の項目と remote の項目が同じ URL を指すことはできません。SSH の項目は 正規化した user@host:port とリモート側のプロファイルの組で判定します。
- cloud の項目は普通、Gateways ページ上部にある Hermes Cloud のサインインと検出の
流れから作られます。接続を追加する画面の Hermes Cloud という種類は、そちらへ 案内するためのものです。
ゲートウェイの切り替えは Sessions のサイドバーから行います。プロファイル、チャット、 メッセージ、cron はそのゲートウェイの中だけで完結します。アプリが管理するウィンドウ側の バックエンドは、これまでどおり上の接続モードの設定で決まります。Primary は名指しが ないときの受け皿で、いま開いている作業場所を切り替えるものではありません。
接続を追加する手順
- Settings → Gateways を開き、接続の一覧までスクロールします(プロファイル列の
プラグを押しても構いません)。
- Add connection を押します。
- 種類を選びます。Local、Hermes Cloud、Remote gateway、SSH のいずれかです。
(アプリが管理する local の項目があるあいだ Local は選べません — ほとんどの場合 そうなっています。Hermes Cloud は上にあるサインインと検出の流れへ案内されます。)
- 項目を埋めます。
- Name — 必須で、重複できません。このインスタンスが出てくるすべての場所に表示される
「デバイス名」です(入力例: Homelab)。最大64文字です。
- *Remote gateway のときだけ:*
- Gateway URL — 動いている
hermes serveのバックエンドのベース URL です。
- Gateway URL — 動いている
たとえば http://homelab.lan:9119 のように書きます。リバースプロキシで パスの先頭を足している場合も使えます。
- Authentication — Session token か OAuth を選びます。
- Session token — リモート側のゲートウェイのダッシュボードのセッショントークンを
貼り付けます。編集するときは *「Leave blank to keep the saved token.」*(空のままにすると保存済みのトークンを使い続けます)。
- OAuth — Nous Portal のブラウザ画面でサインインします。貼り付けるトークンは
ありません。
- *SSH のときだけ:*
- SSH host —
user@host:22の形でまとめて書く1つの欄です(ユーザーと
- SSH host —
ポートは省略できます)。認証には自分の SSH 鍵が使われ、アプリはトンネル越しに ダッシュボードのトークンを引き継ぎます。
- Save connection を押します(やめるときは Cancel)。
- 追加された行の Test を押し、*「Reachable」* が出るのを待ちます。
local 以外の項目は、あとから鉛筆のボタンで編集したり、ゴミ箱のボタンで削除したりできます。 削除するときは確認が出て、*「The instance itself is not touched — you can add it again any time.」*(インスタンス自体には 手を触れないので、いつでも追加し直せます)と伝えてくれます。
接続が1つだけだった頃の設定からの移行
一覧に対応したビルドを最初に起動したとき、それまでの設定は自動で取り込まれます。 全体の接続モードと、Settings → Gateway にあった従来のプロファイルごとの上書き設定は、 名前の付いた一覧の項目になります(URL とホストで重複は取り除かれます)。 (新しいビルドの Gateways の設定ページには、プロファイルごとの上書きはもうありません。 ゲートウェイの接続はマシン単位のもので、プロファイルはつないだゲートウェイから見つかります。) 従来の設定ファイルはそのまま残るので、同じマシンにある古いビルドも動き続けます。 取り込んだ名前がぶつかった場合は、末尾に数字が付きます(Homelab 2)。
ゲートウェイをまたいだエージェント
登録したすべての接続にある、すべてのプロファイルが *エージェント* です。それらを合わせた1つの名簿が、複数ゲートウェイ対応の画面 (および組み込みの Bot Mode の名簿)に表示されます。
- 同じプロファイル名が複数のゲートウェイにあるとき、ハンドルは
@name-device の形で区別されます。Homelab にある research は @research-homelab と表示され、すべてのゲートウェイを通して1つしかないプロファイルは 名前だけのままです。
- 一覧の作成は先回りしますが、ソケットは後回しです。アプリは REST を使って
エージェントを並べるだけで、すべてのゲートウェイの WebSocket をつなぎに行くことは ありません。届かないゲートウェイがあっても、その行だけがエラーを知らせるので名簿全体は 壊れません。SSH の接続は、そこにあるエージェントを最初に開くまで必要時接続のままです (知らないうちにトンネルが張られることはありません)。
- エージェントを開くと、そのエージェントのゲートウェイにつなぎに行きます。
チャット、セッション、記憶は、そのプロファイルを持つマシンの上にあります。 そのインスタンスを直接使っているときとまったく同じです。
(connection, profile) の組ごとに、専用のバックエンドとソケットが用意されます。 これらはローカルのプロファイルごとのバックエンドと同じように、使われていないものから 片付けられていきます。別のゲートウェイを見ているあいだも、裏のエージェントは応答を 返し続けます。
切り替えと適用範囲
サイドバーの下部は ゲートウェイ → プロファイル → セッション という1つの階層に 沿っています。ゲートウェイはマシンやホスト型のバックエンドで、プロファイルは1つの ゲートウェイの上で動く、互いに隔てられた Hermes のエージェントです。
- 登録したゲートウェイが1つだけなら、ゲートウェイを選ぶ操作は増えません。ローカルだけで
使うデスクトップ版は、これまでどおりのプロファイル列とキーボード操作のままです。
- ゲートウェイが複数あるときは、サイドバーに名前付きのゲートウェイ選択欄が1つ出ます。
デバイス、クラウド、ネットワーク、ターミナルのアイコンが接続の種類を表します。 プロファイルのアバターは区切り線の後ろにある別の操作のままです。この選択欄は ゲートウェイが2つのときから、もっと数が増えたときまで同じように使えます。 バックエンドをプロファイルのような小さな記号に変えたり、プロファイルの操作を列から 押し出したりはしません。
- ゲートウェイを選ぶと、そこで最後に使っていたプロファイルが戻ってきます。ホームのラベルは
既定のプロファイルに戻り、レイヤーのラベルは All profiles on this gateway を 表示します。 Cmd/Ctrl+1–9 は、これまでどおり選択中のゲートウェイの中でプロファイルを切り替えます。
- ゲートウェイが複数あるとき、プロファイルの列は全体のプロファイル列になります。登録した
すべてのゲートウェイのプロファイルが1本の帯に並び、それぞれの組の先頭には、そのゲートウェイ の種類を表す記号(デバイス、ネットワーク、ターミナル、クラウド)が付きます。ゲートウェイの 選択欄で使われているのと同じ記号です。選択中のゲートウェイの四角は、ゲートウェイが1つの デスクトップ版とまったく同じ見え方をします。ほかのゲートウェイの四角は薄く表示されます (「休んでいる」状態です)。休んでいる四角にマウスを重ねるとそのマシン名が出るので (omer · This device)、別のマシンにある同じ名前のプロファイルを取り違えずに済みます。
- 休んでいる四角をクリックすると、ゲートウェイの選択欄と同じ切り替えが起き、その
(gateway, profile) にそのまま移ります。相手を呼び出しているあいだ四角は回り、相手が 応じるまでは前のゲートウェイの表示が残ります。相手が落ちている場合はメッセージを出して クリックが失敗するので、ウィンドウが中途半端に切り替わることはありません。組の並びは どのゲートウェイを選んでいても登録した順のままなので、クリックした四角がポインタの下で 動くこともありません。休んでいる四角を右クリックすると Switch to、Color、 Rename、Edit SOUL.md、Delete が選べ、いずれもその四角自身のゲートウェイの上で 実行されます。削除の確認にはマシン名が出ます。
- 直前の一覧取得でつながらなかったゲートウェイも四角はそのまま残り、種類の記号に琥珀色の点が
付きます。眠っている箱も自分のものだからです。同じバックエンドを2回登録していた場合は、 1つの組にまとまります。全体で四角が13個を超えると、帯はゲートウェイごとに区切られた 1つのメニューにまとまります。
- 選んだゲートウェイが終了と再起動をまたいで残るのは、**Settings →
Gateways → At startup, return to Sessions on the last-used gateway** がオンのときだけです。 この設定とゲートウェイの id はアプリのユーザーデータの中に保存されるので、 アプリケーション本体を入れ替えたり更新したりしても消えません。
- 選択中のゲートウェイにプロファイルが13個より多くあるときは、アバターの並びが
名前付きのプロファイル選択欄にまとまります。そのため、ゲートウェイもプロファイルも 数が多い状態が、ゲートウェイ → プロファイル → セッション の考え方を変えずに 同居できます。
- リモートの接続が Primary になっていても、This device は変わらず一人前の
ゲートウェイです。リモート側が止まっているあいだも手元のセッションを使い続けられますが、 アプリはこれを「オフラインモード」とは呼びません。選んでいるモデルやツールが インターネットを必要とすることがあるからです。
- セッションの一覧、メッセージのチャンネル、cron のジョブ、設定、ファイル、記憶は、
すべて選択中の (gateway, profile) の中だけのものです。Telegram のゲートウェイから Signal のゲートウェイへ切り替えたときに、前のゲートウェイのチャンネルのまとまりや セッションがサイドバーに残ることはありません。
- 切り替えの操作を表示するだけなら、読むのは Electron が持つ手元の接続一覧だけです。
リモートのゲートウェイは選ばれたときにだけ開かれます。定期的に全体を見に行くような 問い合わせは行いません。
- エージェントにマウスを重ねると、そのバックエンドを先に温めておくので、切り替えのときに
起動待ちが起きません。
- Capabilities のページ(Skills / Tools / MCP)も同じ考え方で範囲が決まります。
Configuring の選択欄には、合わせた名簿にあるすべての (profile, device) の エージェントが並び、選んだものについて そのマシンの スキル、ツールセット、MCP サーバーを読み書きします。Sessions の作業場所は切り替わりません。ハブからの導入、 環境変数の鍵、MCP の設定は、すべて選んだエージェントのバックエンドに入ります。 MCP タブにある *動いているセッションへ即座に読み込ませる* ボタンは、そのウィンドウが つないでいるゲートウェイのエージェントにだけ出ます。ほかのマシンでの変更は、 次のセッションから効きます。
ゲートウェイの追加、テスト、名前の変更、削除は Settings → Gateways で行います。 プロファイルの操作の横にあるプラグのボタンは、その管理場所への近道であって、 2つめの追加画面ではありません。
セッションと Bot Mode
Sessions では、あえて一度に1つのゲートウェイだけを表示します。こうすることで、ファイル、 ツール、チャンネル、cron、セッションの履歴が1つの分かりやすい実行環境の中に収まります。 全体のプロファイル列が広げるのは*選ぶ場所*だけで、クリックしたあとの作業場所は やはり1つの (gateway, profile) の上にあります。Bot Mode の役割は別なので、合わせた名簿をゲートウェイごとにまとめて見せることがあります。 NAS の上のエージェントと VPS の上のエージェントを、1つの画面から開けるということです。 ボットを開いたときに動くのは、これまでどおりその (gateway, profile) の経路です。
ボットへの直接のメンションや委任は、初期状態ではそのゲートウェイの中に閉じています。 バックエンドの境界を越えると、ファイルシステム、認証情報、ツール、信頼の前提が変わります。 ですからゲートウェイをまたぐ実行は、1つのデスクトップのウィンドウを共有したことによる 思わぬ副作用ではなく、はっきり意図して架けた橋であるべきです。
すべてのインスタンスをまとめて更新する
Settings → Gateways → Update all instances(接続が2つ以上登録されると出てきます)は、 対象になるすべての接続へ hermes update を並行して送ります。
- Local はアプリ自身の更新の仕組みで更新されます(Settings → Updates と同じ流れです)。
- Remote と SSH の接続には、それぞれのバックエンド経由で自分自身を更新するよう
伝えます。更新は *そのマシンの上で* 走ります。
- Hermes Cloud のインスタンスは *「Managed by Hermes Cloud」* という注記とともに
飛ばされます。バージョンの管理はプラットフォーム側が行うからです。
インスタンスごとに個別に結果が返るので、届かないマシンが1つあってもまとめて止まることは ありません。更新を外部の仕組みに任せているバックエンド(Docker、Nix)は、行ごとに 自分の言葉で丁寧に断ってきます。
とはいえ、設定画面のボタンを押す機会はあまりありません。更新の対象が2つ以上になると、 アプリのふだんの更新の入り口(About パネルの Update now、⌘K の Update Hermes、 更新の準備ができたことを知らせるトースト)から、同じ一斉更新が自動で走ります。 順番は、まず動いているバックエンド、次に対象になるほかのゲートウェイ、最後に デスクトップアプリ自身です。デスクトップ版の案内にある 更新するも参照してください。
セキュリティ上の注意
- トークンの置き場所。 リモートのゲートウェイのセッショントークン(およびアプリ内での
サインインで得た OAuth トークン。ゲートウェイのベース URL を鍵にして保存されます)は、 アプリのユーザーデータのディレクトリに、所有者だけが読める(0600)ファイルとして Electron のメインプロセスの中で保存されます。描画側やプラグインがトークンの中身を 見ることはありません。
- 鍵管理サービスによる暗号化(任意)。 初期状態では、トークンは OS の鍵管理サービスを
通しません。とくに macOS では Electron の safeStorage がアプリごとの鍵を ログイン用のキーチェーンに置くため、キーチェーンがロックされていたり壊れていたりすると、 起動のたびにパスワードを聞かれることになります。ファイルの権限に加えて保存時の暗号化も かけたい場合は、Settings → Gateway → 「Encrypt saved secrets with the OS keychain」 をオンにしてください。すでに保存されている 秘密の情報はその場で暗号化し直されます(macOS ではキーチェーン、Windows では DPAPI、 Linux ではセッションのキーリングを使います)。オフに戻せば、また復号されます。
- 一覧のファイル(アプリのユーザーデータのディレクトリにある
connections.json)が
持っているのは、ラベル、URL、ホストだけです。秘密の情報は必ず暗号化された封筒の中にしか 現れません。
- プラグイン SDK の
host.connections()が返すのは、ラベル、種類、Primary の id だけです。
トークンそのものは決して返しません。
プラグインを作る人へ
デスクトップ版のプラグイン SDK は、 複数ゲートウェイの仕組みをそのまま公開しています。
host.connections()— 登録された接続の一覧(ラベル、種類、Primary。トークンの
中身は含みません)。
host.agents()— 合わせた名簿。(gateway, profile)の組ごとに1行で、
@name-device のハンドルがあらかじめ計算されています。
host.ensureAgent(connectionId, profile)— エージェントのゲートウェイを有効にして、
以降の host.request の呼び出しがそのバックエンドに届くようにします。
host.warmAgent(connectionId, profile)— 結果を待たずにソケットを先に温めます
(マウスを重ねた時点で使う想定です)。
4つとも、あるかどうかを確かめてから使う設計です。古いデスクトップ版のビルドには存在しないので、 プラグイン側は1つのゲートウェイだけを扱う profiles.list の流れに戻せるようにしてください。 Bot Mode の複数ゲートウェイ対応の名簿が、お手本になる使い方です。
うまくいかないとき
- 「Connection test failed」 — このマシンから、その URL でバックエンドに届いていません。
リモートのホストで hermes serve が動いているか、ポートが開いているか、 (トークンで認証しているなら)トークンが今も有効かを確かめてください。直したら Test をもう一度押します。
- エージェントは見えるのに開けない — その接続で Test を押してください。
HTTP は通るのに WebSocket だけ失敗する場合、たいていはプロキシ、ファイアウォール、 ゲートウェイの認証や接続元の確認が /api/ws を塞いでいます。
- リモートのゲートウェイが名簿に出てこない — そのバックエンドが止まっているか、
届かない状態です。名簿ではゲートウェイの下にエラーとともに並びます。SSH の接続は 最初に使うまで *必要時接続* と表示されますが、これは設計どおりで、故障ではありません。
- 「Update Hermes Desktop to chat with agents on other connections」 — アプリが
複数接続の仕組みより前のものです。デスクトップアプリ自身を更新してください。
- デバイス名が重複している — そうはなりません。名前は保存の時点で重複できないように
なっています。取り込んだ名前がぶつかった場合は、末尾に数字が付きます(Homelab 2)。
- 「Could not save the connection」 — よくあるのは Name が空、その名前がすでに
使われている、Gateway URL や SSH host の書き方が正しくない、のいずれかです。 エラーメッセージが、どこが違反しているかを名指しで教えてくれます。