Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CLI reference

Everything sshelf does without opening the TUI.

Commands

CommandWhat it does
sshelfLaunch the interactive TUI.
sshelf <host>Connect straight to a saved host by name or id, skipping the TUI, on the same connect path as Enter (frecency recorded, stored secret auto-supplied, 2FA code prompted on the terminal). A miss suggests the closest names; a host named like a subcommand (list, import, …) is reached via the TUI instead.
sshelf -Reconnect to the most recently used host. Errors (without connecting) if there’s no history yet.
sshelf add [NAME ...]Bare: open the TUI add form. With arguments: add a host non-interactively; see below.
sshelf list [query] [--json]List hosts (with a ·site· column). query filters with the TUI’s syntax: fuzzy text and/or tag:NAME / site:NAME (e.g. sshelf list site:prod-dc). The user@host:port column shows site defaults resolved.
sshelf print-command <host>Print the generated, shell-quoted ssh ... command (site defaults included) without connecting or touching frecency, the CLI twin of Ctrl-y.
sshelf sites [--json]List defined sites with member counts + their shared defaults.
sshelf sites add NAME [-u/-p/-J/-i]Define a site (settings optional; edit later with F3).
sshelf import [--dry-run]Read-only import from ~/.ssh/config.
sshelf import --tailscale [--dry-run]Import your Tailscale tailnet: runs your own tailscale status --json and adds every eligible peer (MagicDNS name → host, tailnet → site, ACL tags → tags). Add-only; re-running adds 0.
sshelf export [--stdout]Export the database as an ssh_config Include fragment, written next to sshelf’s config (--stdout prints it instead). Once the file exists, it refreshes on every hosts change.
sshelf set-password <host>Store a password / key passphrase for a host, read from stdin.
sshelf doctorCheck this machine and your host database: the OpenSSH version, the secret backend, dangling site references, a stale export, a missing ssh-agent. Local and read-only; it never contacts a host. Exits 1 if any check failed (warnings don’t).
sshelf completions <shell>Print static shell completions.
sshelf manPrint the man page.

Global flags work before or after a subcommand (sshelf --config F list and sshelf list --config F are the same command). --config FILE uses a specific config file (also $SSHELF_CONFIG); see Configuration. --transfer-log FILE appends transfer diagnostics, no secrets, to FILE (also $SSHELF_TRANSFER_LOG); see Transferring files.

A host name and a subcommand can’t be combined: sshelf prod-web list is refused rather than quietly running list and forgetting the host.

Environment: $SSHELF_TAILSCALE_BIN names the tailscale binary --tailscale should run, for installs that aren’t on PATH (sshelf otherwise tries PATH, then the macOS app bundle at /Applications/Tailscale.app/Contents/MacOS/Tailscale). $SSHELF_VAULT_PASSPHRASE uses the age vault instead of the OS keyring; see Passwords, keys & 2FA.

Adding hosts from the CLI

sshelf add with arguments adds a host non-interactively (handy for scripts and dotfiles). NAME and --hostname are required:

# key auth (a -i identity implies --auth key)
sshelf add prod-web -H 10.25.25.10 -u deploy -i ~/.ssh/id_ed25519 -t prod,web

# jump host + custom port
sshelf add prod-db -H 10.25.25.25 -u mike -p 5432 -J bastion.example.net -i ~/.ssh/db

# agent auth (the default) with extra raw ssh flags
sshelf add edge -H edge.example.net --extra "-o ServerAliveInterval=30"

# password auth: pipe the secret in (kept out of argv/history; stored in the keyring or vault)
echo "$PASS" | sshelf add legacy -H 10.0.0.9 -u root --password-stdin
FlagMeaning
NAME (positional)Alias to search/connect by. Required.
-H, --hostname <HOST>IP or DNS name. Required.
-u, --user <USER>Login user (defaults to $USER at connect time).
-p, --port <PORT>SSH port (default 22).
-a, --auth <agent|key|password>Auth method. Inferred as key with --identity, password with --password-stdin, else agent.
-i, --identity <PATH>Identity file for key auth (repeatable).
-J, --jump <HOST>ProxyJump host (repeatable or comma-separated). Key/agent auth only.
-t, --tag <TAG>Tag (repeatable or comma-separated).
-s, --site <NAME>Assign the host to a site.
--2faMark the host as needing a verification code on connect.
--extra "<ARGS>"Extra raw ssh flags, appended verbatim.
--password-stdinRead a password / key passphrase from stdin and store it.

A duplicate name is refused. To store a secret after the fact, use sshelf set-password <name>.

Shell completions

Static completion (subcommands + flags) ships with every package. Open a new shell after installing so it loads. It’s also printed by sshelf completions <shell>.

Dynamic completion (sshelf prod<Tab> completing your saved host names) takes one line in your shell rc:

source <(COMPLETE=bash sshelf)   # bash: add to ~/.bashrc
source <(COMPLETE=zsh sshelf)    # zsh:  add to ~/.zshrc (after compinit)
COMPLETE=fish sshelf | source    # fish: add to ~/.config/fish/config.fish

Host-name completion works for direct connect, print-command, and set-password.

JSON output

sshelf list --json [query] emits each selected host’s fields plus its generated ssh command, and is always valid JSON even when the selection is empty, the stable surface for scripts and integrations. sshelf sites --json does the same for sites.

The host fields are the record as stored in hosts.toml, so a user, port, jump host or identity file inherited from a site stays null or empty there. The resolved values are in command.

sshelf doctor has no --json: its exit code (0 healthy, 1 something failed) is the scriptable part, and a machine-readable report has no users yet (D-027).