SSD Nodes Learn 🎉 VPS $4.99/月〜
ガイド Matt Connor著者 Matt Connor ・更新日 2026-08-07

スマホからHermesエージェントに接続する方法

VPS上のHermesエージェントへ、Tailscaleのプライベートメッシュ、公開HTTPSエンドポイント、SSHでスマホから接続します。端末紛失時のアクセス無効化も解説します。

スマートフォンからHermesエージェントに接続する3つの方法

スマートフォンからHermesエージェントに接続するには、Webダッシュボードを使用します。重要なのは、そのダッシュボードの前段に何を置くかです。1つ目はプライベートメッシュネットワークです。ダッシュボードはTailscaleのアドレスでのみ待ち受け、インターネットに公開するポートはありません。2つ目は、TLS(トランスポート層セキュリティ)とログイン機能を備えたリバースプロキシの背後に公開エンドポイントを置く方法です。この場合、ログインだけでサーバー上のターミナルへのアクセスを保護することになります。3つ目は、ターミナルアプリからSSH(セキュアシェル)で接続する方法です。設定が最も少なく、その分、最も広いアクセス権を渡すことになります。

このガイドは、自分のVPSでHermesエージェントを実行するの続きです。エージェントはインストール済みで、コマンドラインに応答します。ここからは、スマートフォンから利用できるようにします。

以下のコマンドは、2026年8月3日に公開され、リリースノートでv0.20.0と記載されているtag v2026.8.3を対象にしています。Hermesは頻繁にリリースされるため、mainを追跡するのではなく、マシンでtagを固定してください。インストーラーにはcommitを指定できます。

curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash -s -- --commit 3c27eb6234bf
hermes version

hermes versionは、実際にインストールされている内容を表示します。このページのflagを信頼する前に、tagと比較してください。

リポジトリに含まれるものと、含まれないもの

Hermes リポジトリには iOS アプリも Android アプリもありません。ネイティブクライアントは hermes desktop(別名 hermes gui)です。これは macOS、Windows、Linux 向けの Electron アプリケーションです。ローカルエージェントの代わりにリモートエージェントへ接続できます。Settings の Gateway でリモート URL に http://<server-address>:9119 を設定するか、起動前に HERMES_DESKTOP_REMOTE_URL=http://<server-address>:9119 を export します。これで 2 台目のノートパソコンから利用できます。スマートフォンには対応しません。

スマートフォンから使用する画面は hermes dashboard、つまりブラウザーインターフェースです。設定、セッション、cron ジョブ、skills、ログ、メッセージングプラットフォームを管理できます。ターミナルも組み込まれています。サーバーは PTY(pseudo-terminal)の背後で hermes --tui を起動し、その出力をページにストリーミングします。画面幅が狭い場合、セッション切り替えはスライドオーバーパネルに折りたたまれるため、スマートフォンでもレイアウトを維持できます。

デフォルトでは、ダッシュボードは 127.0.0.1:9119 で待ち受け、サーバー自体でブラウザータブを開きます。これはヘッドレス VPS(virtual private server)では役に立ちません。ブラウザーを開かずに起動し、ソケットを確認します。

hermes dashboard --no-open
ss -lntp | grep 9119

127.0.0.1:9119 のリスナーにはサーバーからのみ接続できます。0.0.0.0:9119 のリスナーには、そのマシンが接続しているすべてのネットワークから接続できます。パブリックネットワークも含まれます。この 1 行で公開範囲が決まるため、推測せずに実際の表示を確認してください。

Tailscale を使ったプライベートメッシュ

特別な理由がない限り、こちらを選んでください。Tailscale は WireGuard を基盤とするメッシュ VPN(仮想プライベートネットワーク)です。登録した各デバイスには固定アドレスが割り当てられ、ほかのデバイスと直接通信します。スマートフォンも同じメッシュに参加するため、ダッシュボードで公開ポートを開く必要はありません。

サーバー上で実行します。

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
tailscale ip -4

スマートフォンに Tailscale アプリをインストールし、同じアカウントでサインインします。サーバー上で tailscale status を実行すると、スマートフォンが名前付きで一覧表示されます。次に、tailscale ip -4 が出力したアドレスにダッシュボードをバインドします。

hermes dashboard --host 100.101.102.103 --port 9119 --no-open

0.0.0.0 ではなくメッシュのアドレスにバインドすると、待ち受けソケットは Tailscale インターフェース上にだけ作成されます。パブリック IP アドレスをポートスキャンしても、9119 番ポートでは何も見つかりません。そこでは何も待ち受けていないためです。これにより、ファイアウォールだけがサーバーを保護する状態ではなくなります。もう一度 ss -lntp | grep 9119 を実行して確認してください。

バインドアドレスは認証方法も決定します。ここを見落とす人が多いので注意してください。127.0.0.1 では、ダッシュボードにログイン機能がありません。それ以外のアドレスでは認証ゲートが必須です。認証プロバイダーを設定していない場合、サーバーは起動を拒否します。プロジェクトではこれをフェイルクローズと呼んでいます。初回は対話形式で実行すると、その場でユーザー名とパスワードの設定を求められます。結果は ~/.hermes/.env に書き込まれます。

HERMES_DASHBOARD_BASIC_AUTH_USERNAME=you
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD_HASH=scrypt$16384$8$1$...
HERMES_DASHBOARD_BASIC_AUTH_SECRET=a-long-random-string

openssl rand -hex 32 でその Secret を生成し、以後は変更しないでください。これはセッション Cookie への署名に使われるため、変更するとすべてのデバイスがサインアウトされます。同じファイルにはモデル API キーも保存されるため、chmod 600 ~/.hermes/.env で非公開にしてください。

信頼する前に、メッシュ上の別のマシンから認証ゲートを確認します。

curl -s http://100.101.102.103:9119/api/status | jq '.auth_required, .auth_providers'

true に続けて ["basic"] が表示される場合、認証ゲートは有効で、応答しているのはパスワードプロバイダーです。プロジェクトのドキュメントでは、このプロバイダーについて明確に説明しています。信頼できるネットワークまたは VPN での利用を想定しており、パブリックインターネットに公開するダッシュボードには適していません。メッシュを使う場合、まさにその条件に該当します。

tailnet 内で HTTPS を使うには、ポートを Tailscale に渡します。

sudo tailscale serve --bg localhost:9119
sudo tailscale serve status

Tailscale は、マシンの MagicDNS 名に対して発行された証明書で TLS を終端します。そのため、ブラウザーの警告が表示されなくなり、セッション Cookie に Secure フラグが付与されます。まず、Tailscale 管理コンソールの DNS ページで MagicDNS と HTTPS Certificates を有効にしてください。その際、確認事項も読んでください。マシン名と tailnet の DNS 名は公開の Certificate Transparency 台帳に公開され、誰でも閲覧できます。

ここで正直に認めるべきコストは、調整サーバーです。スマートフォンと VPS の間の通信はエンドツーエンドで暗号化され、Tailscale を経由しません。しかし、どのデバイスをメッシュに所属させるかを決定するアカウントは、ユーザーのハードウェア上にはありません。これが問題になる場合は、セルフホスト型の Tailscale 制御サーバーである Headscale を使ってコントロールプレーンを自分で運用し、tailscale up --login-server https://headscale.example.com でクライアントの接続先を指定してください。メッシュを使わず、ピアを手動で設定する場合は、WireGuard 単体と Tailscale の比較で失う機能を確認できます。

オプション 2: 公開 HTTPS エンドポイントと、その中に潜む落とし穴

メッシュが利用できない場合があります。業務用スマートフォンでは VPN クライアントをインストールできないことがあります。その場合は、ダッシュボードをリバースプロキシの背後に置きます。ダッシュボードは loopback にバインドしたままにし、証明書は Caddy に管理させます。

hermes.example.com {
  reverse_proxy 127.0.0.1:9119
}

Caddy は証明書を自動で取得・更新します。また、Caddy の reverse_proxy は追加のディレクティブなしで WebSocket のアップグレードを転送します。これは、ダッシュボードに組み込まれたターミナルに必要です。nginx では UpgradeConnection のヘッダーを自分で追加する必要があります。nginx で Certbot を使用して Let's Encrypt 証明書を発行する方法では、この作業の TLS 部分を扱っています。ログインコールバックが正しいホストを指すように、Hermes に公開名を設定します。

dashboard:
  public_url: "https://hermes.example.com"

ここに落とし穴があります。認証ゲートが参照するのは、リクエスト元のアドレスではなく、バインドアドレスです。127.0.0.1 にバインドしたダッシュボードをプロキシの背後に置くと、ダッシュボードからは loopback に見えます。そのためログインは不要と判断され、プロキシが通過させる相手には誰でもコンテンツが提供されます。実際に何を公開しているかを確認します。

