Skip to main content
ssh_exec runs a shell command on a remote device over Tailscale SSH. It uses the Tailscale hostname directly — no IP addresses, no manual known_hosts management. The server spawns a real ssh process using a dedicated key mounted at /root/.ssh/reacher-key. Windows targets are supported via cmd (default) or powershell. PowerShell commands are automatically encoded as Base64 UTF-16LE before being sent, which prevents quoting and escaping issues.
Tailscale SSH must be explicitly enabled on each target device before this tool can connect. Run sudo tailscale up --ssh on the device to enable it.

Parameters

hostname
string
required
Tailscale hostname of the target device (e.g. "myserver"). Use tailscale_status to list available hostnames.
command
string
required
Shell command to execute on the remote device.
user
string
SSH user to connect as. The schema default is hazem (the project author’s username — you will almost certainly need to override this). Always specify the correct user for your target device, e.g. ubuntu, root, or your own username.
shell
string
Shell to use on Windows targets. Accepted values: cmd or powershell. Defaults to cmd. Ignored on non-Windows hosts.

Return value

success
boolean
true if the command exited with code 0.
hostname
string
The target hostname as provided.
user
string
The SSH user used for the connection.
command
string
The command that was executed.
shell
string
The shell used (cmd or powershell).
stdout
string
Trimmed standard output from the command.
stderr
string
Trimmed standard error output.
exitCode
number
Process exit code. 0 means success.
blocked
boolean
Present and true when the command was blocked by a safety rule. Also includes reason and matched_rule fields.
dry_run
boolean
Present and true when DRY_RUN=true is set. Includes a would_execute field instead of running the command.

Usage examples

{
  "hostname": "homelab",
  "command": "df -h /"
}

Safety considerations

Reacher enforces two optional safety layers configured in reacher.config.yaml:

Command blocklist

ssh.blocked_commands is a list of substrings. If any blocked string appears in the command (case-insensitive), the tool returns immediately with success: false and blocked: true — the SSH connection is never made.
ssh:
  blocked_commands:
    - 'rm -rf'
    - 'shutdown'
    - 'reboot'

Directory allowlist

ssh.allowed_dirs restricts SSH operations to specific paths. The tool parses path tokens from the command (tokens starting with /, ~, or ./) and checks each one against the list. An empty list means no restriction.
ssh:
  allowed_dirs:
    - /home/deploy
    - /var/log/myapp

Dry-run mode

Set DRY_RUN=true to have ssh_exec evaluate safety rules and return a would_execute response without making any SSH connection. Useful for testing configurations.
All tool calls are written to reacher-audit.log with timestamp, arguments, and result. Sensitive keys are stripped automatically.

Common use cases

  • Check logstail, journalctl, cat on log files
  • Inspect processesps, top, htop snapshots
  • Run deployments — trigger deploy scripts, git pull, docker compose up
  • System healthdf, free, uptime, systemctl status
  • File inspection — read configs, check file permissions, list directory contents
Run tailscale_status first to discover available hostnames and verify a device is online before attempting SSH.