MCPcopy Index your code
hub / github.com/Higangssh/homebutler

github.com/Higangssh/homebutler @v0.19.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.19.0 ↗ · + Follow
1,279 symbols 4,301 edges 132 files 329 documented · 26% updated todayv0.19.2 · 2026-07-07★ 1644 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

HomeButler logo

HomeButler

Your tiny homelab butler.

A single Go binary for running a small home server without babysitting it.

Website · Docs · Releases

Go 1.25+ Go Report Card License: MIT Release homebutler MCP server

HomeButler mascot holding a tiny server

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.

homebutler demo

▶️ 34s demo — monitor, diagnose, and manage your homelab

Quick Start

# 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 init

Use 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:8080

Machine-readable output is available everywhere:

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, and report baseline readiness
  • 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
  • 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.

Why not just use Portainer, Netdata, or CasaOS?

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.

Core workflows

🧾 Butler Report

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

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, and whether report has a baseline for change detection.

📦 One-Command App Install

homebutler install demo

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 & Topology

homebutler inventory scan
homebutler inventory export --format mermaid
homebutler --json inventory scan

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.

🏠 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

Use Mermaid export when you want a diagram for GitHub, Obsidian, docs, or an AI assistant:

graph TD
  home["🏠 Home Network"] --> homelab["🖥 homelab

192.168.1.10"]
  homelab --> c1["📦 api-server

running"]
  homelab --> p1["🌍 :8080/tcp

api-server"]
  c1 -. exposes .-> p1

Demo

🌐 Web Dashboard

homebutler web dashboard

homebutler serve — A real-time web dashboard embedded in the single binary via go: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 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.

Supported backends: Docker (real-time event stream) · systemd (polling) · PM2 (polling)

Step 1: Add targets to watch

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 watching

Step 2: Start monitoring

homebutler watch start                  # Foreground, Ctrl+C to stop
homebutler watch start --interval 10s   # Custom poll interval (default 30s)

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)

Step 3: Investigate

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 - 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

Crash Analysis

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.

Flapping Detection

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 (optional, off by default)

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

alerts:
  cpu: 90
  memory: 85
  disk: 90
  rules:
    - name: cpu-spike
      metric: cpu
      threshold: 90
      action: notify

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

Manage targets

homebutler watch remove nginx           # Stop watching
homebutler watch check                  # One-shot check (no continuous monitoring)

🖥️ TUI Dashboard

homebutler TUI dashboard

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.

# 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

How it works

``` ~/.homebutler/apps/ └──

Extension points exported contracts — how you extend this code

Monitor (Interface)
Monitor watches a set of targets and sends incidents to the channel. Watch blocks until ctx is cancelled or an unrecover [3 …
internal/watch/monitor.go
ContainerLister (FuncType)
ContainerLister abstracts docker.List for testing.
internal/alerts/initprompt.go
RemoteRunner (FuncType)
RemoteRunner executes a homebutler command on a remote server via SSH. Default implementation uses remote.Run.
internal/server/server.go
CommandRunner (FuncType)
CommandRunner abstracts external command execution for testability.
internal/watch/monitor.go
EventStreamer (FuncType)
EventStreamer abstracts the creation of a docker events process for testability. It returns an io.ReadCloser for the eve
internal/watch/docker_monitor.go

Core symbols most depended-on inside this repo

Handler
called by 85
internal/server/server.go
Run
called by 53
internal/mcp/server.go
String
called by 49
internal/backup/drill.go
writeJSON
called by 45
internal/server/server.go
RunCmd
called by 45
internal/util/cmd.go
stringArg
called by 31
internal/mcp/server.go
output
called by 27
cmd/helpers.go
loadConfig
called by 25
cmd/root.go

Shape

Function 1,049
Struct 131
Method 91
FuncType 4
TypeAlias 3
Interface 1

Languages

Go98%
TypeScript2%

Modules by API surface

internal/server/server_test.go95 symbols
internal/remote/ssh_test.go49 symbols
internal/backup/drill_test.go45 symbols
internal/install/install_test.go36 symbols
internal/server/server.go29 symbols
internal/mcp/server.go28 symbols
internal/watch/store_test.go26 symbols
internal/docker/docker_test.go25 symbols
internal/watch/detector_test.go24 symbols
internal/backup/drill.go24 symbols
internal/doctor/doctor.go23 symbols
internal/watch/docker_monitor_test.go22 symbols

For agents

$ claude mcp add homebutler \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact