remote_shell
Run commands on one remote host in a persistent shell session so working directory, environment variables, and activated virtualenvs carry over between calls.
Instructions
Run a command (or a sequence) on ONE remote host in a persistent shell session: cwd and environment (cd / export / venv activation) survive across calls. Use it only when you need that continuity — otherwise remote_exec is faster (no session setup) and can target many hosts; for a long task to background and poll, use remote_job.
Pick one:
command="pytest" → {host, session_id, command, exit_code, output, duration_s}. ONE command per call is the preferred shape: the session PERSISTS across separate calls, so cwd / exports / venv from an earlier call still apply to the next — you keep step-by-step continuity AND get to read each step's real output before deciding the next.
commands=["cd /app","source .venv/bin/activate","pytest"] → runs the sequence in order in ONE call (same session). Reach for it ONLY for a fixed sequence you do NOT need to inspect between steps; you can't judge one step's output before the next runs. Returns {host, session_id, results:[…]}; stop_on_error=True (default) halts at the first failure and adds stopped_at.
Behavior:
bash or zsh; an unknown login shell falls back to bash (if bash is missing the call is refused — use remote_exec).
Output is the COMBINED stdout+stderr stream (use remote_exec when you need them split). Oversize output is capped and flagged truncated=true.
A command that wedges on an interactive prompt (sudo password, ssh first-connect, passphrase, …) is auto-aborted, returning exit_code -1 + error:"interactive_prompt_blocked" + session_preserved:true — cwd/env survive, so the next command runs straight away.
★ No sudo or secret injection here (both are one-shot by nature): to run as root use remote_exec(use_sudo=True); for a command needing a secret use remote_exec(secrets=[…]).
timeout (per command, seconds; REQUIRED — no default): the call is held open until the command exits or timeout elapses. Keepalive pings stop the client aborting a hung call, so timeout is your real cut-off — pass a SMALL one for an exploratory / re-runnable command (e.g. 10–30) to fail fast, raising it only for a genuinely slow but bounded command. Hard ceiling (PORTAL_MAX_TIMEOUT, default 300s): a request above it is refused — use remote_job for a long task.
⚠️ By convention, write operations should target /tmp/ on the remote unless the user approved another path (not enforced here).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| host | Yes | ||
| command | No | ||
| timeout | Yes | ||
| commands | No | ||
| stop_on_error | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |