SSD Nodes Learn Hosting plans →
How to do am Matt ConnorBy Matt Connor

How to reach your Hermes agent from phone

Access your Hermes agent VPS from your phone using private mesh, public HTTPS, or SSH. Learn how to secure your setup for v0.20.0 and revoke access if your phone gets lost.

Di three ways wey you fit take reach your Hermes agent from your phone

To reach your Hermes agent from your phone, you go use di web dashboard, and di main decision na wetin you go put for front of dat dashboard. Option one na private mesh network, wey di dashboard go listen only for Tailscale address and no port go dey face internet. Option two na public endpoint wey dey behind reverse proxy with TLS (transport layer security) and login, where dat login na di only tin wey dey protect terminal go your server. Option three na SSH (secure shell) from terminal app, wey no need plenty setup and e dey give you pass-everything access.

Dis guide start from where running a Hermes agent on your own VPS stop. Di agent don install, e dey answer for command line, and now you want am for your pocket.

Di commands wey dey below, we write am follow tag v2026.8.3, wey dem release for 3 August 2026 and label am v0.20.0 for di release notes. Hermes dey release update quick-quick, so make you pin your machine to one tag instead of follow main. Di installer fit accept commit:

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

hermes --version go print wetin you actually install. Compare am with di tag before you trust any flag wey dey dis page.

Wetin de repository ship, and wetin e no de do

No iOS or Android app dey inside the Hermes repository. The native client na hermes desktop (alias hermes gui), one Electron application for macOS, Windows, and Linux. E fit connect to remote agent instead of local one: set the remote URL to http://<server-address>:9119 for Settings under Gateway, or export HERMES_DESKTOP_REMOTE_URL=http://<server-address>:9119 before you launch am. That one go solve matter for second laptop. E no de do anything for phone.

The surface wey you go use from phone na hermes dashboard, the browser interface. E de manage configuration, sessions, cron jobs, skills, logs, and messaging platforms, and e get terminal inside: the server de spawn hermes --tui behind one PTY (pseudo-terminal) and de stream the output go inside the page. For small screen, the session switcher de fold enter slide-over panel, so the layout de work well for phone.

By default, the dashboard de listen for 127.0.0.1:9119 and e de open browser tab for the server body, wey no get use for headless VPS (virtual private server). Start am without the browser and look the socket:

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

Listener wey dey for 127.0.0.1:9119 na only from the server you fit reach am. Listener wey dey for 0.0.0.0:9119 na from every network wey the machine connect to you fit reach am, including the public one. That one line na im decide how exposed you be, so make you read am instead of just assume.

Option 1: private mesh wit Tailscale

Choose dis one unless you get reason why you no go fit use am. Tailscale na mesh VPN (virtual private network) wey dem build on top WireGuard. Every device wey you add go get stable address and go fit talk direct to oda devices. Your phone go join di same mesh, so di dashboard no go ever need public port at all.

On top di server:

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

Install di Tailscale app for your phone and sign in wit di same account. tailscale status for di server go list your phone by name. Now, bind di dashboard to di address wey tailscale ip -4 print:

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

To bind to di mesh address, instead of 0.0.0.0, e mean say di listening socket go exist only for di Tailscale interface. If you do port scan for your public IP address, you no go see anything for 9119 because nothing dey listen there, so your firewall no be di only thing wey dey protect you again. Confirm am wit ss -lntp | grep 9119 again.

Di bind address sef dey decide authentication, and dis na di part wey many pipo dey miss. On 127.0.0.1, di dashboard no get login. On any oda address, di auth gate na must, and if you no configure provider, di server go refuse to start. Di project dey call dis "failing closed". Run am interactively di first time and e go offer to set up username and password right there, wey dem go save as dashboard.basic_auth for inside ~/.hermes/config.yaml. You fit configure di same provider through ~/.hermes/.env instead, na so di project own worked example dey do am:

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

Generate dat secret wit openssl rand -hex 32 and leave am alone. E dey sign di session cookie, so if you change am, e go sign every device out. Di same file dey hold your model API keys, so keep am private wit chmod 600 ~/.hermes/.env.

Check di gate from anoda machine for di mesh before you trust am:

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

true follow by ["basic"] mean say di gate dey on and na di password provider dey answer. Di project own documentation talk am straight about dat provider: e be for trusted network or VPN, and e no fit for dashboard wey dey face public internet. On top mesh, dat one na exactly di situation wey you dey.

For HTTPS inside di tailnet, give di port to Tailscale:

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

Tailscale dey terminate TLS wit certificate wey dem issue for di machine MagicDNS name, so di browser go stop to dey warn you and di session cookie go get im Secure flag. Enable MagicDNS and HTTPS Certificates for di DNS page of di Tailscale admin console first, and read di acknowledgement while you dey there: dem go publish your machine names and your tailnet DNS name to di public certificate transparency ledger, wey anybody fit read.

Di honest cost here na di coordination server. Traffic between your phone and your VPS dey encrypted end to end and e no dey pass through Tailscale, but di account wey dey decide which devices belong to di mesh no dey your hardware. If dat one matter to you, run di control plane yourself wit Headscale, di self-hosted Tailscale control server, and point clients go there using tailscale up --login-server https://headscale.example.com. If you prefer to comot di mesh and configure peers by hand, di comparison between plain WireGuard and Tailscale cover wetin you go lose.

Option 2: public HTTPS endpoint, and di wahala wey dey inside

Sometimes mesh no dey available. Work phone fit no gree make you install VPN client. Na dat time you go put di dashboard behind reverse proxy. Make di dashboard stay for loopback and allow Caddy handle di certificate:

hermes.example.com {
  reverse_proxy 127.0.0.1:9119
}

Caddy go fetch and renew di certificate by imself, and im reverse_proxy go pass WebSocket upgrades through without extra directives, wey di dashboard embedded terminal need. For nginx, you go need add di Upgrade and Connection headers by yourself, and issuing a Let's Encrypt certificate with Certbot on nginx cover di TLS part of dat work. Tell Hermes im public name so login callbacks go point to di correct host:

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

Now di wahala be dis. Di auth gate dey look bind address, e no dey look di address wey di request take come. Dashboard wey bind to 127.0.0.1 behind proxy go see loopback, e go decide say login no needed, and e go serve anybody wey di proxy allow pass. Check wetin you actually publish:

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

If dat one print false, di internet just one URL away from terminal for your server. No exploit dey involved and nothing for di logs go complain. Two ways dey to fix am and you need at least one of dem. Either you put authentication for inside di proxy, with Authentik as a self-hosted single sign-on provider for front of am via forward auth, or you configure di dashboard own OIDC (OpenID Connect) provider:

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"

Even if you do am correct, dis option get level wey you no fit go lower. Public login page na page wey anybody fit reach and attack, and behind am na shell for your VPS. Username and password na small protection for dat kind thing, na why di docs dey push OAuth or OIDC for public binds. Rate limit di login, keep ufw closed to everything except the proxy ports and SSH, and dey read di access log from time to time.

Option 3: SSH and mosh from mobile terminal

Di easiest way: install terminal app for your phone, put SSH key inside, and use di agent own text interface.

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

tmux new -A -s phone dey attach to session wey dem call phone, or e go create am if e no dey, so di agent go continue dey run even if connection cut and you go land for di same place next time. Di pattern na di same one wey dem dey use for driving Claude Code from a phone.

Normal SSH over mobile network no dey sweet, because connection dey die anytime di phone change address or go sleep. Mosh dey fix dat one. E dey run over UDP (user datagram protocol) and e dey sync terminal state instead of byte stream, so session go survive even if you waka commot from wifi go cellular:

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

From di phone, run mosh you@vps.example.com. Mosh go start mosh-server over your existing SSH login and den e go move di session go UDP for di 60000 to 61000 range, na why you must open dat range.

Di security wahala na di normal one. SSH session na shell, and shell fit do everything wey dat account get permission to do. Di agent approval prompts na di only tin wey dey stand between person wey thief your unlocked phone and your files. Use separate non-root account for dis, use key only, and follow hardening SSH on a VPS before you put key for device wey you dey carry waka.

