Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fleet-manager

A Claude Code plugin for managing a fleet of Linux servers over SSH. Keeps a per-server inventory and an "active server" pointer, deploys a dedicated SSH key, and provides guided setup, connectivity diagnostics and system status across hosts.

Modeled on synology-manager-plus; the NAS stays there (DSM-specific), fleet-manager is for generic Linux hosts.

Workspace & persistence

Your real inventory lives outside the plugin, in ${XDG_CONFIG_HOME:-~/.config}/fleet-manager (servers/*.md, active-server, inventory.md). It is therefore never committed — server topology cannot land in git — and it survives claude plugin update, which replaces the whole version-pinned plugin directory. Set FM_CONTEXT_DIR to relocate it.

Installs from before 0.3.3 kept this state inside the plugin directory, where each update stranded it. The library copies such an inventory forward automatically on first use and leaves the originals in place.

Commands

Command Description
/first-run Onboard your first server (guided intake)
/add-server Add another server (re-add protected)
/list-servers Show the inventory; mark the active server
/use <name> Set the active server
/setup-ssh [server] Generate + deploy the plugin keypair (idempotent)
/diag [server] Connectivity + health check
/status [server] Disk / memory / uptime / load
/compose-list [server] List Compose projects
/docker-list [server] [--all] List containers
/compose-logs [server] <project> Compose logs
/compose-up [server] <project|--file path> Start a stack (scope-gated)
/compose-down [server] <project> [--remove] Stop a stack (critical → --confirm)
/compose-update [server] <project> Pull + recreate
/logs [server] [unit] System journal (journalctl/syslog)
/health-summary Fleet-wide health (one row per server)
/copy <src> <dst> Copy local↔server (rsync/scp)
/sync <src> <dst> [--apply] Mirror local↔server (dry-run default)

The active server is targeted when no argument is given; pass a name to override. Every command prints → Ziel: <name> (user@host:port) before acting.

Fleet & transfer

/health-summary does a sequential one-row-per-server sweep (UP/DOWN/SKIP + verdict), one SSH round-trip each. /copy and /sync move files between the local machine and a server using the <server>:<path> syntax (the name before : is an inventory server, resolved through the plugin key). Both require the server's file_transfer scope; rsync is used (--protect-args), with an scp fallback for /copy. /sync is dry-run by default (--apply to execute); --delete additionally needs the typed --confirm-delete=<server> token, and a protected-path destination needs --confirm=<server>. Paths must be space-free at the command boundary.

Compose & logs

The compose suite drives docker compose on each host via a per-server docker_cmd discovered at /diag/intake (e.g. docker, sudo -n docker) and allowlist-validated. Compose commands require the server's docker_compose scope; /logs requires system_monitoring. Destructive actions against a project listed in the profile's critical_compose_projects require a human-typed --confirm=<project> token (or FM_CONFIRM_CRITICAL=yes) — a fail-safe against accidental runs (it makes intent visible in the command line; it is not an agent-proof gate). A never-started stack is brought up with /compose-up --file /abs/path/docker-compose.yml.

Requirements

  • SSH access to each server; the plugin uses its own key ~/.ssh/fleet-manager_ed25519.
  • Bash >= 4, OpenSSH client locally.

Host-key verification (first connection)

The plugin does not disable host-key checking — it relies on the OpenSSH default, which is the secure choice. Because every connection runs with BatchMode=yes (no interactive prompts), the first connection to a host whose key is not yet in your ~/.ssh/known_hosts will fail rather than silently trust-on-first-use. Establish the host key once, out of band, before /diag:

ssh-keyscan -p <port> <host> >> ~/.ssh/known_hosts   # review the fingerprint first
# or simply connect once interactively and accept the key:
ssh -p <port> <user>@<host>

This is intentional: it prevents a silent man-in-the-middle on an unknown host. /setup-ssh surfaces this as a likely cause when key auth fails.

Development

  • Unit tests: for t in tests/unit/*.sh; do bash "$t"; done
  • Static checks: for s in tests/static/*.sh; do bash "$s"; done
  • Integration (needs Docker + rsync): bash tests/integration/run-all.sh

License

MIT — CallMeTechie

About

Claude Code plugin to manage a fleet of Linux servers over SSH

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages