ssh_tail
Retrieve incremental output from a running SSH job started by ssh_spawn. Uses a cursor to fetch only new lines, optionally waiting for more output. Returns status when job completes.
Instructions
Stream incremental output from a job started by ssh_spawn. Given a monotonic cursor 'since_line_no', return every buffered line with line_no > cursor (up to max_lines). If wait_ms > 0 and nothing new is available, block up to wait_ms milliseconds for new output. Returns still_running=False and exit_status when the job has finished.
Canonical polling loop (use this): cursor = 0 while True: r = ssh_tail(job_id, since_line_no=cursor, wait_ms=5000, max_lines=500, stream='both') for ln in r['lines']: show_to_user(ln) cursor = r['last_line_no'] if not r['still_running']: break
If r['buffer_truncated'] is True, older output was evicted from the ring buffer before you read it — either live with the gap or increase limits.ring_buffer_lines on the server. This tool does NOT open a new SSH connection per call; all data comes from in-memory buffers maintained by the spawn's reader threads.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | The id returned by ``ssh_spawn``. | |
| since_line_no | No | Your cursor. 0 on the first call; on each subsequent call, pass the ``last_line_no`` from the previous response. Negative values are clamped to 0. | |
| wait_ms | No | If > 0 and no new lines are immediately available, block up to this many milliseconds waiting. Capped internally at 60000 ms so a misbehaving caller can't hold an MCP channel for 10 minutes. Values below 10 ms are treated as 0 (no wait) because condvar wakeup latency eats them anyway. | |
| max_lines | No | Maximum lines to return in this response. Capped internally at 10000. The cap is there to keep a single response payload small — if the buffer has more lines pending, just poll again with an updated cursor. | |
| stream | No | ``"stdout"``, ``"stderr"``, or ``"both"`` (default). "both" merges the two streams by line_no, which gives the true interleaved order a human would see. | both |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||