Wetin dey spoil for mobile network

Four things dey, and none of dem be bug wey you fit fix with configuration.

The dashboard dey log you out while you no dey look. How quick e go happen depend on the login provider. The username and password provider dey give session wey dey last 12 hours by default, wey session_ttl_seconds set under dashboard.basic_auth. The Nous Portal OAuth provider dey issue access tokens wey get 15 minute TTL (time to live), and the current API contract no get refresh token. When token expire, the page go see 401 response and go back to /login. With 15 minute token, if you open the dashboard, put phone for pocket for twenty minutes, you go come back meet login screen and anything wey you dey type don loss. Nothing spoil. Just sign in again.

The embedded terminal no dey survive when you move am go background tab. The server dey spawn the TUI (text user interface) behind a PTY and e dey close am well-well when the tab close, and if you open am again, e go spawn fresh one. Mobile browsers dey discard background tabs to free memory, so if you switch to another app for long time, that terminal go close. Your chat history dey safe, because sessions dey stored for server and hermes sessions list still dey show dem. You no fit reattach to the terminal itself. If you need session wey go survive, use tmux over SSH.

Idle connections dey die quietly. Mobile carriers dey cut idle TCP connections to free NAT (network address translation) table entries, and the phone go stop to dey service the network almost entirely once the screen off. A WebSocket wey don silent for some time usually don die by the time you unlock, and the page go reconnect only after you touch am. Na why mosh dey feel better pass SSH for phone: e no get connection wey e fit lose.

Nothing dey push notification. Neither the dashboard nor an SSH session fit wake your phone. No Hermes app dey for the device, so no path dey to the platform push service. A long agent run go finish, and you go only know when you check am later.

Notifications dey arrive through messaging gateway

The way to fix that last one na the gateway, wey be different method to reach the agent entirely. hermes gateway dey connect the agent to messaging platforms like Telegram, Discord, Slack, WhatsApp, Signal and email. You go come talk to your agent inside one app wey already get push channel for your phone, wey already sabi handle background delivery, and wey sabi manage when network cut.

hermes gateway setup
hermes gateway install
hermes gateway status

hermes gateway install dey register the gateway as one systemd service, so e go start back after reboot. The installer gateway stage fit run that step for you, but nothing for the installer dey create unit for hermes dashboard, so the dashboard no go come back by itself after restart. Write one unit for any part wey you depend on, and writing systemd services and timers on a VPS don cover the file itself.

One scheduled job fit push result the same way, without any conversation:

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

Authorisation for here na deny by default. If no allowlist dey and GATEWAY_ALLOW_ALL_USERS no set, dem go refuse every user, and na that one be the correct place to start. Put the names of the accounts wey you want inside ~/.hermes/.env:

TELEGRAM_ALLOWED_USERS=123456789
GATEWAY_ALLOWED_USERS=123456789

Or you fit use code-based pairing instead of to dey paste numeric IDs. Na this one be the default for chat-style DM platforms, and you fit set am explicitly with unauthorized_dm_behavior: pair inside ~/.hermes/config.yaml. Any unknown account wey message the agent go receive eight-character code, and nothing else go happen until you approve am:

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

Codes dey expire after one hour, user fit request one every ten minutes, and five failed attempts go lock that account out.

How to limit wetin person fit do if dem thief your phone

If your phone fit reach your agent, e mean say that phone fit run commands for your server, and phone fit loss anytime. Decide now wetin the person wey hold the phone fit do.

Make you keep approvals on. approvals.mode defaults to smart, wey dey ask auxiliary model to judge risk and auto-approve only low-risk commands. If you set am to off, e be like say you dey run everything with --yolo, and HERMES_YOLO_MODE=1 dey do am through environment. No carry phone wey dey talk to agent for that state. Set approvals.cron_mode: deny so scheduled jobs no go fit approve demsef while you dey sleep.

approvals:
  mode: smart
  cron_mode: deny