curl -s https://hermes.example.com/api/status | jq '.auth_required'

これが false と出力された場合、インターネットから 1 つの URL を経由するだけで、サーバー上のターミナルにアクセスできます。エクスプロイトは必要なく、ログにも異常は記録されません。対処方法は 2 つあり、少なくとも 1 つを実施してください。プロキシ側で認証を設定するか、forward auth 経由で セルフホスト型シングルサインオンプロバイダーとしての Authentik を前段に置きます。または、ダッシュボード独自の OIDC (OpenID Connect) プロバイダーを設定します。

HERMES_DASHBOARD_OIDC_ISSUER=https://auth.example.com/application/o/hermes/
HERMES_DASHBOARD_OIDC_CLIENT_ID=hermes-dashboard
HERMES_DASHBOARD_OIDC_SCOPES="openid profile email"

正しく設定しても、この方法には下げられない最低限のリスクがあります。公開ログインページは誰でも到達して攻撃できるページであり、その背後には VPS 上の shell があります。ユーザー名とパスワードだけでは保護として不十分です。そのため、公開バインドでは OAuth または OIDC を使用するようドキュメントで推奨しています。ログインにレート制限を設定し、proxy ports と SSH 以外をすべて閉じた ufw の設定を維持し、アクセスログを定期的に確認してください。

モバイル端末から SSH と mosh を使う

最も手間が少ない方法は、スマートフォンにターミナルアプリをインストールし、SSH key を読み込ませて、エージェント本来のテキストインターフェースを使うことです。

ssh you@vps.example.com
tmux new -A -s phone
hermes --tui

tmux new -A -s phonephone という名前のセッションに接続します。セッションが存在しない場合は作成します。そのため、接続が切れてもエージェントは実行を続け、次回は同じ場所に戻れます。この方法は、スマートフォンから Claude Code を操作する際に使うものと同じです。

モバイルネットワーク上で通常の SSH を使うと、スマートフォンのアドレスが変わったり、スリープしたりするたびに接続が切れるため、不便です。mosh はこの問題を解決します。mosh は UDP(user datagram protocol)を使用し、バイトストリームではなくターミナルの状態を同期します。そのため、Wi-Fi から携帯回線へ移動してもセッションを維持できます。

sudo apt install -y mosh
sudo ufw allow 60000:61000/udp

スマートフォンから mosh you@vps.example.com を実行します。mosh は既存の SSH ログインを使って mosh-server を起動し、その後セッションを UDP の 60000 から 61000 の範囲へ移します。そのため、この範囲のポートを開放する必要があります。

セキュリティ上のリスクは単純です。SSH セッションは shell であり、shell からはそのアカウントが実行できるすべての操作が可能です。すると、盗まれてロック解除されたスマートフォンとファイルの間に残る最後の防御は、エージェントの承認プロンプトだけになります。この用途には専用の非 root アカウントを使用し、認証方式は key のみにしてください。また、持ち歩くデバイスに key を保存する前に、VPS の SSH を強化する手順を実施してください。

モバイルネットワークで機能しなくなること

設定で解消できない問題が4つあります。

見ていない間にダッシュボードからログアウトされます。 アクセストークンの TTL(有効期間)は15分で、現在の API 契約にはリフレッシュトークンがありません。トークンの有効期限が切れると、ページは401レスポンスを検出し、/loginへ戻ります。ダッシュボードを開いたまま、スマートフォンをポケットに入れて20分待つと、入力中の内容が失われたログイン画面に戻っています。故障ではありません。もう一度サインインしてください。

埋め込みターミナルはバックグラウンドタブに対応できません。 サーバーは PTY の背後で TUI(テキストユーザーインターフェイス)を起動し、タブが閉じると正常に終了させます。タブを開き直すと、新しい TUI が起動します。モバイルブラウザーはメモリを回収するためにバックグラウンドタブを破棄することがあり、別のアプリに切り替えたまま長時間経過すると、そのターミナルも終了します。セッションはサーバーに保存され、hermes sessions listには引き続き表示されるため、チャット履歴は失われません。ターミナル自体に再接続することはできません。切断後も維持されるセッションが必要な場合は、SSH 経由で tmux を使用してください。

