Jarvis (Hermes Agent)¶
Jarvis is the homelab's autonomous AI assistant — the Nous Research Hermes Agent running on its own dedicated VM so it can be isolated (or killed) instantly.
| Host | VM 121 hermes-jarvis on pve1 — 192.168.1.252 |
| Install | Bare-metal, systemd services hermes-gateway + hermes-dashboard (non-root jarvis user) |
| Web UI | jarvis.mdhmedia.uk — built-in Hermes dashboard (:9119), behind tinyauth SSO (Google login) |
| Messaging | Telegram bot (outbound polling, allowlisted users only) |
| Models | Nous Portal (default) + Anthropic API key; optional claude CLI on the VM |
| Profiles | default (general) + neteng (network engineer — see below) |
| Repo | hermes-vm/agent/ — setup script, config templates, full README; hermes-vm/agent/profiles/neteng/ — the network-engineer profile |
Why a dedicated VM¶
The agent runs shell commands as part of its job, so the VM boundary is the sandbox — not a container. Containerizing an infra-ops agent forces a docker-socket mount or SSH-back-to-host, which is host-root with extra steps.
ssh root@192.168.1.199 "qm stop 121" # pull the plug — severs everything
ssh root@192.168.1.199 "qm start 121" # self-resumes via systemd
Backups
All agent state (config, memories, skills, session history) lives in
/home/jarvis/.hermes. VM 121 is backed up by a weekly pve1 vzdump job
(Sun 02:00, keep 2), which then mirrors offsite via pve-offsite-sync.
Security posture¶
- Command approval
manual(never YOLO mode); Telegram allowlist, deny-by-default gateway auth; SSRF protection on. - Hardened systemd unit:
NoNewPrivileges,ProtectSystem=strict,PrivateTmp. - Docker on the VM is for auxiliary containers only (Portainer Agent — environment "jarvis" in Portainer BE — and the future Matrix rebuild). The agent never gets the docker socket.
- Claude subscription use is confined to the official
claudeCLI on the VM (Anthropic ToS bans subscription OAuth in third-party apps; the Hermes provider uses a normal API key instead).
The neteng profile — homelab network engineer¶
Jarvis runs a version-controlled profile, neteng, that acts as the homelab's
always-on network/SRE engineer. It is the built-out version of the old Phase-4 roadmap.
- Taught the homelab. A knowledge pack (
HOMELAB.md) — topology, host inventory, Loki/PromQL cookbooks, deployment model, quirks — is seeded into the profile's memory, so it reasons from an accurate map of the network. - Monitors. The
grafana-stackMCP gives it live Loki + Prometheus queries; theALERTSmetric is its source of truth for what is firing. - Fixes within a tight scope. Its one write capability is restarting existing containers through a scoped, revocable Portainer token. Everything structural (Caddy, Proxmox, DNS, data) is proposed via Telegram and routed through the GitOps repo.
- Keeps the pane of glass honest. It annotates Grafana for every incident and action; the "Jarvis Ops" dashboard renders those as an incident timeline.
- Alerts two ways. A Grafana-native Telegram contact point fires straight from
Grafana (independent of the agent — the dumb-pipe safety net), while
netengcron jobs (30-min health sweep, daily digest, weekly review) add triage and improvement suggestions on top.
Source and deploy script live in hermes-vm/agent/profiles/neteng/. See
hermes-vm/agent/README.md for the full write-up.