Skip to content

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 claude CLI 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-stack MCP gives it live Loki + Prometheus queries; the ALERTS metric 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 neteng cron 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.