r/openwrt • u/TAIPANBOX • 1h ago
Hermes Agent on an OpenWrt router
I maintain hermes-openwrt, which packages the Hermes Agent (open source, from Nous Research) as a native OpenWrt 25.12 service. Version 0.21.5, package 0.21.5-r14, released 2026-10-09. Install steps are in the repo. This post is about what it does and what we measured.
What it is
A Hermes Agent package for OpenWrt 25.12: installs with apk from a signed feed, runs as a service, has a LuCI page. No Docker, no chroot. The agent lives on the router; the model runs with a provider you choose.
What it does
- Diagnoses the network on request in Telegram: ping to the gateway and the internet over IPv4 and IPv6, DNS checks, state of ports and interfaces, errors and losses on them, load and free memory. It answers with what it actually saw and says what it could not check.
- Knows what is on the network: connected clients (DHCP), interface state, Wi-Fi and network setup (passwords and keys hidden), and the router's system log.
- Searches the web and reads pages without a browser and without a separate web API key. It can find a piece of documentation or a new firmware or package version and summarise the key points.
- Runs on a schedule: an hourly network check that stays silent when all is normal and writes once when something is wrong; a morning digest (weather, exchange rate, one news item).
- Runs commands in its own terminal as an unprivileged user: anything that does not need root (ping, traceroute, nslookup, system status).
- Checks that a service it started is really running: it compares against the router's service list instead of trusting its own start command. It reads the settings of installed packages, with secrets hidden.
- Changes router settings (network, Wi-Fi, firewall, port forwarding, DHCP) and manages services only after /unlock. For example, it brings up a guest Wi-Fi isolated from the home network. After a new protocol is installed (AmneziaWG, for example), it can restart the network itself in an unlocked window.
- Installs packages if you enable it in LuCI: it first shows what would be installed, then installs after /unlock. Only by package name and only from the official OpenWrt feed: links, local files, third-party feeds and disabling signature checks are not possible. Tested with AdGuard Home, Tor, Transmission and vnstat: the agent installed and started each of them.
- VPN: sets up WireGuard on the router (interface, peers, addresses, firewall rules) after /unlock, and can install the WireGuard packages itself when package install is enabled. AmneziaWG can also be configured through the chat (interface, peer, obfuscation parameters), but its packages must be installed by hand: they are not in the official feed. Private keys are generated on the router with one command, so they never reach the model provider. The agent checks whether the tunnel is up.
- Helps with the rest: OpenVPN, SQM, setting up AdGuard Home, Transmission, Tor and so on. It finds the current instructions for your OpenWrt version, checks them against what is really on the router, and writes the steps.
- Remembers context between conversations, uses Hermes's built-in skills, and writes new skills itself after successful tasks.
- Models: any provider with an OpenAI-compatible API, such as OpenAI, Anthropic (Claude, directly with your key), Google Gemini, OpenRouter, a ChatGPT subscription, or your own model server on the LAN. Several providers can be set up at once, and /model switches the model in a chat.
- LuCI page: agent state, log, keys (write only), security settings.
- USB stick: the agent's data moves to a stick with one command, so it works on routers with little flash. If the stick does not appear right after the packages are installed, wait a few seconds and run block info again.
Which model
You need a current model. On the same routers in our tests: gpt-6.1-sol ran a full diagnosis and configured WireGuard and a guest network correctly; claude-haiku-5.5 runs a full diagnosis with ping too, at about half a cent per conversation; the older gpt-4o-mini looped and advised a reboot. A ChatGPT subscription can be connected with no per-token cost.
Resources
The service uses about 190 MB of RAM. It runs on a 512 MB router (Beryl AX) with the data on a USB stick.
Flash writes (measured on Flint 2 with 1 GB RAM and eMMC 8 GB, 7.3 GB usable, OpenWrt 25.12.5, data in internal flash, 2026-10-09; write counters, temperature, load and memory sampled every 20 seconds over 30-minute windows, projected to a day)
- Agent idle: the whole router writes about 0.5 GB per day. Without the agent: 0.05 to 0.15 GB per day.
- One conversation (diagnosis, device list, firewall check) adds 2.5 to 4 MB. Most of the agent's writes are its journal, service markers and the model catalogue cache.
- Installing a package writes it once.
- eMMC life counter: 0x01, that is 0 to 10 percent of its life used.
Next to other services
We asked the agent through Telegram to install what usually runs on a router, and measured on Flint 2:
- AdGuard Home, vnstat and Tor keep their databases, logs and caches in RAM by default, so eMMC writes stay at background level. AdGuard under 1,160 DNS queries in 10 minutes wrote as much as without it.
- Transmission: Debian (735 MB) downloaded to a USB stick in 6.5 minutes. On eMMC: background writes, CPU at 44 to 45 °C with 0 to 6 percent load, at least 395 MB of memory free, Transmission itself using 15 to 27 MB.
- Tor client: 61 to 66 MB of memory, eMMC at background level.
- AmneziaWG: the Flint 2 to Brume 2 tunnel gave 542 to 599 Mbit/s. The Brume 2 CPU was the bottleneck (94 to 96 percent), the Flint 2 at about a third. During a 4-minute iperf3 run, a Hermes diagnosis ran in parallel: 556 to 563 Mbit/s against 556 to 572 without it, no drop. eMMC unaffected.
- The agent opens no port to the outside; it uses outbound connections to Telegram. No port conflicts with these services.
- The shared resource is RAM: with the agent, AdGuard Home, Transmission and Tor running at once, Flint 2 kept 340 to 420 MB free. A 512 MB router would be tight with all of them.
- Note: after install, the AdGuard Home setup wizard on port 3000 is open to the LAN without a password, and Transmission's RPC accepts control from the LAN without one by default. These are the packages' own defaults, not the agent's. Set passwords right after install.
Release check, 0.21.5-r14 (2026-10-09)
The full scenario: clean install, start, a ping run by the agent, Telegram, allowlist, diagnosis, PIN unlock and rollback of a change. 15 checks per router.
- Brume 2: 15 of 15.
- Beryl AX with an external USB stick: 15 of 15.
- Flint 2: 15 of 15, including a reboot (after the router was recovered). Install onto a USB stick on Flint 2: 6 of 6.
- Beryl AX with 200 MB of free flash: the install stopped at its space check, as designed. We do not force it.
Security
- After install the agent can only read the router. Changes stay blocked until you enable a second factor (PIN, app code or both) on the Security page in LuCI.
- To change something, send /unlock and your PIN in one message in the private chat. The bot deletes that message at once, so the PIN never reaches the model. A window stays open for 15 minutes; /lock closes it earlier.
- In a window the agent may change network, Wi-Fi, firewall, DHCP and system settings, and manage services. It never gets commands as root, firmware flashing, installs from links, settings that run scripts, or its own settings.
- Package install is off by default. When enabled, it works only with official OpenWrt feed packages and only inside an unlock window.
- A change that cuts the connection rolls back by itself after about 90 seconds.
- Wi-Fi keys, WireGuard keys and other secrets are shown to the agent as <redacted>.
- The agent's keys are root-only files. The agent cannot read its own key from files or from its process memory.
- Only Telegram IDs on the allowlist get answers.
- Everything the agent reads (logs, client lists, addresses) goes to the model provider. Choose a provider you trust, or a model on your own server on the LAN.
What it cannot do
- No browser: JavaScript sites, logins and purchases are not for it.
- It does not run the model on the router.
- It does not remove packages and does not install from third-party feeds.
- It does not change the settings of the services themselves (AdGuard Home, Transmission, Tor, Tailscale): it installs and starts them, you configure them.
- It needs clean OpenWrt 25.12 on aarch64. Stock GL.iNet firmware does not qualify.
What you need: at least 512 MB of RAM, about 400 MB of free flash (less is possible with a USB stick), and a provider key or a ChatGPT subscription. Make a backup before installing.
Tested on Flint 2 (GL-MT6000), Brume 2 (GL-MT2500) and Beryl AX (GL-MT3000, with a USB stick). Reports from other aarch64 routers are welcome.
Repository, install guide, measured numbers and the full security model: https://github.com/TAIPANBOX/hermes-openwrt (MIT).