Skip to content

CLI

Use sshc help for the full command list. Use sshc <command...> --help or sshc help <command...> for the exact arguments accepted by an individual command, for example sshc sync push --help or sshc help terminal send.

The CLI uses the same OpenSSH configuration and the running engine's vault and sessions. For automation, use supported --json output instead of parsing human-readable text.

Codex and other AI agents can call the CLI directly. When the vault is unlocked and every host key and credential required by the route is already saved, non-interactive SSH uses the stored password, key passphrase, and assigned TOTP. The agent does not need the credential itself.

Engine and vault

sh
sshc engine
sshc engine --port 60001
sshc engine --replace
sshc
sshc open
sshc status --json
sshc version
sshc vault status
sshc vault create
sshc vault unlock
sshc vault lock
sshc vault change-password
sshc service install
sshc service status
sshc service disable
sshc update

sshc without arguments fetches a one-time URL from the running engine and opens it in the browser; sshc open only prints the URL. sshc engine --port <n> (1024–65535) pins the listening port. sshc version (-v, --version) prints this binary's version, and sshc vault status prints the same table as sshc status with the vault state.

Interactive secrets such as the Vault master password display one * per typed character instead of the value. Backspace and Ctrl+U update the mask, and the plaintext is never written to Terminal scrollback.

sshc service manages a systemd user service on Linux or a launchd user agent on macOS. install registers a stable Homebrew or install.sh path, and disable removes only a definition created by sshc. install, disable, and update show the planned changes and ask for confirmation. Use -y or --yes only when automation must skip the prompt.

sshc vault change-password validates the current password as soon as you press Enter, before asking for a new password. Passwordless Vaults skip the current-password prompt. Leave both the new password and confirmation empty to remove password protection. sshc vault lock keeps a passwordless Vault unlocked; set a master password to enable locking. After upgrading the CLI, restart the engine to apply these changes.

OTP

sh
sshc otp list [--json]
sshc otp <name>
sshc otp show <name> --json
sshc otp add <name>
sshc otp edit <name>
sshc otp remove <name> [-y|--yes]

list prints saved names and assignments only. sshc otp <name> and show print the previous, current, and next code plus the remaining lifetime of the current code, which makes a clock boundary visible. The provisioning secret stays inside the engine and is absent from both human and JSON output.

add and edit read a Base32 setup key or otpauth:// URI from an interactive terminal, displaying * instead of the value. An assigned TOTP cannot be removed until its Connections assignments are cleared.

SSH

sh
sshc ssh
sshc ssh --list
sshc ssh <alias>
sshc ssh <alias> --non-interactive -- <command...>
sshc info <alias> --json

The Homebrew formula installs completions for bash, zsh, and fish. For other installation methods, add the matching command below to your shell startup file. Completion covers subcommands, options, enumerated values, and connection aliases for sshc ssh, sshc info, sshc terminal create ssh, and sshc sftp. Alias candidates are read from the current ~/.ssh/config and reachable Include files whenever you press Tab. An alias containing characters sshc refuses to launch or evaluate (shell metacharacters, whitespace, a leading -) is left out of both sshc ssh --list and completion, and the reason is reported on stderr.

Command parsing, per-command help, and bash, zsh, and fish completion are built from the same command definition. Names and choices offered by completion therefore match sshc help from the installed version.

sh
# bash
source <(sshc completion bash)

# zsh
source <(sshc completion zsh)

# fish
sshc completion fish | source

On Linux, the system Bash completion loader may not search Homebrew's completion directory. If only filenames are offered, run source <(sshc completion bash) in the current shell. Add that line to ~/.bashrc to load the current command definitions for each new shell. Reload it after updating sshc if the current shell still offers old commands.

sshc info resolves Include, Match, ProxyJump and encoding through the real connection path without an engine. It does not print saved credentials, SetEnv values or the ProxyCommand body.

sh
sshc ssh bastion --non-interactive -- uname -a

Non-interactive SSH fails when it would need a question, such as an unknown host key, 2FA, or an unsaved password.

Sync

sh
sshc sync setup
sshc sync --json
sshc sync push [--force] [--json]
sshc sync pull [--force] [--json]
sshc sync now [--json]
sshc sync auto on|off [--json]

sshc sync setup shows the configured endpoint, bucket, path, region, and direction as defaults. Direction accepts both, push, or pull. The Access Key ID is shown as ***** followed by its final five characters; the Secret Access Key and sync key are shown only as configured. Press Enter on blank secret prompts to keep the values already held by the engine. While a new hidden value is typed, each character appears as *, and Backspace updates the mask without printing the plaintext.

