Tells an agent what changed on a server since it last looked - status, Docker, backups, Proxmox.
io.github.Higangssh/homebutler MCP Server
This MCP server lets you inspect and manage a homelab over MCP, covering status, Docker, ports, and backups, without shell access. It is implemented as a single Go binary intended for running a small home server without manual “babysitting.”
🛠️ Key Features
Inspect homelab status via MCP
Manage Docker-related aspects
Review/handle port information
Manage backups
No shell access required
Provided as a single Go binary
🚀 Use Cases
Monitor and manage services in a homelab through MCP
Operate Docker services and related networking/ports
Handle backup workflows remotely via MCP
Support chatops-style management workflows (topics include chatops)
⚡ Developer Benefits
Go-based, single-binary deployment
Fits MCP server usage patterns (topics include mcp and mcp-server)
Developer-oriented toolset (topics include cli, devops, monitoring, selfhosted)
⚠️ Limitations
Limited to homelab inspection/management areas listed in the description (status, Docker, ports, backups)
brew install Higangssh/homebutler/homebutler # or: curl -fsSL https://raw.githubusercontent.com/Higangssh/homebutler/main/install.sh | sh
homebutler report # first run saves a baseline; the second tells you what moved
Or as a container, reaching your machines over SSH — docs/docker.md:
docker run -v ~/.config/homebutler:/config -v ~/.ssh:/root/.ssh:ro ghcr.io/higangssh/homebutler
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.
Reading a change
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.
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. Run it from a terminal, cron, a web dashboard you start when you want one, or an AI agent.
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.
a run through homebutler: report naming what moved since the last snapshot — a container gone, a port answered by something new, one recreated behind the same name — then the same answer as JSON with the kind as a field, then doctor listing what is exposed and what has never been backed up with the command for each, then a backup drill booting the archive in its own container and requiring an HTTP health check, then the same report on a phone, then the settings screen editing notification channels
# 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
# Or as a container — the hub that reaches your machines over SSH
docker run -d -p 8080:8080 -v ~/.config/homebutler:/config -v ~/.ssh:/root/.ssh:ro \
ghcr.io/higangssh/homebutler serve --host 0.0.0.0 --token "$(openssl rand -hex 16)"# Interactive setup — add your servers in seconds
homebutler init
Use it right away:
bash
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:8080
Machine-readable output is available everywhere:
bash
homebutler status --json
homebutler inventory scan --json
homebutler report --json
What it does
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, task status, and honest dashboard freshness, with power actions that name their target explicitly
Use it anywhere — CLI, JSON, web dashboard, or MCP for AI agents without giving them SSH
Why homebutler?
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.
Alongside what you already run
Keep Uptime Kuma for is it up, Beszel or Netdata for the graph, Dozzle for the logs.
HomeButler answers the question none of them ask: what is different from last time, and does it matter?
No agent on the machines it watches. The binary is put there once with homebutler deploy and runs only when asked, over SSH — no daemon, no open port, nothing listening between runs.
The judgement is a written rule, not a model. What earns a line is in docs/report.md, and the same input gives the same report — no AI required, no account, no paid tier.
It checks that a backup comes back. A backup you have never restored is a folder. backup drill boots the archive as a second copy of the app, on a network and port of its own, and requires it to answer an HTTP health check before calling the archive good — then removes everything it made. A failed drill exits non-zero, so backup drill --all belongs in the same cron entry as backup. docs/backup.md has what it does and what it does not prove.
code
🔐 Integrity: ✅ tar valid (8 files)
🚀 Boot: ✅ container started in 0s
🌐 Health: ✅ HTTP 200 on port 60405
✅ DRILL PASSED
Core workflows
🧾 Butler Report
bash
homebutler report
homebutler report --keep 7 # retain only the latest 7 snapshots
homebutler report --no-save # preview without writing a snapshot
report 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.
🩺 Doctor Check
bash
homebutler doctor
homebutler doctor --strict # non-zero exit if warnings/failures are found
homebutler doctor --json # automation / MCP friendly
doctor 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.
Every finding carries a category, and --json carries the same word, so a
caller filters on it without reading the title:
Category
What it is about
system
CPU, memory, disk
docker
containers that are stopped or unhealthy
exposure
ports listening on every interface
backup
backups missing, stale, never drilled, or growing without a retention limit
report
whether there is a baseline to compare against
watch
targets listed with nothing polling them
notifications
channels configured, or never tested
proxmox
an endpoint that cannot be reached with the token it has
config
the config file itself — permissions, keys homebutler does not know
incomplete
a collector did not answer, so this diagnosis is partial
overall
nothing specific: the all-clear
incomplete is the one worth handling. It means the answer you are reading is
missing a section, which is different from that section being fine.
🗂 Config Validation
bash
homebutler config validate
homebutler config validate --strict # exit non-zero on warnings too
homebutler config validate --json
config 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.
text
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.
📦 One-Command App Install
code
$ homebutler install list
📦 Available apps (15):
uptime-kuma A self-hosted monitoring tool
vaultwarden Lightweight Bitwarden-compatible password manager
jellyfin Free software media system for streaming movies, TV, and music
pi-hole Network-wide ad blocking via DNS filtering
…
homebutler install uptime-kuma — Deploy self-hosted apps in seconds. Pre-checks Docker, ports, and duplicates. Generates docker-compose.yml automatically. See all available apps →
inventory 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.
text
🏠 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:
bash
homebutler inventory scan --filter exposed
text
🏠 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:
homebutler serve — A web dashboard embedded in the single binary via go:embed. Servers, Docker containers, open ports, alerts and Wake-on-LAN from any browser. With --token it also edits the config: thresholds, notification channels, servers, Proxmox endpoints and wake devices.
The Report tab, where you actually read it
the Report tab on a phone: what needs attention first — a container recreated and not running, a port answered by something new — then the changes with their kind word, including a container replaced behind the same name and a comparison that could not be made, then doctor's findings ordered by severity with the command to run for each
The screen somebody opens after a notification. What needs attention first, then
what moved with the kind word each change carries, then the snapshot being
compared against and how old it is. A comparison that could not be made says so
rather than reading as an all-clear.
Loading it saves nothing — a page that took a snapshot every time it was opened
would prune the baseline you wanted to compare against. Saving one is a button.
✨ 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
bash
homebutler serve # Start on port 8080
homebutler serve --port 3000 # Custom port
homebutler serve --demo # Demo mode with realistic sample data
🔄 Process Restart Watch
Your 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.
homebutler watch install # register it with systemd or launchd
homebutler watch installed # is it registered?
homebutler watch uninstall
watch 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.
Every endpoint under proxmox: in your config is polled too: unreachable or
ACL-filtered endpoints and any guest listed under that endpoint's guests:
report one incident when the problem starts and one recovery incident when it
clears. A guest not listed there is observational only — watch start never
alerts on it, deliberately stopped or not. See
Proxmox setup → for the guests: field.
When a crash is detected, you'll see:
code
[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)
Step 3: Investigate
bash
homebutler watch history# List all incidents
homebutler watch show <incident-id> # Full details
watch show output includes:
Pre-death logs — what the process printed right before it died
Post-restart logs — what happened after the restart
action: 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 -1 to 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:
A 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.
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.
🧠 AI-Powered Management (MCP)
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 →
App Install
Deploy self-hosted apps with a single command. Each app runs via docker compose with automatic pre-checks, health verification, and clean lifecycle management.
bash
# 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 <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
code
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.
bash
homebutler serve # http://localhost:8080
homebutler serve --port 3000 # custom port
homebutler serve --demo # demo mode with sample data
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.
bash
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 channels
Default thresholds: CPU 90%, Memory 85%, Disk 90%. Start with watch, then add alerts only if you specifically want threshold-based checks.
🔍 Backup Drill
"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. A failed drill exits non-zero.
bash
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 backup
Full walkthrough, including what a passing drill does not prove: docs/backup.md.
What happens:
Finds the latest backup archive
Verifies archive integrity (tar validation)
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
code
🔍 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.
Manage multiple servers from a single machine over SSH.
bash
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
Built-in MCP server — an agent gets the same report as typed JSON, kind, target and detail rather than a sentence to parse, and every tool is classed read, write or destructive.
Works with Claude Desktop, ChatGPT, Cursor, Windsurf, and any MCP client.
📖 MCP server setup → — supported clients, available tools, agent skills.
Installation
Homebrew (Recommended)
bash
brew install Higangssh/homebutler/homebutler
Automatically installs to PATH. Works on macOS and Linux.
One-line Install
bash
curl -fsSL https://raw.githubusercontent.com/Higangssh/homebutler/main/install.sh | sh
Auto-detects OS/architecture, downloads the latest release, and installs to PATH.
npm (MCP server)
bash
npm install -g homebutler
Downloads the Go binary automatically. This package publishes one command,
homebutler-mcp, and it starts the MCP server — npx -y homebutler@latest
launches that, not the CLI. For the command line, use one of the other
installs above.
Go Install
bash
go install github.com/Higangssh/homebutler@latest
Build from Source
bash
git clone https://github.com/Higangssh/homebutler.git
cd homebutler
make build-all
make build-all compiles the web dashboard into the binary and needs Node
installed. make build skips it — the CLI is complete either way, and
homebutler serve then says the dashboard is missing and names the two ways
to get it.
Browser dashboard, on-demand with homebutler serve
All three call the same internal/ packages — no code duplication.
An agent reads the same report a person does, and gets the parts it has to branch on
rather than a screen it has to interpret:
python
report = json.loads(subprocess.run(
["homebutler", "report", "--json"], capture_output=True, text=True).stdout)
for change in report["notable_changes"]:
if change["kind"] == "replaced": # the container came back as something else
redeploy(change["target"])
else:
log(change["text"]) # "port: :8080/tcp — nginx → caddy"
Every line carries text as well, so a caller that only wants to print it does not have
to put the sentence back together.
Nothing above this is homebutler's business: an MCP client, a chat bot, a cron line or a
person at a terminal all reach the same answer.
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).
Contributing
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.
Security
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.