An SSH server inventory and connectivity toolkit.
shellkit reads a Nix host inventory and gives you a fast table view, a TUI, an
SSH config generator, and an MCP ssh tool that runs step-based scripts on
remote hosts.
- Inventory table and interactive TUI for your SSH fleet
- Connectivity checker across every host and overlay address
- SSH config generation from a single source of truth
- MCP
sshtool — a step-based DSL for running scripts, fan-out, file transfer, and output chaining on remote hosts - Two execution paths for that DSL — a fast in-process command runner
(nanosecond-precision trace, real per-command exit codes) on by default for
statically-screened scripts, falling back to the legacy real-bash path for
anything outside its bash-compatible subset (
"interp": falseforces legacy per step); see skills/shellkit-expert/SKILL.md - TUI log dashboard for MCP call history
shellkit is a single Go binary. Build it with plain Go:
git clone https://github.com/caoer/shellkit.git
cd shellkit
go build -o shellkit ./cmd/shellkitOr install straight from source:
go install github.com/caoer/shellkit/cmd/shellkit@latestA Nix flake is provided for a reproducible dev shell —
nix develop (or direnv allow with direnv), then
just build.
Runtime requirement: shellkit reads its inventory by shelling out to
nix eval, sonixmust be onPATHat runtime — even for a plaingo build. See Optional dependencies for the rest.
shellkit reads hosts from a Nix file that exposes a hosts attribute set. Each
host's fields map to addresses, login details, and metadata:
{
hosts = {
web-1 = {
wan_ip = "203.0.113.10";
user = "deploy";
identity = "id_ed25519";
};
db-1 = {
lan_ip = "10.0.0.20";
user = "admin";
proxy_jump = "web-1";
};
};
}See examples/inventory.sample.nix for the full field reference.
Point shellkit at your inventory with a flag or an environment variable:
shellkit -f ./inventory.nix list
export SHELLKIT_INVENTORY=./inventory.nixIf neither is set, shellkit searches the current directory upward for
shellkit.nix, inventory.nix, hosts.nix, or lib/ssh/hosts/default.nix,
and fails with guidance when none is found.
shellkit # interactive TUI (default)
shellkit list # print the server table
shellkit list --json # machine-readable output
shellkit check # probe every server
shellkit ssh <name> # SSH into a server by name or alias
shellkit generate-configs # write an SSH config to $SHELLKIT_GENERATED_CONFIG_PATH or stdoutFilter to a subset with --managed <value>, and choose which address to
connect on with --addr auto|wan|lan|wireguard|tailscale|easytier.
On macOS with OrbStack running, local OrbStack VMs are
auto-discovered and appear alongside your inventory hosts. generate-configs
also clears stale SSH ControlMaster sockets under ~/.ssh/sockets/ so the
regenerated config starts with fresh connections.
Run shellkit as an MCP server to expose the ssh tool to an agent:
shellkit mcp # stdio transport
shellkit mcp start # background HTTP daemon
shellkit mcp status # check the daemon
shellkit mcp stop # stop the daemon
shellkit mcp restart # restart the daemon
shellkit mcp log-dashboard # TUI for MCP call logsThe ssh tool takes one or more steps. Each step has a name, an optional JSON
config that selects the action, and a script body. Later steps read earlier
steps' output:
### install
{"ssh": "web-1", "timeout": 120}
apt-get update && apt-get install -y nginx
echo "installed=true" >> $OUTPUT
### verify
{"ssh": "web-1"}
if [ {{install.outputs.installed}} = true ]; then
systemctl is-active nginx
fi
Fan out with {"ssh": ["web-1", "web-2"]}, drive interactive programs with
{"tmux": "host:session"}, and run a body with no config to execute it locally.
Send ### help to the tool for the full pipeline and tmux reference.
| Variable | Purpose |
|---|---|
SHELLKIT_INVENTORY |
Inventory file path (.nix exposing a hosts attset) |
SHELLKIT_ADDR_PREF |
Default address preference (overridden by --addr) |
SHELLKIT_DEFAULT_IDENTITY |
Fallback SSH identity when a host sets none (default: ~/.ssh/id_ed25519) |
SHELLKIT_GENERATED_CONFIG_PATH |
Destination for generate-configs |
SHELLKIT_MCP_PORT |
MCP HTTP port (default: 19222) |
SHELLKIT_MCP_TOKEN |
Bearer token for the MCP HTTP server |
shellkit shells out to these when a feature needs them:
ssh— system OpenSSH client (required for connections)sops— decryptpassword_refsecretssshpass— password-based SSH logintmux— drive interactive remote sessions
just build # build the binary
just test # run the Go test suite
just lint # go vet + golangci-lint + shellcheck + nix flake check
just fmt # format Go, shell, and nix sourcesThe Nix flake provides the toolchain (nix develop / direnv allow); entering
the dev shell installs a fast lefthook pre-commit hook (gofmt + go vet).
See CONTRIBUTING.md.
MIT — see LICENSE.