SFTP transfers

Transfers use the running engine and the same OpenSSH configuration, host-key checks, and Vault credentials as the Web UI. Specify remote paths as absolute POSIX paths such as /var/log/app.log.

sh
sshc sftp get bastion /var/log/app.log ./app.log
sshc sftp put bastion ./release.tar.gz /tmp/release.tar.gz
sshc sftp get bastion /srv/data ./data --recursive
sshc sftp put bastion ./public /var/www/public --recursive
sshc sftp get bastion /srv/archive ./archive --recursive --jobs 4
sshc sftp get bastion /srv/archive ./archive --recursive --max-total-size 8192
sshc sftp settings
sshc sftp settings --split-size 73 --split-jobs 6 --chunk-size 41
sshc sftp get bastion /backup/disk.img ./disk.img --split-size 100 --split-jobs 4 --chunk-size 512
sshc sftp put bastion ./disk.img /backup/disk.img --split-size 100 --split-jobs 4 --chunk-size 512

sshc sftp settings displays the split threshold, connections per file, and chunk size shared by Web and CLI. Add --split-size (16–1024 MiB), --split-jobs (1–128), or --chunk-size (8–4096 MiB) to persist only the supplied defaults. --json returns the saved values for automation.

-j or --jobs sets the number of files transferred concurrently from 1 to 8; the default is 1. Split options on get or put override the saved defaults for that invocation. --split-jobs 1 disables splitting. Initial defaults are 100 MiB, one connection (no splitting), and 32 MiB chunks. To transfer in parallel, give --split-jobs for that run or change the saved default with sshc sftp settings --split-jobs or the Transfer Manager. A host that authenticates with a one-time code transfers over one connection whatever the setting. --split-jobs accepts up to 128, while the actual connection count is limited by the number of unfinished chunks. Concurrent split transfers multiply the total connection count, so choose a value that fits both the server and the device. Regular file uploads and downloads support up to 512 GiB.

put and get give a transferred file the modification time of its source. Symlinks are transferred as what they point to, as WinSCP and scp do, and a link to a directory brings that directory's contents. A link whose target is missing, or an entry that is neither a file nor a directory, is reported on standard error as skip and counted in the result's skipped without stopping the rest. A directory sent with --recursive creates the remote directories it needs; a single-file put stops with remote_directory_missing when the destination directory does not exist. A newly created file gets the server's default permissions (its umask); a replaced file keeps its own.

Recursive downloads default to a safety budget of 64 levels below the selected root, 10,000 files and directories in total, and 1,024 MiB of file data. If a limit is reached, sshc stops before transferring anything. For an intentionally larger tree, raise the per-run limit with --max-depth (up to 256), --max-entries (up to 1,000,000), or --max-total-size (MiB, up to 8 TiB). These options apply only to get --recursive.

In an interactive terminal, sshc sftp get displays one progress bar for each SFTP connection while the engine prepares the remote file. A split transfer therefore shows one line per connection, while a non-split transfer shows one. Progress is suppressed for --json and non-interactive output so automation remains clean.

Existing files are never overwritten implicitly. --overwrite shows one confirmation before replacing them; add --yes only when automation must skip that confirmation. Use --skip-existing to preserve existing files or --dry-run to inspect the plan without changing anything. With --json, stdout contains one JSON result while progress remains on stderr. Pressing Ctrl+C also cancels the remote temporary upload.

Serial / Telnet

sh
sshc serial
sshc serial /dev/ttyUSB0 --baud 9600
sshc telnet console.example:23

Press Ctrl+] to leave an interactive Serial or Telnet connection. Telnet neither encrypts the connection nor authenticates the server.

Terminal control

Inspect, create, and control terminals owned by the running engine.

sh
sshc terminal list --json
sshc terminal create ssh bastion --json
sshc terminal create shell --json
sshc terminal show <session-id> --json
sshc terminal read <session-id> --cursor 0 --limit 4096 --json
sshc terminal send <session-id> --text 'uptime' --json
sshc terminal send <session-id> --text 'partial input' --no-enter
sshc terminal wait <session-id> --for connected --timeout 30s --json
sshc terminal rename <session-id> deploy
sshc terminal close <session-id>

create shell opens a local shell on the engine host. send appends Enter (CR) by default; --no-enter sends the text as is.

read returns a scrollback cursor and warns when an older position has already been discarded. send checks the current process generation to avoid sending to a replacement process.