skills/sshp/SKILL.md (2923 bytes)
1 --- 2 name: sshp 3 description: Run one command on many SSH hosts in parallel with sshp, and read per-host output and exit codes. Use to run a command on several servers, for example "is the service up on every server", "disk space on all hosts", "which hosts run kernel X", or when the user names several hosts or a hosts file. Use -n for a dry run before risky commands. 4 --- 5 6 # sshp: parallel SSH runner 7 8 `sshp` (https://github.com/bahamas10/sshp) runs one command on many hosts at once and prefixes each output line with `[host]`. Prefer it over a shell loop of `ssh` calls. 9 10 If the `sshp_run` MCP tool is available, use it: it enforces the host allowlist and returns JSON per host. If the operator left `allow_write` off, it refuses commands outside a read-only verb list. Otherwise call the `sshp` binary as below. 11 12 ## Rules 13 14 1. **Probe first.** Commands that change nothing are a good start: `uptime`, `df -h`, `systemctl is-active X`, `journalctl -u X -n 50`, `cat /etc/os-release`. 15 2. **Dry run risky commands.** Run with `-n` to list what would run. For a destructive command (delete, reboot, mass restart), show the user the host list and command and get a yes first. 16 3. **Never let it hang.** Always pass `-o BatchMode=yes -o ConnectTimeout=10`. A password prompt or host-key prompt then fails fast instead of blocking. 17 4. **Limit concurrency for heavy work.** Default `-m 50`. Use `-m 1` for rolling changes (one host at a time), `-m 5` for anything that loads the hosts. 18 5. **Read exit codes per host.** Always pass `-e`. sshp prints `[host] exited: N (T ms)`. Report the hosts that failed, not only the overall status. sshp itself exits non-zero if any host failed. 19 6. **Use a hosts file.** `-f hosts` reads one host per line (`user@host` works). Do not invent hosts; use the ones the user gives or the configured file (`~/.config/sshp-ai/hosts`). 20 21 ## Commands 22 23 ```sh 24 # Run: one line per host, exit codes, no prompts 25 sshp -e -c off -o BatchMode=yes -o ConnectTimeout=10 -f hosts uptime 26 27 # Group output by host (multi-line output stays together) 28 sshp -g -e -f hosts -- df -h / 29 30 # Join mode: group hosts that produced identical output (spot the odd one out) 31 sshp -j -f hosts -- uname -r 32 33 # Dry run: show what would run, start nothing 34 sshp -n -f hosts -- systemctl restart nginx 35 36 # Rolling change after the user said yes: one host at a time, login as root 37 sshp -m 1 -g -e -l root -f hosts -- systemctl restart nginx 38 ``` 39 40 Put `--` before the remote command so sshp does not parse its flags. Quote a remote pipeline as one argument: `sshp -f hosts -- 'ps aux | grep nginx'`. 41 42 ## Exit codes 43 44 | sshp exit | Meaning | 45 |---|---| 46 | 0 | Every host exited 0 | 47 | 1 | At least one host exited non-zero (see `[host] exited:` lines) | 48 | 2 | Bad sshp arguments | 49 | 4 | Interrupted (SIGINT or SIGTERM) | 50 51 Per host, `255` means ssh itself failed (DNS, refused, auth, host key). Any other code is the remote command's own exit code.