How-To Guide
How to Open and Secure the Hermes Agent Dashboard
Open Hermes Web UI on port 9119, keep it running with systemd on Linux, secure remote access, use browser Chat, and verify channels and cron jobs end to end.
Quick answer
Run hermes doctor && hermes dashboard, then open http://127.0.0.1:9119. Use hermes dashboard for backend plus Web UI and hermes serve for a headless remote-Desktop backend. On Linux, keep the chosen process alive with a systemd user service under the same Hermes account, enable lingering for boot startup, and keep the messaging gateway separate. Prefer loopback plus SSH/VPN; a non-loopback bind requires authentication.
This guide covers the complete dashboard path: local launch, optional web/PTY dependencies, machine-level profile switching, private VPS access, fail-closed authentication for public binds, browser Chat, process controls, and an end-to-end delivery test. Use FlyHermes instead when the real requirement is managed browser/mobile access and channel uptime rather than self-hosted administration.
Managed cloud · API costs included · Skill library · Cancel anytime
Before you start:
- ☑Hermes Agent installed
- ☑hermes setup completed and hermes doctor passing
- ☑A modern web browser
- ☑Hermes v0.16 or newer if you want the latest desktop, dashboard/admin, remote backend, auth, MCP/channel, and browser Chat surface behavior
Steps
- 1
Verify Hermes before opening Web UI
Run
hermes doctorandhermes chat -q "reply ok". Fix provider, config, PATH, or dependency errors before treating the dashboard as the problem. - 2
Start the local dashboard
Run
hermes dashboardand openhttp://127.0.0.1:9119. Usehermes dashboard --port 9120if 9119 is occupied. - 3
Choose dashboard or headless serve
Run
hermes dashboardwhen you need the browser admin UI. Runhermes servewhen Hermes Desktop only needs a headless remote backend. Pick one per port. Telegram, Discord, and other channels use the separate gateway service. - 4
Keep Web UI running with systemd on Linux
Use the copy-paste user unit in the Hermes dashboard and Web UI runbook. Run it as the same account that owns
HERMES_HOMEand can rundocker ps; load%h/.hermes/.envand preserve the working PATH instead of running Hermes as root. - 5
Enable boot startup and verify the service
Run
systemctl --user daemon-reload && systemctl --user enable --now hermes-dashboard.service. If it must start before login, runsudo loginctl enable-linger "$USER". Checksystemctl --user status, the user journal, andhttp://127.0.0.1:9119/api/statusbefore testing a real channel delivery. - 6
Install optional dashboard dependencies if prompted
From a source checkout run
cd ~/.hermes/hermes-agent && uv pip install -e ".[web,pty]". The web extra provides the server; PTY support powers browser Chat. - 7
Choose the correct profile
Use the sidebar profile switcher before editing Config, API Keys, Skills, MCP, Models, or Chat. Gateway services remain profile-specific and must be checked separately.
- 8
Confirm which Windows or WSL runtime owns the dashboard
Native Windows and WSL keep separate Hermes homes. If sessions, provider settings, or profiles look wrong, check which environment started port 9119 and run
hermes config pathin both before editing or copying state. - 9
Use Web UI to separate a Desktop failure from a backend failure
If Hermes Desktop will not open after an update, try the CLI smoke test and local dashboard. A working dashboard means the runtime and profile data are available; repair the native client or stale updater process without deleting memory, sessions, or skills.
- 10
Use a private path for VPS access
Keep the dashboard bound to loopback and tunnel it with
ssh -L 9119:localhost:9119 user@your-vps, or use a trusted VPN. - 11
Configure auth before any non-loopback bind
Set up Basic Auth, Nous OAuth via
hermes dashboard register, or OIDC before binding to a reachable interface. Current Hermes fails closed without an auth provider;--insecureis a deprecated no-op. - 12
Configure a Cloudflare Tunnel or reverse proxy safely
For a public hostname, prefer Nous OAuth or OIDC, set
HERMES_DASHBOARD_PUBLIC_URL=https://dashboard.example.com, runhermes dashboard --host 0.0.0.0 --port 9119 --no-open, and point the tunnel tohttp://127.0.0.1:9119. Confirm/api/statusreportsauth_required: truebefore logging in. Port 8642 is the optional OpenAI-compatible API server, not Web UI. - 13
Inspect the control plane in order
Check Status, selected profile, Sessions, Analytics, Logs, Cron Jobs, Skills, MCP, Config, Models, and Gateway state before rotating keys or rebuilding the server.
- 14
Use browser Chat inside the trusted boundary
The Chat tab runs the real Hermes TUI over an authenticated PTY/WebSocket. Resume sessions there, but keep it private like the rest of the admin surface.
- 15
Prove the actual workflow
Send one browser Chat response, Telegram/Discord message, or cron delivery to the exact destination. Record that result as success; a green dashboard is only a checkpoint.
Pro Tips
- 💡Use
hermes dashboard --statusbefore starting another server andhermes dashboard --stopbefore changing bind or auth settings. - 💡Use
--skip-buildonly when the frontend is already built and npm is unavailable in the current environment. - 💡Use
--isolatedonly for a deliberate dedicated per-profile server; the normal dashboard is machine-level. - 💡A non-default port is not a security control.
- 💡Prefer SSH tunneling or VPN access to a public bind.
- 💡
--insecureno longer disables authentication and should not appear in new deployment instructions. - 💡Gateway processes remain profile-specific even when the dashboard profile switcher looks correct.
- 💡Use Logs and Sessions together to understand failed cron or channel runs.
- 💡Use Analytics before blaming model cost; it shows calls, tokens, and model usage.
- 💡Choose FlyHermes when managed browser/mobile access and uptime matter more than owning the server.
- 💡Do not create one dashboard port per profile. One machine-level dashboard on 9119 switches across co-located profiles; only separately exposed OpenAI-compatible API servers need distinct per-profile ports.
- 💡A Cloudflare Tunnel supplies HTTPS transport and routing, not Hermes authentication. Keep OAuth/OIDC enabled and verify the auth gate before sharing the hostname.
- 💡Use one process per backend port: dashboard for browser UI, serve for headless Desktop access, and gateway for messaging delivery.
- 💡If Docker works interactively but not under systemd, compare the service user, supplementary groups,
HERMES_HOME, PATH, Docker socket, andDOCKER_HOST.
Troubleshooting
❌ Dashboard or Web UI returns 'connection refused' when opening in browser
✅ Start the dashboard with hermes dashboard and check the selected port. If you chose port 9120, open http://127.0.0.1:9120. Verify nothing else is using the port with lsof -i :9120.
❌ Web UI frontend not built and npm is not available
✅ Hermes may be running with a reduced PATH. Check which node and which npm in your shell, then build once manually: cd ~/.hermes/hermes-agent/web && npm install && npm run build. Relaunch hermes dashboard after web_dist exists.
❌ Built dashboard assets exist but Hermes still cannot find them
✅ Point Hermes directly at the built frontend: HERMES_WEB_DIST=$HOME/.hermes/hermes-agent/hermes_cli/web_dist hermes dashboard --port 9120 --no-open.
❌ Dashboard is exposed on a public VPS
✅ Move it back to loopback plus SSH/VPN, or configure Basic Auth, Nous OAuth, or OIDC with HTTPS and firewall rules. Current Hermes fails closed on non-loopback binds without an auth provider.
❌ Browser Chat tab is missing from WebUI
✅ Confirm that the dashboard web and PTY dependencies are installed, then restart hermes dashboard. The Chat tab is a local PTY-backed TUI surface; on native Windows use WSL2 for the PTY requirement.
❌ Dashboard command works but browser cannot reach it
✅ Confirm the actual port, host binding, firewall, SSH tunnel, and whether you ran with --no-open on a server. For local use, start with the default localhost:9119 before exposing anything.
❌ Dashboard loads but Telegram or Discord is still silent
✅ Use Web UI as a checkpoint only. Then run hermes gateway status, inspect agent/errors logs, verify the active profile and allowed chat/thread IDs, and send one real message in the exact target channel.
❌ Dashboard launches but the team still cannot use Hermes remotely
✅ The self-hosted dashboard is an admin panel for your runtime; it does not magically provide managed uptime, secure public access, or channel delivery. Use FlyHermes when the requirement is hosted browser/mobile access and connected channels.
❌ Dashboard says a gateway is connected but Telegram or Discord does not reply
✅ Use the dashboard/logs to inspect state, then run an end-to-end send/reply test in the exact chat/topic. Process health and channel delivery are separate checks.
❌ Dashboard edits the wrong profile
✅ Check the profile switcher and URL ?profile=<name> before changing Config, API Keys, Skills, MCP, or Models. For scripts and services, use explicit hermes -p <name> ... commands.
❌ Dashboard profile switcher looks right but gateway state still differs
✅ Gateway processes remain profile-specific services. Run hermes -p <name> gateway status for the profile that owns the bot/channel and then send a real test message.
❌ `--insecure` no longer opens the dashboard
✅ --insecure is deprecated and a no-op. Configure Basic Auth, Nous OAuth, or OIDC for a non-loopback bind, or keep the server on 127.0.0.1 and use a tunnel.
❌ Cloudflare Tunnel opens the wrong Hermes port or OAuth keeps redirecting
✅ Route the public hostname to dashboard port 9119, not API port 8642. Set HERMES_DASHBOARD_PUBLIC_URL to the exact HTTPS hostname, confirm the dashboard runs with a non-loopback bind and an OAuth/OIDC provider, then inspect /api/status for auth_required: true and the expected provider.
❌ Dashboard works in a shell but fails under systemd or loses Docker access
✅ Run the user unit as the same Hermes account, verify docker ps first, load %h/.hermes/.env, preserve PATH, and compare the Docker socket or DOCKER_HOST. Enable lingering only after the service works; do not switch to root as a shortcut.
❌ WSL dashboard opens but shows the wrong profile or different sessions
✅ Native Windows and WSL are separate Hermes installations. Identify which process owns port 9119, compare hermes config path in each environment, stop the unintended dashboard, and relaunch from the runtime whose profile you want to manage.
❌ Hermes Desktop stopped opening after an update but Web UI still works
✅ Treat this as a client/update problem, not lost agent state. Back up the profile, stop stale Desktop or gateway child processes, verify CLI and Web UI, then rerun the supported update or rebuild path. Do not delete sessions, memory, or skills.
❌ Remote backend test passes but Desktop Chat disconnects
✅ The status probe can pass while authentication or the WebSocket fails. Confirm the exact port 9119 URL, sign in again, compare the selected profile in Web UI, and verify that Desktop is not pointed at the separate port 8642 API server.
FAQ
What command opens the Hermes dashboard?
Run hermes dashboard. It opens on http://127.0.0.1:9119 by default.
How do I use a different dashboard port?
Run hermes dashboard --port 9120 or another free port. Use --no-open on a headless server.
Can one dashboard manage multiple profiles?
Yes. Use the profile switcher for Config, API Keys, Skills, MCP, Models, and Chat. Gateways remain separately managed per profile.
Does `--insecure` bypass authentication?
No. It is deprecated and a no-op. Every non-loopback bind requires a configured password or OAuth provider.
How should I access Web UI on a VPS?
Prefer a loopback bind with an SSH tunnel or VPN. If a public bind is required, add an auth provider, HTTPS, and firewall restrictions.
How do I configure Nous OAuth for the dashboard?
Run hermes dashboard register, then use the saved OAuth client configuration with the dashboard login gate.
What does the browser Chat tab run?
It runs the real Hermes TUI behind an authenticated PTY/WebSocket. The web and PTY extras are required; native Windows users should use WSL2 for Chat.
How do I stop a running dashboard?
Use hermes dashboard --status to list dashboard processes and hermes dashboard --stop to stop them.
Why can Telegram or Discord fail while Web UI looks healthy?
Channel delivery also depends on the correct profile, gateway service, platform permissions, allowlists, routing, and provider credits. Test the exact destination.
When should I use FlyHermes instead?
Use FlyHermes when you want managed browser/mobile access, connected channels, and uptime without maintaining dashboard authentication, VPS processes, providers, and gateways.
Does each Hermes profile need its own dashboard port?
No. The normal machine-level dashboard serves co-located profiles through its profile switcher. Per-profile API servers are separate and need distinct ports only when you expose them to OpenAI-compatible clients.
Can I use Cloudflare Tunnel for Hermes Web UI?
Yes. Route the tunnel to port 9119, use Nous OAuth or OIDC for an internet-facing hostname, set HERMES_DASHBOARD_PUBLIC_URL to the exact HTTPS URL, and verify the dashboard auth gate is active. The tunnel does not replace authentication.
Should I run both hermes serve and hermes dashboard?
Usually no. The dashboard runs the backend plus browser UI; serve runs the headless backend for remote clients. Pick one per port. Run the messaging gateway separately if Telegram, Discord, or other channels must stay connected.
Related setup and cost guides
Hermes WebUI / dashboard overview
Copy-paste Linux systemd unit, command map, dashboard boundary, and mission-control checklist.
FlyHermes pricing for managed dashboards
Compare managed FlyHermes with the server, provider, gateway, and incident-response work of self-hosting.
VPS deployment trade-offs
Deploy an always-on runtime and verify services after reboot.
secure your Hermes server
Protect dashboard auth, SSH, secrets, network access, and dangerous tools.
Telegram agent setup
Connect a Telegram bot and prove one real reply after the gateway starts.