Google Play
Fastest setup, automatic updates, and the complete everyday Hermes experience.
- Chat, voice, profiles, and Manage
- Terminal, media, and notifications with Relay
- No AccessibilityService or unattended phone control
Three steps — install the app, point it at your Hermes, say hello. If your Hermes agent is already running, this takes about two minutes and needs nothing installed on the server.
Choose the build by one question: do you want Hermes to operate the phone, or only be available from it? Both builds come from the same codebase and can live side-by-side.
Fastest setup, automatic updates, and the complete everyday Hermes experience.
The same app plus Device Control for people who want Hermes to operate the phone.
The Release tracks page explains the full capability and safety differences. Building from source is an advanced alternative under the Sideload instructions below.
Grab the signed APK directly from GitHub Releases — works on any Android 8.0+ device.
1. Download the APK. Head to github.com/Codename-11/hermes-relay/releases, open the newest Android release (android-v*; historical Android releases used bare v*), and grab the file ending in -sideload-release.apk — for example, hermes-relay-1.0.0-sideload-release.apk.
Download the .apk, not the .aab
Each release also ships -release.aab files. That's the Android App Bundle format Google Play uses internally — it won't install directly on your device. Always pick a file ending in .apk.
2. Allow installs from your browser (first time only). Android blocks APKs from unknown sources by default:
The exact wording varies by OEM (Samsung and Pixel both say "Install unknown apps"; older versions use "Security → Unknown sources"), but the idea is the same.
3. Install it. Open the downloaded APK from your Downloads notification or the Files app, then tap Install.
4. Verify integrity (optional but recommended). Every release ships a SHA256SUMS.txt. Compare your download's checksum before installing:
sha256sum hermes-relay-*-sideload-release.apk
# Compare the output against the matching line in SHA256SUMS.txtGet-FileHash -Algorithm SHA256 hermes-relay-*-sideload-release.apk
# Compare the Hash column against the matching line in SHA256SUMS.txtIf the hashes don't match, don't install — redownload and try again.
5. Verify the signing certificate (advanced). The APK is signed with the Codename-11 release keystore. To confirm the signature matches the one Google Play pins to the app, compare this fingerprint:
A9:A4:2D:94:20:8B:94:B3:68:5B:01:93:E3:94:9B:90:50:AD:80:60:56:E7:16:3C:FC:E5:11:AF:68:0D:79:4Bkeytool -printcert -jarfile hermes-relay-*-sideload-release.apkgit clone https://github.com/Codename-11/hermes-relay.git
cd hermes-relay
scripts/dev.bat build # Build debug APK
scripts/dev.bat run # Build + install + launch (requires connected device)Hermes-Relay talks to two upstream Hermes surfaces:
:8642 — Chat and sessions:9119 — Manage sign-in and admin screensAlready have a Hermes server — or someone set one up for you?
If Hermes is already running, or a more technical friend handed you a server URL and key, you're done with this step — skip straight to step 3 (Connect). Everything below is only for setting up the Hermes server itself the first time.
You'll need a reachable current Hermes Agent instance with the API server and dashboard enabled. The Relay power-user plugin (step 4) additionally needs Python 3.11+ on the server.
What the app actually needs is three things: the Hermes API server enabled, reachable from your phone, and an API key — the bearer token the app sends to authenticate Chat. Installing Hermes and choosing a provider/model is ordinary Hermes setup, so we defer that to the official docs (Installation, Nous Portal, API Server). The block below is just the app-facing minimum.
If Hermes is already installed and a provider is configured, skip the install and hermes setup --portal lines and run only the .env + hermes gateway part.
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
hermes setup --portal # log in / pick a provider — skip if already configured
# Pick any API_SERVER_KEY you like — you'll scan or type it into the app.
# openssl just generates a strong random one; substitute your own if you prefer.
mkdir -p ~/.hermes
API_SERVER_KEY="$(openssl rand -hex 32)"
cat >> ~/.hermes/.env <<EOF
API_SERVER_ENABLED=true
API_SERVER_HOST=0.0.0.0
API_SERVER_PORT=8642
API_SERVER_KEY=$API_SERVER_KEY
EOF
chmod 600 ~/.hermes/.env
echo "Android API URL: http://<this-computer-ip>:8642"
echo "Android API key: $API_SERVER_KEY"
hermes gatewayiex (irm https://hermes-agent.nousresearch.com/install.ps1)
hermes setup --portal # log in / pick a provider — skip if already configured
# Pick any API key you like — you'll scan or type it into the app.
$HermesDir = Join-Path $HOME ".hermes"
New-Item -ItemType Directory -Force $HermesDir | Out-Null
$ApiKey = ([guid]::NewGuid().ToString("N") + [guid]::NewGuid().ToString("N"))
@"
API_SERVER_ENABLED=true
API_SERVER_HOST=0.0.0.0
API_SERVER_PORT=8642
API_SERVER_KEY=$ApiKey
"@ | Add-Content (Join-Path $HermesDir ".env")
Write-Host "Android API URL: http://<this-computer-ip>:8642"
Write-Host "Android API key: $ApiKey"
hermes gatewayWhat each line does: API_SERVER_ENABLED=true turns the API server on (it's off by default); API_SERVER_HOST=0.0.0.0 makes it reachable on your network (Hermes defaults to 127.0.0.1, which only the host itself can reach); API_SERVER_PORT is the port the app assumes; API_SERVER_KEY is the token the app sends on every request. Replace <this-computer-ip> with the address your phone can reach — a LAN IP, Tailscale name, or HTTPS reverse-proxy host. Don't use 127.0.0.1 from Android unless Hermes is running on the phone itself.
Binding to 0.0.0.0 exposes the API to your whole network
0.0.0.0 lets any device on the same network reach the API server, which is why the bearer key matters. On a home LAN behind a router that's normally fine. On untrusted or public networks, don't expose it directly — keep the key set and front it with Tailscale or an HTTPS reverse proxy (see Remote access). To limit it to a single interface, set API_SERVER_HOST to a specific LAN IP instead of 0.0.0.0.
The key is yours to choose — and you don't have to thumb-type it
Three easy ways to get the key onto your phone (no 64-character typing required):
{"api_url":"http://<this-computer-ip>:8642","api_key":"<your-key>"} — then scan it from Scan setup QR.Optional — only for Manage and voice. Chat works fine without the dashboard. Set it up if you want to browse and install skills, switch models, manage keys, and edit profiles from your phone, or use voice on a vanilla install.
For Manage, run the Hermes dashboard on a phone-reachable URL. Because your phone reaches it on a non-loopback address, the dashboard requires auth — it won't start on 0.0.0.0 without a provider configured — so set credentials first, then start it. On a trusted LAN or VPN, username/password is the quick path:
# Run on the Hermes host. Replace choose-a-strong-password with your own.
DASHBOARD_SECRET="$(openssl rand -base64 32)"
cat >> ~/.hermes/.env <<EOF
HERMES_DASHBOARD_BASIC_AUTH_USERNAME=admin
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD=choose-a-strong-password
HERMES_DASHBOARD_BASIC_AUTH_SECRET=$DASHBOARD_SECRET
EOF
chmod 600 ~/.hermes/.env
hermes dashboard --no-open --host 0.0.0.0 --port 9119# Set the same HERMES_DASHBOARD_* values in $HOME\.hermes\.env (use your own password), then:
hermes dashboard --no-open --host 0.0.0.0 --port 9119You sign in with this username/password from the app's Manage tab the first time. For stronger setups Hermes also accepts a hashed password (HERMES_DASHBOARD_BASIC_AUTH_PASSWORD_HASH) instead of plaintext, and for a public or hosted dashboard you should use Nous OAuth or self-hosted OIDC rather than a password — see the upstream Web Dashboard docs. On the host's own loopback the dashboard runs without auth; the credentials above are needed only because your phone connects over the network. (The dashboard also reads and writes ~/.hermes/.env, which holds your keys and secrets.)
Dashboard auth and API bearer auth are different
The API key from the previous step is for Android Chat on :8642. Dashboard sign-in on :9119 uses dashboard cookies plus short-lived /api/ws tickets. Android supports dashboard username/password and Nous/OIDC sign-in for Manage, but dashboard login does not create an API key.
On first launch:
http://192.168.1.100:8642) and key by hand.{"api_url":"http://192.168.1.100:8642","api_key":"<your-key>","dashboard_url":"http://192.168.1.100:9119"} is accepted. dashboard_url is optional when the dashboard uses the conventional same-host :9119 URL.https://your-host.ts.net:8642 in the Remote access field.That's it — Chat is live, and the Manage surfaces (Skills, Cron, MCP, Profiles, Models/Config) light up too. Manage may ask you to sign in to the dashboard the first time; that same sign-in also unlocks voice for the connection. Relay pairing is not required for any of this.
Home and away on one connection
Save both a LAN URL and a Tailscale URL and Android probes them on every connect, using the highest-priority reachable one. Chat and Manage move together — LAN at home, Tailscale when you leave.
The documentation uses deterministic renders from the real Android components, so these screens update with the canonical screenshot set instead of drifting like a hand-recorded demo.


The chat header shows the agent name with a green pulse on the avatar when the API server is reachable. If the dot is red:
hermes gateway)API_SERVER_ENABLED=true?:8642)More: Troubleshooting · Chat guide · Connections.
Skip this unless you want Terminal, Bridge device control, Relay sessions, channel grants, or relay-backed device-control features. Chat, voice, and Manage all work without it.
On the Hermes host:
hermes plugins install Codename-11/hermes-relay/plugin --enable
hermes relay doctor
hermes relay start --no-ssl
hermes pairhermes pair is provided by the Hermes-Relay plugin through upstream Hermes' plugin CLI support; it is not a built-in Hermes core command. Then scan the QR in Android from Settings → Connections → Pair Relay, or from onboarding's Scan setup QR path. If the relay isn't running, the plugin can still print an API-only QR, so Chat works and Relay can be paired later. The QR may include dashboard_url for custom dashboard/reverse-proxy layouts; otherwise Android derives the dashboard from the API host on port 9119.
Use the legacy installer only when you also want the systemd user service, shell shims, external skill-path registration, and the old clone/update workflow:
curl -fsSL https://raw.githubusercontent.com/Codename-11/hermes-relay/main/install.sh | bashThe optional compatibility monkeypatch is separate from normal Relay pairing. Modern Vanilla Hermes chat, Manage, and dashboard voice do not need it. Check it with hermes relay compat status; install it only for older Hermes builds or compatibility-only route gaps:
hermes relay compat status
hermes relay compat install
hermes relay compat removeStart the relay
# If you installed the hermes-relay plugin (recommended):
hermes relay start --no-ssl
# Or directly from a repo checkout:
python -m plugin.relay --no-sslRun this on the same machine as hermes-agent. On current upstream Hermes installs with the plugin enabled, the plugin-provided hermes pair is available — when the relay is running, its URL and a fresh pairing code are embedded in the QR automatically.
For persistent deployment, Docker, systemd, and TLS options, see the Relay Server docs.
If you only saw an API-only QR earlier (because the relay wasn't running), just start the relay and re-run hermes pair — the new QR will include the relay block.
Multiple Hermes servers
The app can save more than one Hermes server, such as Home and Work. Add or switch servers later in Settings → Connections.
Hermes-Relay supports multi-endpoint pairing: one QR carries every network path your server is reachable on, and the phone auto-picks whichever is reachable at the moment — LAN, cell, tailnet, or public reverse proxy — without re-pairing when you change networks.
--mode auto. hermes pair --mode auto (on the server) probes the LAN, detects Tailscale if it's running, and emits an ordered candidate list in the QR. Add --public-url https://hermes.example.com to include an external reverse-proxy or Cloudflare Tunnel URL.hermes-relay-tailscale enable — this fronts the loopback relay port 8767 and Hermes API port 8642 with tailscale serve, using Tailscale's managed TLS + tailnet ACLs. (Both ports matter: relay pairing covers terminal/bridge/control; chat and API-key voice use the Hermes API server.) Prefer a reverse proxy + Let's Encrypt or a self-hosted VPN? Both work identically as long as the phone can reach both services.--mode accepts auto, lan, tailscale, or public. --prefer <role> promotes a named role to priority 0 (e.g. --prefer tailscale).For the full matrix (Tailscale, Caddy + Let's Encrypt, Cloudflare Tunnel, self-hosted WireGuard, plaintext over trusted VPN) with working config blocks, see Remote access and the Connections page.
Manage uses the Hermes dashboard/admin server and stores dashboard cookies separately from Relay pairing credentials.
/auth/password-login with the upstream basic provider, stores the dashboard cookies, and checks /api/auth/me./auth/login?provider=... flow in an in-app WebView, imports the resulting cookies, checks /api/auth/me, and probes /api/auth/ws-ticket./api/auth/providers advertises supports_password: true.Relay pairing does not replace dashboard login, and dashboard login does not mint an API key: it matches the Hermes Desktop remote-gateway path by authenticating /api/ws and /api/pty with dashboard cookies plus a single-use ticket from /api/auth/ws-ticket. Android uses that gateway path when it is ready and falls back to API-server SSE when it is not.
During onboarding:
http://192.168.1.100:8642 — scan for Hermes on LAN, or scan a generic QR containing the API URL/key.API_SERVER_KEY if the QR didn't include it.https://your-host.ts.net:8642.After onboarding: open Settings → Connections. Each Hermes host is a card; the active card expands inline to show status rows, route details, and an Advanced section with manual API URL/key config, Relay URL override, insecure-mode toggle, and the manual Relay pairing-code fallback. The per-card Pair Relay / Re-pair button scans a Relay QR when you need power tools.
For Vanilla Hermes setup there is no built-in upstream mobile pairing command yet, so use LAN scan, copy/paste, or a generic QR with the API URL/key. If a QR includes a Relay block, Android shows the Relay pairing confirmation and TTL/grants picker; if it's API-only, Android saves the Vanilla Hermes API/dashboard connection.
If you used the upstream plugin manager:
hermes relay compat remove --all # optional; only removes legacy compat hooks
hermes plugins remove hermes-relayIf you used the legacy installer:
bash ~/.hermes/hermes-relay/uninstall.sh
# or, if the clone is already gone:
curl -fsSL https://raw.githubusercontent.com/Codename-11/hermes-relay/main/uninstall.sh | bashIt removes the legacy systemd service, shell shims, editable package, external skill path, clone, and compat hook. It is idempotent and never touches state shared with other Hermes tools. Flags: --dry-run, --keep-clone, --remove-secret. For agent-assisted cleanup, use the Agent Cleanup Prompt.
[?] Get Help · [!] Found a Bug? · [+] Get Started