Make the world wey the agent fit break small. terminal.backend: docker dey run commands inside container wey dey drop all Linux capabilities except small list, e dey set no-new-privileges, and e dey limit process count, so the container come be the boundary instead of just prompt. terminal.cwd dey pin the working directory. HERMES_WRITE_SAFE_ROOT dey restrict write_file and patch to the directories wey you name, and if person try write outside those places, e go block am and no approval fit override am.

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

Hermes don already block writes to ~/.ssh, ~/.aws, ~/.kube and /etc/sudoers, and to e own secret stores like ~/.hermes/.env. Project .env files wey dey other place for disk, you no fit read dem but you fit still write to dem. E still dey reject hardline list of destructive commands no matter wetin your approval settings talk. Make you treat that one as base level, no be your full plan. Run the agent as ordinary user, no be root. The same logic apply to any coding agent wey you leave dey run without supervision, and how to run Claude Code safely on a VPS explain am well-well.

Then write down the steps to revoke access before you need am. If you remove the device for Tailscale admin console, e go cut mesh access sharp-sharp. If you change HERMES_DASHBOARD_BASIC_AUTH_SECRET and restart, e go invalidate every dashboard session for every device, because that value dey sign the session cookie. If you delete the phone public key from ~/.ssh/authorized_keys, e go end SSH. hermes pairing revoke telegram <user-id> go remove messaging account. If the device get anything wey fit read your provider keys, drop dem with hermes auth logout <provider> and create new ones upstream.

Check the result, no just assume say e work. These na commands wey you go run for your own box, and wetin dem print depend on how you set your system:

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

The logs dey under ~/.hermes/logs/. Read dem after any incident, and read dem sometimes even when nothing happen.

FAQ

Hermes get official mobile app for iOS or Android?

No. The Hermes repository get command line interface, web dashboard, and Electron desktop client for macOS, Windows and Linux. No first-party iOS or Android build dey. From phone, you fit use the web dashboard for browser, SSH client, or messaging platform wey connect through hermes gateway. Third-party mobile clients dey, but dem be third-party code wey go hold your agent credentials, so read the source code before you install any.

Why Hermes dashboard dey log me out for my phone?

E depend on the login provider. The Nous Portal OAuth provider dey issue access tokens wey expire after 15 minutes (TTL), and the current API contract no get refresh token. So, once the token expire, the page go receive 401 error and go navigate go /login. If you put browser for background for phone, this one go show well-well, because twenty minutes for another app don reach to trigger am. The username and password provider dey default to 12-hour session, wey session_ttl_seconds dey control. With that provider, set HERMES_DASHBOARD_BASIC_AUTH_SECRET to one stable random value so the session signing key go remain the same even after restart; this one go remove the second reason why you dey log out.

I fit put Hermes dashboard for public internet safely?

Only if you don verify the authentication yourself. The auth gate dey switch on based on the bind address, so dashboard wey bind to 127.0.0.1 behind reverse proxy no go ever ask internet for login. Run curl -s https://your-host/api/status | jq '.auth_required' and read wetin come out. Use OAuth or OIDC instead of username and password, because the project documentation talk say the password provider na for trusted networks and VPNs. Private mesh go avoid this question entirely, and that one na why e be the better default.

I need Tailscale account, or I fit self-host the control plane?

You fit self-host am. Headscale na open implementation of the Tailscale coordination server, and official Tailscale clients fit connect to am with tailscale up --login-server https://headscale.example.com. You go come own the list of devices wey you allow enter the mesh. The cost be say you go run and back up that server yourself, and while the server dey down, you no fit enrol or re-authenticate any device.

How I go take get notification for my phone when agent finish job?

Use the messaging gateway. The dashboard and SSH no get way to wake phone, because no Hermes app dey for the device to receive push notification. Connect the agent to Telegram, Signal, Discord or any other supported platform with hermes gateway setup, then make that platform own app deliver the message. Cron job fit also push single message with hermes send -t telegram -s "Job done" -f /path/to/report.txt, wey go deliver without calling the model.