アイドル状態の接続は静かに切断されます。 モバイルキャリアは NAT(ネットワークアドレス変換)テーブルのエントリを解放するため、アイドル状態の TCP 接続を切断します。また、画面をオフにすると、スマートフォンはネットワーク処理をほぼ停止します。しばらく通信していない WebSocket は、ロック解除時にはすでに切断されていることが多く、ページが再接続するのは画面に触れてからです。スマートフォンでは SSH より mosh のほうが快適に感じられるのはこのためです。mosh には失うべき接続自体がないためです。

通知はプッシュされません。 ダッシュボードも SSH セッションも、スマートフォンを起動することはできません。デバイスに Hermes アプリがないため、プラットフォームのプッシュサービスへ通知を送る経路もありません。長時間実行するエージェント処理が完了しても、次に画面を見るまで気付きません。

通知はメッセージングゲートウェイ経由で届きます

最後の問題は、エージェントへの接続方法を根本的に変えるゲートウェイで解決できます。hermes gatewayは、Telegram、Discord、Slack、WhatsApp、Signal、メールなどのメッセージングプラットフォームにエージェントを接続します。これにより、スマートフォンでプッシュ通知の経路をすでに持ち、バックグラウンド配信にも対応し、ネットワークが切断された場合も処理できるアプリ内でエージェントとやり取りできます。

hermes gateway setup
hermes gateway install
hermes gateway status

hermes gateway installはゲートウェイをsystemdサービスとして登録するため、再起動後も復帰します。Hermes installerはサービスユニットを作成しないため、再起動後にhermes dashboardが自動的に復帰することはありません。依存する各コンポーネント用にユニットを作成してください。ファイル自体の作成方法については、VPSでのsystemdサービスとタイマーの作成を参照してください。

スケジュールされたジョブも、会話を介さずに同じ方法で結果を送信できます。

hermes send -t telegram -s "Backup report" -f /home/you/report.txt

ここでの認証は、デフォルトで拒否されます。allowlistを設定せず、GATEWAY_ALLOW_ALL_USERSも未設定の場合、すべてのユーザーが拒否されます。これは適切な開始状態です。許可するアカウントを~/.hermes/.envに指定します。

TELEGRAM_ALLOWED_USERS=123456789
GATEWAY_ALLOWED_USERS=123456789

または、数値IDを貼り付ける代わりに、unauthorized_dm_behavior: pair~/.hermes/config.yamlで設定してコードベースのペアリングを有効にします。未知のアカウントがエージェントにメッセージを送ると、8文字のコードが返されます。承認するまで、それ以外の処理は行われません。

hermes pairing list
hermes pairing approve telegram ABC12DEF
hermes pairing revoke telegram 123456789

コードの有効期限は1時間です。ユーザーがリクエストできるのは10分に1回です。認証に5回失敗すると、そのアカウントはロックアウトされます。

盗難されたスマートフォンの被害範囲を限定する

エージェントに接続できるスマートフォンは、サーバー上でコマンドを実行できます。そして、スマートフォンは紛失します。手にした人が何を実行できるかを、今のうちに決めておいてください。

承認は有効にしておきます。approvals.mode のデフォルト値は smart です。この設定では補助モデルがリスクを判定し、低リスクのコマンドだけを自動承認します。off に設定すると、すべてを --yolo で実行するのと同じ状態になります。HERMES_YOLO_MODE=1 では環境変数を通じて同じ状態にします。その状態でエージェントに接続するスマートフォンを持ち歩かないでください。approvals.cron_mode: deny を設定し、スケジュールされたジョブが就寝中に自動承認できないようにします。

approvals:
  mode: smart
  cron_mode: deny

エージェントが操作できる範囲を小さくします。terminal.backend: docker は、短い許可リスト以外の Linux capability をすべて削除したコンテナ内でコマンドを実行し、no-new-privileges を設定し、プロセス数を制限します。これにより、プロンプトではなくコンテナが境界になります。terminal.cwd は作業ディレクトリを固定します。HERMES_WRITE_SAFE_ROOT は、write_filepatch がアクセスできるディレクトリを指定した場所に制限します。指定外への書き込みは、承認で上書きすることもできず、ブロックされます。

export HERMES_WRITE_SAFE_ROOT=/home/you/projects:/home/you/.hermes

Hermes はすでに ~/.ssh~/.aws~/.kube/etc/sudoers への書き込みをブロックし、ディスク上のどの場所にも .env ファイルを書き込めないようにし、承認設定に関係なく破壊的なコマンドの厳格なリストを拒否します。これは最低限の保護であり、これだけを対策にしないでください。エージェントは通常ユーザーとして実行し、root としては絶対に実行しないでください。同じ考え方は、 unattended で実行したままにするあらゆるコーディングエージェントにも当てはまります。VPS 上で Claude Code を安全に実行する方法では、この点をさらに詳しく説明しています。

