---
name: host-inventory
description: "Capture and persist a host's identity and runtime state (OS, kernel, CPU, RAM, disk, IPs, GPU, listening services, containers, toolchain) into memory and/or hindsight. Load when the user asks for server/host info, a system audit, an environment snapshot, or wants to record 'this machine's setup' for future sessions."
version: 1.0.0
author: Hermes Agent
license: MIT
platforms: [linux, macos, windows]
metadata:
  hermes:
    tags: [sysinfo, inventory, snapshot, audit, devops]
---

# Host Inventory

A repeatable procedure for **capturing a host's identity and runtime state** and **persisting it** so future sessions start already knowing what machine they're on. Loaded when the user asks for "server info", "system snapshot", "host inventory", "这台机器配置", etc.

## When to use

- User asks "查下服务器信息" / "what's this host" / "dump system info"
- Onboarding a new shell/VM/container and wanting to remember it
- Before/after a deployment, to record the delta
- After non-trivial environment changes (kernel upgrade, disk resize, network reconfigure)

## Two-step procedure

1. **Capture** with the bundled script (`scripts/capture.sh`).
2. **Persist** to the right tier:
   - **Built-in memory** — only if the inventory is small enough (<200 chars) AND the user wants it auto-injected every turn. Usually NO — host inventory is bulky and not needed every turn.
   - **Hindsight** — preferred. Call `hindsight_retain(content=<markdown>, context="<server name> snapshot <date>", tags=["host", "inventory", "<os>", "<role>"])`.

## What the script captures (Linux)

| Category | What | Command hint |
|---|---|---|
| Identity | hostname, kernel, OS, arch, uptime | `uname -a`, `/etc/os-release`, `uptime` |
| Hardware | CPU model/cores/threads, RAM, swap, disk | `lscpu`, `free -h`, `df -h /` |
| Network | IPs (private + public v4/v6), default route, DNS | `ip -4 addr`, `ip route`, `cat /etc/resolv.conf` |
| GPU | vendor/model + memory (when present) | `nvidia-smi` or `lspci \| grep -i vga` |
| Containers | docker/podman ps, compose stacks, networks | `docker ps --format` |
| Listeners | every TCP/UDP port bound, with owning PID | `ss -tlnp` / `ss -ulnp` |
| Toolchain | language runtimes + common CLIs | `for c in git curl jq python3 docker; do command -v $c` |
| Cloud | instance ID, region (AWS/GCP/Azure metadata) | `curl -s http://169.254.169.254/...` when reachable |

The bundled script handles all of the above and prints a single Markdown table block plus a JSON blob for `hindsight_retain`.

## Persist call shape (preferred)

```python
hindsight_retain(
    content=<markdown_table+key_facts>,
    context="<hostname> inventory snapshot YYYY-MM-DD",
    tags=["host", "inventory", "<os>", "<role: db|web|dev|proxy>", "<cloud-region>"],
)
```

3–5 semantic tags per entry. If multiple roles are running on the host (e.g. web + db + proxy), include all dominant roles.

## Pitfalls (verified 2026-07-05)

- **`curl ifconfig.me` returns IPv6-only on some hosts** — the "public IP" field may look empty even when egress works fine. Don't retry; record both v4 and v6 with the source that returned them.
- **Docker `compose` is a subcommand, not a binary** — script must use `docker compose …` not `docker-compose …`. Recent installs (Docker 29.x) only ship the plugin.
- **`ss -tlnp` shows `[::]:443` for dual-stack listeners** — record "v4+v6" not just v6.
- **`/proc/cpuinfo` or `lscpu` may report logical vs physical differently** — capture both `CPU(s):` and `Core(s) per socket:` to disambiguate.
- **Don't include `/proc/<pid>/cmdline` output verbatim** — it leaks env-vars/secrets. Mask them.
- **GPU section is optional**: only run if `nvidia-smi` exists, or `lspci | grep -i vga` returns anything. On headless VMs the GPU block is empty — that's correct, don't fabricate one.
- **Network section includes docker bridges** (172.17/172.18 by default) — these are container plumbing, not real interfaces. Label them clearly.
- **Built-in memory `memory_char_limit` is configurable** (`hermes config set memory.memory_char_limit <N>`) but the full inventory almost always exceeds it. Default to hindsight; only fall back to built-in when the user explicitly asks for "always remember this server" injection.
## Related

- `hermes-memory-strategy` — two-tier persistence rules and pitfalls. **Load before persisting.**
- `terminal` background-mode hard constraints — capture script is foreground-only; safe to run interactively.
