Only the changes worth mentioning.
A single Go binary that remembers what your server looked like last time,
and tells you β or an agent β what moved.
Section rules, labels, and severities are colour-coded in a terminal. Colour is dropped automatically when output is piped, redirected, or run from cron.
That is the whole idea. Most homelab tools show you a graph of right now, and leave "does this matter?" to you. HomeButler remembers what your server looked like last time, decides what is worth saying, and says it β six containers before and six after is not "no change" when one of them is a different container.
Every line is three columns: what kind of change, what it happened to, and
what exactly happened. The kind is one of eight words, and it is the same word in
--json, so an agent branches on it without reading prose:
| Kind | Means | You would see it after |
|---|---|---|
gone |
it was there last time and is not now | docker rm, a service stopping, a port closing |
new |
it was not there last time and is now | starting anything |
replaced |
same name, different thing underneath | docker compose up -d β the container is recreated, so the name and the count are unchanged |
image |
same container, different image | pulling a new tag |
state |
same container, running where it was stopped, or the reverse | a crash, or bringing something back up |
port |
same port, a different process answering on it | one service taking over another's port |
disk |
a mount moved by more than half a gigabyte | anything that writes |
skipped |
the comparison could not be made | Docker was down when either snapshot was taken |
replaced is the one the rest of this exists for. A container recreated under the
same name leaves every count identical, which is why a report that compares counts β
as this one did before 0.26.0 β answers "no significant changes" while the thing you
were running has been swapped out underneath you.
skipped is the second: homebutler says it could not compare rather than reporting
nothing changed. An all-clear it cannot stand behind is worse than no answer.
The header names the snapshot being compared against, so "what changed" is never ambiguous about the window it covers.
π What earns a line, and what is deliberately suppressed β
HomeButler helps you answer the boring but painful questions every homelab eventually creates:
- What is running on my server right now?
- Which container owns this port?
- Why did this service restart at 3 AM?
- Is my backup actually restorable?
- Can I install this self-hosted app without hand-writing another compose file?
- Can I let an AI assistant inspect my server without handing it a full SSH shell?
No daemon required. No database. No always-on web service. Just one Go binary you can use from the terminal, scripts, a web dashboard, or AI tools.
The design goal is simple: give humans and agents a narrow, structured interface to the server. HomeButler returns readable summaries and JSON instead of asking you to trust a black-box shell session.
# One-line install (auto-detects OS/arch)
curl -fsSL https://raw.githubusercontent.com/Higangssh/homebutler/main/install.sh | sh
# Or via Homebrew
brew install Higangssh/homebutler/homebutler
# Interactive setup β add your servers in seconds
homebutler initUse it right away:
homebutler status # CPU, memory, disk, uptime
homebutler docker list # running containers
homebutler inventory scan # containers + ports + topology
homebutler report # butler-style health report + change summary
homebutler install uptime-kuma # deploy a self-hosted app
homebutler backup drill uptime-kuma # verify a backup actually restores
homebutler watch tui # terminal dashboard
homebutler serve # web dashboard at http://localhost:8080Machine-readable output is available everywhere:
homebutler status --json
homebutler inventory scan --json
homebutler report --json- Install apps β deploy Uptime Kuma, Jellyfin, Pi-hole, Gitea, Portainer, and more with one command
- Map your server β see containers, exposed ports, system ports, and service topology
- Run a doctor check β diagnose resource pressure, stopped containers, public ports, backup hygiene, notifications, report baseline readiness, and configured Proxmox endpoint reachability
- Catch crashes β save logs before/after Docker, systemd, or PM2 restarts and detect flapping loops
- Verify backups β boot backups in isolated containers before you trust them
- See a Proxmox cluster β nodes, QEMU and LXC guests, storage, and task status, with power actions that name their target explicitly
- Use it anywhere β CLI, JSON, web dashboard, or MCP for AI agents without giving them SSH
Self-hosting is not hard because one docker compose up is hard. It is hard because the maintenance never ends: ports collide, containers restart silently, backups look fine until restore day, and every server becomes a slightly different snowflake.
HomeButler is a small operations toolkit for that messy middle.
Those are great dashboards. HomeButler is CLI-first, scriptable, JSON-friendly, air-gap friendly, and safe to copy onto any server. Use it when you want commands you can run from a terminal, cron job, SSH session, CI script, or AI agent β especially when you care more about βwhat changed?β than another graph.
homebutler report
homebutler report --keep 7 # retain only the latest 7 snapshots
homebutler report --no-save # preview without writing a snapshotreport gives you a concise butler-style summary of your homelab: current health, warnings, notable changes since the previous snapshot, and suggested next commands. On the first run, HomeButler creates a baseline under ~/.homebutler/reports/snapshots/; later runs compare against the latest snapshot. Old snapshots are pruned automatically (--keep 30 by default) so reports do not grow forever.
homebutler doctor
homebutler doctor --strict # non-zero exit if warnings/failures are found
homebutler doctor --json # automation / MCP friendlydoctor is a read-only preflight for the problems homelab users usually discover too late: high disk or memory usage, stopped containers, public bind ports, stale or missing backups, missing notifications, whether report has a baseline for change detection, and whether each configured Proxmox endpoint is reachable with the token it has. Every finding names the next command to run, so --strict makes it usable from cron or CI β including a Proxmox host that is unreachable or rebooting.
homebutler config validate
homebutler config validate --strict # exit non-zero on warnings too
homebutler config validate --jsonconfig validate reads your config without starting anything and tells you
which file was used, which of the four resolution rules picked it, and what
homebutler actually made of each section. It exists because the two ways config
goes wrong are both silent: a key homebutler does not recognise is dropped
without a word, and a --config path that does not exist falls back to
built-in defaults rather than failing.
Sections
β servers 2 servers (homelab, nas)
Β· notify not set
β alerts cpu 95% Β· memory 85% Β· disk 90%
Findings
β οΈ Line 5: field notifiy not found in the homebutler config
β Did you mean "notify"? Unrecognised keys are ignored silently.
homebutler install uptime-kumaβ Deploy self-hosted apps in seconds. Pre-checks Docker, ports, and duplicates. Generatesdocker-compose.ymlautomatically. See all available apps β
homebutler inventory scan
homebutler inventory show --filter exposed
homebutler inventory export --format mermaid
homebutler --json inventory scaninventory scan gives you a quick map of what is running on a server: system health, Docker containers, app ports, and system ports. Docker-published ports are connected back to the container that owns them, so local forwarding details like Colima/Lima stay understandable.
π Home Network
Server homelab (192.168.1.10)
Summary β
1 running Β· βͺ 1 stopped Β· π 2 public ports Β· π 4 local ports
π¦ Containers (2)
ββ βͺ vaultwarden Β· not started
β ββ image vaultwarden/server:latest
ββ β
api-server Β· running
ββ image my-api:latest
ββ exposes :8080 β 8080/tcp
π App Ports (1)
ββ π :8080/tcp Β· api-server
To answer "what is reachable from outside my machine/network?" without reading the whole tree, filter the scan to exposed ports only:
homebutler inventory scan --filter exposedπ Home Network
Server homelab
π Exposed Ports
ββ :8080/tcp Β· api-server
ββ :8443/tcp Β· dashboard
Only ports listening on all interfaces (0.0.0.0, ::, *) are shown. Anything bound to a specific address is hidden, including loopback and LAN addresses. Unsupported filter values return an error, as does combining --filter with --json; the default inventory scan output is unchanged.
Use Mermaid export when you want a diagram for GitHub, Obsidian, docs, or an AI assistant:
graph TD
home["π Home Network"] --> homelab["π₯ homelab<br/>192.168.1.10"]
homelab --> c1["π¦ api-server<br/>running"]
homelab --> p1["π :8080/tcp<br/>api-server"]
c1 -. exposes .-> p1
homebutler serveβ A real-time web dashboard embedded in the single binary viago:embed. Monitor all your servers, Docker containers, open ports, alerts, and Wake-on-LAN devices from any browser. Dark theme, auto-refresh every 5 seconds, fully responsive.
β¨ Web Dashboard Highlights
- Server Overview β See all servers at a glance with color-coded status (green = online, red = offline)
- System Metrics β CPU, memory, disk usage with progress bars and color thresholds
- Docker Containers β Running/stopped status with friendly labels ("Running Β· 4d", "Stopped Β· 6h ago")
- Top Processes β Top processes sorted by CPU/memory with zombie detection
- Resource Warnings β Visual CPU, memory, and disk thresholds in the dashboard
- Network Ports β Open ports with process names and bind addresses
- Wake-on-LAN β One-click wake buttons for configured devices
- Server Switching β Dropdown to switch between local and remote servers
- Zero dependencies β No Node.js runtime needed. Frontend is compiled into the Go binary at build time
homebutler serve # Start on port 8080
homebutler serve --port 3000 # Custom port
homebutler serve --demo # Demo mode with realistic sample dataYour container crashed at 3 AM β but why? homebutler watch catches it the moment it happens, saves the dying logs, figures out the cause, and tells you if it's happening over and over.
Supported backends: Docker (real-time event stream) Β· systemd (polling) Β· PM2 (polling)
homebutler watch add nginx # Interactive: choose Docker / systemd / PM2
homebutler watch add --kind docker nginx # or specify directly
homebutler watch add --kind systemd nginx.service
homebutler watch add --kind pm2 my-api
homebutler watch list # See what you're watchinghomebutler watch start # Foreground, Ctrl+C to stop
homebutler watch start --interval 10s # Custom poll interval (default 30s)homebutler watch install # register it with systemd or launchd
homebutler watch installed # is it registered?
homebutler watch uninstallwatch install hands the loop to whatever supervises the host β a systemd user
unit on Linux, a launchd agent on macOS β so monitoring survives logout and
reboot. Both are user-level and neither is a preference: on Linux the watch list
lives in your home directory, so a root unit would find an empty list; on macOS
Docker Desktop only runs inside a logged-in session, so a LaunchDaemon would
poll a daemon that is not there. On Linux a user unit stops at logout unless you
run sudo loginctl enable-linger $USER, which watch install tells you.
watch start is the monitoring process. It watches the containers and services
on the watch list for restarts, checks CPU, memory and disk against your
thresholds, and runs any remediation rules you have configured β one process,
one set of notification providers. alerts --watch still exists and does the
threshold half on its own.
When a crash is detected, you'll see:
[03:14:22] INCIDENT: nginx (incident nginx-20260410-031422.581-7a2124)
Crash: OOM β process killed by SIGKILL (oom, confidence: high)
β FLAPPING: acute (3 restarts in short window)
homebutler watch history # List all incidents
homebutler watch show <incident-id> # Full detailswatch show output includes:
- Pre-death logs β what the process printed right before it died
- Post-restart logs β what happened after the restart
- Crash analysis β category (oom / panic / segfault / timeout / dependency / error), reason, confidence level, matched log patterns
- Flapping status β if the process is stuck in a crash loop
Every incident is automatically analyzed using exit codes and log patterns:
| Signal | Exit Code | Meaning |
|---|---|---|
| SIGKILL | 137 | OOM Killer or forced kill |
| SIGSEGV | 139 | Segmentation fault (memory corruption) |
| SIGTERM | 143 | Graceful shutdown request |
| β | 1 | Application error |
| β | 0 | Clean exit (may be intentional restart) |
Log patterns like panic:, Out of memory, Connection refused, FATAL, and timeout are matched automatically to help identify the root cause.
Detects when a process is stuck in a restart loop (e.g., crash β restart β crash again):
- Acute β 3+ restarts within 10 minutes (something is broken right now)
- Chronic β 5+ restarts within 24 hours (slow recurring issue)
Flapping incidents are tagged [FLAPPING] in history and highlighted in watch show.
Notifications are disabled by default, which is useful for air-gapped or closed networks where everything runs locally.
A minimal example in ~/.config/homebutler/config.yaml:
notify:
telegram:
bot_token: "your-bot-token"
chat_id: "your-chat-id"
watch:
enabled: true
notify_on: flapping
cooldown: 5m
flapping:
short_window: 10m
short_threshold: 3
long_window: 24h
long_threshold: 5
retention:
max_incidents: 200
alerts:
cpu: 90
memory: 85
disk: 90
rules:
- name: cpu-spike
metric: cpu
threshold: 90
action: notify
- name: elsa-monitor-down
metric: container
kind: systemd # docker (default) | systemd | pm2
watch: [lh-elsa-monitor.service]
action: restartaction: restart restarts Docker containers unless the rule says otherwise.
kind: systemd or kind: pm2 points it at a service or a PM2 app instead.
The kind is written on the rule rather than looked up from the watch list, so
restarting a host service is something you asked for in the config. It also
means every rule written before kind existed keeps meaning exactly what it
meant.
Two things worth knowing before using it:
systemctl restart needs root or a polkit rule. Running homebutler
unprivileged, a systemd restart will be refused, reported as failed, and
warned about when alerts --watch starts rather than when the rule first
fires.
A target that is flapping is not restarted. Restarting something already
in a restart loop feeds the loop, and most systemd units carry
Restart=always, so homebutler restarting them fights systemd's own backoff.
The thresholds are the watch.flapping ones above, and the skip is reported
rather than counted as either success or failure. This applies to Docker
targets too.
Legacy ~/.homebutler/watch/config.json is still read as a fallback for watch-specific settings, and legacy alerts.yaml notify/webhook provider settings are still accepted for older setups.
-
watch.enabled: trueβ allow watch notifications -
watch.notify_on: flappingβ notify only when repeated restart loops are detected -
watch.notify_on: incidentβ notify on every incident -
watch.notify_on: allβ notify on both incidents and flapping -
watch.notify_on: offβ disable watch notifications without removing provider config -
watch.cooldown: 5mβ suppress duplicate notifications for the same event fingerprint during the cooldown window -
watch.flappingβ optional advanced tuning for restart-loop detection -
watch.retention.max_incidents: 200β how many incidents to keep on disk, newest first. The directory grows fastest exactly when a service is restarting in a loop. Set-1to keep everything.Each incident keeps up to 100 captured log lines per side, and at most 64 KB of them. Line counts alone do not bound a file: one stack trace or JSON document on a single line is arbitrarily long, and a container being OOM-killed is exactly the one likely to write one. A log that does not fit keeps its end β the last thing a process said is what explains why it stopped β and says how much was dropped.
These settings can also be written under a watch.notify: block, which is the
canonical form:
watch:
notify:
enabled: true
notify_on: flapping
cooldown: 5m
flapping:
short_window: 10mBoth spellings are read, so either layout works. If a file contains both, the
notify: block wins and homebutler config validate says so.
homebutler watch remove nginx # Stop watching
homebutler watch check # One-shot check (no continuous monitoring)homebutler proxmox status
homebutler proxmox guests --status running
homebutler proxmox guest shutdown --node pve1 --type lxc --vmid 105 --confirm
homebutler proxmox task UPID:pve1:... --node pve1A Proxmox endpoint is its own kind of target, configured under proxmox: with an
API token rather than SSH, so it does not join the --server or --all fan-out.
TLS verification stays on: trust comes from a pinned SHA-256 fingerprint, then a
CA file, and only then an explicit insecure fallback.
Reads are plain. Power actions are not: every one of them takes an explicit
endpoint, node, guest type and VMID, and refuses to run without --confirm,
which is checked before any credential is read. They also need their own
action_token_id (plus action_token or action_token_file) configured on
the endpoint β the read token alone will not start, reboot, or shut down a
guest; see Proxmox setup β for creating that second token.
shutdown asks the guest to shut down cleanly β it is not Proxmox's hard
stop, which cuts power and can leave a filesystem behind it. A successful
action reports the task it submitted, not that the guest finished; proxmox task answers that separately.
proxmox script prints the install command for a Community Script pinned to one
commit, along with a warning that the script is not reviewed by homebutler and
runs as root. It never fetches or runs it β see #62
for why that line is where it is.
π Proxmox setup, tokens, and TLS β
homebutler watch tuiβ A terminal-based dashboard powered by Bubble Tea. Monitors all configured servers with real-time updates, color-coded resource bars, and Docker container status. No browser needed.
Use natural language when you want automation. MCP clients can call homebutler tools to check server status, list Docker containers, inspect ports, or run operational workflows. See screenshots & setup β
Deploy self-hosted apps with a single command. Each app runs via docker compose with automatic pre-checks, health verification, and clean lifecycle management.
# List available apps
homebutler install list
# Install (default port)
homebutler install uptime-kuma
# Install with custom port
homebutler install uptime-kuma --port 8080
# Install jellyfin with media directory
homebutler install jellyfin --media /mnt/movies
# Check status
homebutler install status uptime-kuma
# Stop (data preserved)
homebutler install uninstall uptime-kuma
# Stop + delete everything
homebutler install purge uptime-kuma~/.homebutler/apps/
βββ uptime-kuma/
βββ docker-compose.yml β auto-generated, editable
βββ data/ β persistent data (bind mount)
- Pre-checks β Verifies docker is installed/running, port is available, no duplicate containers
- Compose-based β Each app gets its own
docker-compose.ymlyou can inspect and customize - Data safety β
uninstallstops containers but keeps your data;purgeremoves everything - Cross-platform β Auto-detects docker socket (default, colima, podman)
| App | Default Port | Description | Notes |
|---|---|---|---|
uptime-kuma |
3001 | Self-hosted monitoring tool | |
plex |
32400 | Plex Media Server | --media /path to mount media dir |
vaultwarden |
8080 | Bitwarden-compatible password manager | |
filebrowser |
8081 | Web-based file manager | |
it-tools |
8082 | Developer utilities (JSON, Base64, Hash, etc.) | |
gitea |
3002 | Lightweight self-hosted Git service | |
jellyfin |
8096 | Media system (movies, TV, music) | --media /path to mount media dir |
homepage |
3010 | Modern homelab dashboard | |
stirling-pdf |
8083 | All-in-one PDF tool (merge, split, convert, OCR) | |
speedtest-tracker |
8084 | Internet speed test with historical graphs | |
mealie |
9925 | Recipe manager and meal planner | |
pi-hole |
8088 | DNS ad blocking | |
adguard-home |
3000 | DNS ad blocker and privacy | |
portainer |
9443 | Docker management GUI | |
nginx-proxy-manager |
81 | Reverse proxy with SSL and web UI |
# Jellyfin: mount your media library
homebutler install jellyfin --media /mnt/movies
# Pi-hole / AdGuard: DNS ad blocking (port 53 required)
homebutler install pi-hole
# β οΈ If port 53 is in use (Linux): sudo systemctl disable --now systemd-resolved
# Portainer: Docker GUI (mounts docker socket)
homebutler install portainer
# Access via HTTPS: https://localhost:9443
# Nginx Proxy Manager: reverse proxy
homebutler install nginx-proxy-manager
# Default login: admin@example.com / changeme (change immediately!)
# Any app: custom port
homebutler install <app> --port 9999- Port conflict detection β Checks if the port is already in use before install
- DNS mutual exclusion β Warns if pi-hole and adguard-home are both installed
- Docker socket warning β Alerts when an app requires Docker socket access (portainer)
- OS-specific guidance β Linux gets systemd-resolved fix, macOS gets lsof command
- Post-install tips β DNS setup, HTTPS access, default credential warnings
Want more apps? Open an issue or see Contributing.
homebutler <command> [flags]
Commands:
status System status (CPU, memory, disk, uptime)
doctor Diagnose health, exposure, backups, and readiness
config validate Check the config file and report what is ignored
docker list List running containers
install <app> Install a self-hosted app (docker compose)
alerts Show current alert status
watch tui TUI dashboard (monitors all configured servers)
watch add/list/remove Manage watched containers
watch check/start One-shot or continuous restart detection
watch history/show Browse restart history
proxmox status Proxmox VE cluster, nodes, guests, and storage
serve Web dashboard (browser-based, go:embed)
Flags:
--json JSON output (default: human-readable)
--verbose, -v Show detailed error information
--server <name> Run on a specific remote server
--all Run on all configured servers in parallel
--port <number> Port for serve command (default: 8080)
--config <path> Config file (auto-detected, see Configuration)
Run homebutler --help for all commands.
π All Commands & Flags
Commands:
init Interactive setup wizard
config validate Check the config file and report what is ignored
status System status (CPU, memory, disk, uptime)
doctor Diagnose health, exposure, backups, and readiness
watch tui TUI dashboard (monitors all configured servers)
watch add <name> Add container to restart watch list
watch list Show watched containers
watch remove <name> Remove container from watch list
watch check One-shot restart check
watch start Continuous monitoring: restarts, thresholds, rules
watch install Register watch with systemd or launchd
watch installed Report whether it is registered
watch uninstall Remove the service unit
watch history List restart history (alias: incidents)
watch show <id> Show restart details with logs
serve Web dashboard (browser-based, go:embed)
docker list List running containers
docker restart <n> Restart a container
docker stop <n> Stop a container
docker logs <n> Show container logs
docker top <n> Show processes running inside a container
docker inspect <n> Show image, state, ports, mounts, networks, health
report What changed since the last snapshot
inventory scan Map containers, ports, and topology
inventory show Same as scan (--filter exposed narrows it)
inventory export Export the map (--format mermaid)
proxmox status Proxmox VE cluster, nodes, guests, storage
proxmox guests List QEMU and LXC guests
proxmox node <n> Node detail
proxmox guest ... start / shutdown / reboot (needs --confirm)
proxmox task <upid> Task status for an action already submitted
proxmox tasks Recent tasks on a node
proxmox script Community Script install commands (prints, never runs)
notify test Send a test notification through configured providers
wake <name> Send Wake-on-LAN packet
ports List open ports with process info
ps Show top processes (alias: processes)
ps --sort mem Sort by memory instead of CPU
ps --limit 20 Show top 20 (default: 10, 0 = all)
network scan Discover devices on LAN
alerts Show current alert status
alerts --watch Thresholds only (watch start covers these too)
trust <server> Register SSH host key (TOFU)
backup Backup Docker volumes, compose files, and env
backup list List existing backups
backup drill <app> Verify backup restores correctly (isolated)
backup drill --all Verify all apps in backup
restore <archive> Restore from a backup archive
upgrade Upgrade local + all remote servers to latest
deploy Install homebutler on remote servers
install <app> Install a self-hosted app (docker compose)
install list List available apps
install status <a> Check installed app status
install uninstall Stop app (keep data)
install purge Stop app + delete all data
mcp Start MCP server (JSON-RPC over stdio)
version Print version
Flags:
--json JSON output (default: human-readable)
--verbose, -v Show detailed error information
--server <name> Run on a specific remote server
--all Run on all configured servers in parallel
--port <number> Port for serve command (default: 8080)
--demo Run serve with realistic demo data
--watch Continuous monitoring mode (alerts command)
--interval <dur> Watch interval, e.g. 30s, 1m (default: 30s)
--config <path> Config file (auto-detected, see Configuration)
--local Upgrade only the local binary (skip remote servers)
--local <path> Use local binary for deploy (air-gapped)
--service <name> Target a specific Docker service (backup/restore)
--allow-bind <path> Host path a restore may write a bind mount to (repeatable)
--endpoint <name> Proxmox endpoint from config (optional if only one)
--confirm Required for a Proxmox guest power action
--to <path> Custom backup destination directory
--archive <path> Specific backup archive for drill
--all Verify all supported apps (backup drill)
π Web Dashboard
homebutler serve starts an embedded web dashboard β no Node.js, no Docker, no extra dependencies.
homebutler serve # http://localhost:8080
homebutler serve --port 3000 # custom port
homebutler serve --demo # demo mode with sample dataOne-command Docker backup β volumes, compose files, and env variables.
homebutler backup # backup everything
homebutler backup --service jellyfin # specific service
homebutler backup --to /mnt/nas/backups/ # custom destination
homebutler backup list # list backups
homebutler restore ./backup.tar.gz # restore
β οΈ Database services should be paused before backup for data consistency.
π Full backup documentation β β how it works, archive structure, security notes.
alerts still exists for CPU, memory, and disk threshold checks, but it is an advanced flow and not the recommended first step for new users.
homebutler alerts --watch # default: 30s interval
homebutler alerts --watch --interval 10s # check every 10 seconds
homebutler alerts history # view alert history
homebutler notify test # test your notification channelsDefault thresholds: CPU 90%, Memory 85%, Disk 90%. Start with watch, then add alerts only if you specifically want threshold-based checks.
"Having a backup" and "being able to restore" are different things.
Backup Drill boots your backup in an isolated Docker environment and verifies the app actually responds β like a fire drill for your data.
homebutler backup drill uptime-kuma # verify one app
homebutler backup drill --all # verify all apps
homebutler backup drill --json # machine-readable output
homebutler backup drill --archive ./file # use a specific backupWhat happens:
- Finds the latest backup archive
- Verifies archive integrity (
tarvalidation) - Creates an isolated Docker network + random port
- Boots the app from backup data
- Runs an HTTP health check
- Reports pass/fail and cleans up everything
π Backup Drill β uptime-kuma
π¦ Backup: ~/.homebutler/backups/backup_2026-04-04_1711.tar.gz
π Size: 18.6 MB
π Integrity: β
tar valid (8 files)
π Boot: β
container started in 0s
π Health: β
HTTP 200 on port 58574
β±οΈ Total: 2s
β
DRILL PASSED
Zero risk β runs in a completely isolated environment. Your running services are never touched.
Supports health checks for: nginx-proxy-manager, vaultwarden, uptime-kuma, pi-hole, gitea, jellyfin, plex, portainer, homepage, adguard-home.
homebutler init # interactive setup wizardπ What report compares β β what earns a line, what is deliberately suppressed, and why.
π Configuration details β β config file locations, watch/notify options, and advanced alert thresholds.
Manage multiple servers from a single machine over SSH.
homebutler status --server rpi # query specific server
homebutler status --all # query all in parallel
homebutler deploy --server rpi # install on remote server
homebutler upgrade # upgrade all serversπ Multi-server setup β β SSH auth, config examples, deploy & upgrade.
Built-in MCP server β manage your homelab from any AI tool with natural language.
{
"mcpServers": {
"homebutler": {
"command": "npx",
"args": ["-y", "homebutler@latest"]
}
}
}Works with Claude Desktop, ChatGPT, Cursor, Windsurf, and any MCP client.
π MCP server setup β β supported clients, available tools, agent skills.
brew install Higangssh/homebutler/homebutlerAutomatically installs to PATH. Works on macOS and Linux.
curl -fsSL https://raw.githubusercontent.com/Higangssh/homebutler/main/install.sh | shAuto-detects OS/architecture, downloads the latest release, and installs to PATH.
npm install -g homebutlerDownloads the Go binary automatically. Use npx -y homebutler@latest to run without installing globally.
go install github.com/Higangssh/homebutler@latestgit clone https://github.com/Higangssh/homebutler.git
cd homebutler
make buildrm $(which homebutler) # Remove binary
rm -rf ~/.config/homebutler # Remove config (optional)Goal: Engineers manage servers from chat β not SSH.
Alert fires β AI diagnoses β AI fixes β you get a summary on your phone.
homebutler is the tool layer in an AI ChatOps stack. It doesn't care what's above it β use any chat platform, any AI agent, or just your terminal.
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Layer 3 β Chat Interface β
β Telegram Β· Slack Β· Discord Β· Terminal Β· Browser β
β (Your choice β homebutler doesn't touch this) β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββΌββββββββββββββββββββββββββββ
β Layer 2 β AI Agent β
β OpenClaw Β· LangChain Β· n8n Β· Claude Desktop β
β (Understands intent β calls the right tool) β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β CLI exec or MCP (stdio)
ββββββββββββββββββββββββΌββββββββββββββββββββββββββββ
β Layer 1 β Tool (homebutler) β YOU ARE HERE β
β β
β βββββββββββ βββββββββββ βββββββββββ β
β β CLI β β MCP β β Web β β
β β stdout β β stdio β β :8080 β β
β ββββββ¬βββββ ββββββ¬βββββ ββββββ¬βββββ β
β ββββββββββββββΌβββββββββββββ β
β βΌ β
β internal/* β
β system Β· docker Β· ports Β· network β
β wake Β· alerts Β· remote (SSH) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
Three interfaces, one core:
| Interface | Transport | Use case |
|---|---|---|
| CLI | Shell stdout/stderr | Terminal, scripts, AI agents via exec |
| MCP | JSON-RPC over stdio | Claude Desktop, ChatGPT, Cursor, any MCP client |
| Web | HTTP (go:embed) |
Browser dashboard, on-demand with homebutler serve |
All three call the same internal/ packages β no code duplication.
homebutler is Layer 1. Swap Layer 2 and 3 to fit your stack:
- Terminal only β
homebutler status(no agent needed) - Claude Desktop β MCP server, Claude calls tools directly
- OpenClaw + Telegram β Agent runs CLI commands from chat
- Custom Python bot β
subprocess.run(["homebutler", "status", "--json"]) - n8n / Dify β Execute node calling homebutler CLI
No ports opened by default. CLI and MCP use stdin/stdout only. The web dashboard is opt-in (homebutler serve, binds 127.0.0.1).
Now: CLI + MCP + Web dashboard β you ask, it answers.
Goal: Full AI ChatOps β infrastructure that manages itself.
Contributions welcome! Please open an issue first to discuss what you'd like to change. CONTRIBUTING.md covers what homebutler accepts and what a new target has to prove.
Found a vulnerability? Report it privately through the Security tab rather than a public issue. SECURITY.md covers what is in scope and what to expect.