次に、必要になる前に失効手順を書き出しておきます。Tailscale の管理コンソールでデバイスを削除すると、メッシュへのアクセスが直ちに切断されます。HERMES_DASHBOARD_BASIC_AUTH_SECRET を変更して再起動すると、すべてのデバイス上のダッシュボードセッションが無効になります。この値がセッション Cookie の署名に使われるためです。スマートフォンの公開鍵を ~/.ssh/authorized_keys から削除すると、SSH 接続を終了できます。hermes pairing revoke telegram <user-id> はメッセージングアカウントを削除します。デバイスにプロバイダーのキーを読み取れる情報が保存されていた場合は、hermes auth logout <provider> でキーを無効化し、プロバイダー側で新しいキーを発行してください。

推測で済ませず、結果を確認してください。以下は自分のサーバーで実行するコマンドです。出力内容は環境によって異なります。

tailscale status
hermes pairing list
hermes logs gateway -n 100
hermes status --deep

ログは ~/.hermes/logs/ に保存されます。インシデントの後に読み、インシデントが発生していないときも定期的に確認してください。

FAQ

iOS または Android 用の公式 Hermes モバイルアプリはありますか?

いいえ。Hermes リポジトリには、コマンドラインインターフェイス、Web ダッシュボード、macOS、Windows、Linux 向けの Electron デスクトップクライアントが含まれています。iOS または Android 向けの公式ビルドはありません。スマートフォンからは、ブラウザーで Web ダッシュボードを使用するか、SSH クライアントを使用するか、hermes gateway 経由で接続したメッセージングプラットフォームを使用します。サードパーティー製のモバイルクライアントもありますが、エージェントの認証情報を保持するサードパーティーコードです。インストールする前にソースコードを確認してください。

Hermes ダッシュボードからスマートフォンでログアウトされるのはなぜですか?

アクセストークンの TTL は 15 分で、現在の API 契約にはリフレッシュトークンがありません。トークンの有効期限が切れると、ページは 401 を受け取り、/login へ移動します。スマートフォンでブラウザーをバックグラウンドにすると、この動作が顕著になります。別のアプリを 20 分使用するだけで有効期限に達するためです。HERMES_DASHBOARD_BASIC_AUTH_SECRET には安定したランダム値を設定してください。これによりセッション署名キーが再起動後も同じになり、ログアウトされるもう1つの原因を解消できます。

Hermes ダッシュボードを安全にパブリックインターネットへ公開できますか?

自分で認証を検証した場合に限り可能です。認証ゲートは bind address に基づいて有効になるため、127.0.0.1 に bind したダッシュボードを reverse proxy の背後に置いても、インターネット側にはログインを要求しません。curl -s https://your-host/api/status | jq '.auth_required' を実行し、返された内容を確認してください。username と password ではなく OAuth または OIDC を使用してください。プロジェクトのドキュメントでは、password provider は信頼済みネットワークと VPN 向けと説明されているためです。プライベートメッシュを使用すれば、この問題自体を避けられます。そのため、こちらがより適切なデフォルトです。

Tailscale アカウントは必要ですか。それとも control plane を自分でホストできますか?

自分でホストできます。Headscale は Tailscale coordination server のオープンな実装であり、公式 Tailscale クライアントは tailscale up --login-server https://headscale.example.com を使用して接続できます。これにより、メッシュへの参加を許可するデバイスの一覧を自分で管理できます。ただし、そのサーバーを運用してバックアップする必要があります。また、サーバーが停止している間は、デバイスを登録したり再認証したりできません。

エージェントがジョブを完了したときに、スマートフォンへ通知するにはどうすればよいですか?

メッセージングゲートウェイを使用してください。デバイス上で通知を受信する Hermes アプリがないため、ダッシュボードと SSH にはスマートフォンを起動する機能がありません。hermes gateway setup を使用してエージェントを Telegram、Signal、Discord、またはその他の対応プラットフォームへ接続し、そのプラットフォームのアプリから通知を配信させます。cron job から hermes send -t telegram -s "Job done" -f /path/to/report.txt を使用して単一のメッセージを送信することもできます。この方法では model を呼び出さずに配信できます。

#hermes#mobile#remote-access#tailscale#ai-agents