Skip to Content
Tools🖥️ Remote Device

Remote Device

The Remote Device tool lets a DocsGPT agent run shell commands on a machine you control, such as a server, a Raspberry Pi, or your own laptop. You install docsgpt-cli on that machine, run it in host mode, and pair it with your DocsGPT account. The paired device then shows up as a tool you can attach to any agent.

The machine connects outward to DocsGPT, so it works behind NAT or a firewall without opening any inbound ports.

How it works

  1. You run docsgpt-cli host on the target machine. It pairs to your account and keeps a lightweight connection open: it polls while idle and streams while a command is running.
  2. When an agent calls the device’s run_command action, DocsGPT sends the command down to the daemon.
  3. The daemon runs the command locally, streams stdout and stderr back, and the agent uses the output to continue.
  4. Every invocation is recorded in the device’s activity log.

Prerequisites

  • docsgpt-cli installed on the machine you want to control. See the installation instructions : download a binary from the releases page , use Homebrew (brew tap arc53/docsgpt-cli && brew install docsgpt-cli), or build from source.
  • Outbound internet access from that machine to your DocsGPT instance.
  • On the DocsGPT server:
    • Redis reachable at CACHE_REDIS_URL. Pairing and the command broker use it; without it, creating or redeeming a pairing returns 503 redis_unavailable.
    • The API served through the ASGI app (docsgpt.asgi:asgi_app), as docsgpt api, docsgpt dev and the Docker images do. Under flask run, the device command stream GET /api/devices/sessions/<id>/events returns 404, so a device pairs but never receives commands. See ASGI-only features.
    • Optionally, the REMOTE_DEVICE_* settings: the pairing code lifetime, the idle timeout for a device session, how long queued commands and pending invocations are kept, and whether commands must be signed. See the Settings Reference.

The host commands require a docsgpt-cli build with remote-device support. If docsgpt-cli host is not recognized, update to the latest release or build from source.

Pair a device

Pairing uses a short one-time code (a device-code style flow).

  1. In DocsGPT, go to Settings -> Tools, click Add tool, and choose Remote Device.
  2. Give it a name, an optional description (the agent sees this, so describe what the machine is for), and pick an approval mode. DocsGPT then shows a pairing code such as ABCD-WXYZ and the command to run.
  3. On the target machine, run:
    docsgpt-cli host pair --url https://your-docsgpt-instance
    Enter the code when prompted. (Omit --url to use the default cloud instance.) The code is valid for 10 minutes by default (REMOTE_DEVICE_PAIRING_TTL_SECONDS). If it expires, start the pairing again.
  4. The UI switches to “Paired” once the code is redeemed. If you ran the command at a terminal, the CLI then offers to start the daemon or install it as a service.

Run the daemon

Start it in the foreground:

docsgpt-cli host

You will see a startup banner, then periodic “idle” heartbeats. Press Ctrl-C to stop.

To keep it running across reboots, install it as a service:

# Linux (systemd). As root this installs a system service; otherwise a user service. docsgpt-cli host install-service # macOS (launchd). The default is a per-user LaunchAgent that starts on login. docsgpt-cli host install-service # Always-on machine that starts at boot (Linux example): sudo docsgpt-cli host install-service --system --user $USER

Remove the service with docsgpt-cli host uninstall-service.

Approval modes

The approval mode is set per device, either in the pairing form or later on the device’s page under Settings -> Tools. There are two modes:

  • Ask (default): every command pauses for your approval before it runs. You approve it from the chat. You can also choose “approve and don’t ask again” to auto-approve that command pattern in the future.
  • Full access: commands run without asking.

A built-in safety denylist always applies, even in Full access mode. Catastrophic commands (for example rm -rf /, fork bombs, writing directly to a disk device, or git push --force) still pause for explicit approval and cannot be bypassed.

Compound commands are split on operators such as &&, ||, ;, and |, and each part is checked on its own, so a dangerous part cannot be hidden behind a safe one.

Attach to an agent

A paired device behaves like any other tool. Open or create an agent, add the device from the tool picker, and the agent can call its run_command action. The picker shows whether the device is currently online.

If you attach more than one device to an agent, give each a clear description so the agent can pick the right one.

Long commands as background jobs

In a chat, a command that runs longer than the yield window (BACKGROUND_YIELD_SECONDS, 30 by default), or one the agent starts with background=true, becomes a background job. The turn ends, the command keeps running on the machine, and the agent comes back to the conversation with its exit code and output when it ends, as it would for any job. The chat shows a job card with the elapsed time, the latest output line and a Cancel button.

  • How long. A command in the foreground keeps its 600-second cap. With background=true, its timeout_ms may go up to DEVICE_JOB_MAX_SECONDS (an hour by default) and defaults to it. A device job’s lifetime is DEVICE_JOB_MAX_SECONDS from when it was handed off.
  • watch. run_command takes the same watch spec as code_executor: patterns resume the agent when a line matches while the command runs, progress_regex updates the card, and heartbeat_s sends the output printed since the last heartbeat.
  • Approvals are unchanged. The approval mode, the auto-approved patterns and the denylist are applied before the command starts, and an approved command’s clock starts after the approval.
  • When the device goes offline. A device not heard from for 90 seconds counts as offline: the card says Waiting for the device, and the job picks up the output again when the device reconnects. A client that keeps its report (outbox) gets ten minutes past the command’s timeout to send it, instead of two.
  • When the result never arrives. The job ends interrupted (lost), with a note that the command may or may not have run and should be verified before retrying, when the device is revoked, when it is connected but never reports past the command’s own timeout (or never picks the command up), or when the job’s lifetime ends without a report. If the device is connected at the end of the lifetime, the command is stopped and the job fails as timed out.
  • Cancel. A command the device has not picked up yet is taken off its queue and never runs. A running one is sent a cancel; if the device doesn’t confirm within 30 seconds, the job ends cancelled with a note to check the machine. A client that can’t cancel ends the job at once, saying so.

How much of this the machine’s docsgpt-cli supports depends on its version. Clients that send X-Device-Capabilities: cancel,outbox (arc53/DocsGPT-cli#14 ) keep a command’s report until DocsGPT has it, stop a cancelled command and its child processes, and never restart in the middle of a command. Older clients report only if they can reach the server when the command ends, so a report lost on a network drop leaves the job interrupted, and they can’t stop a running command: cancelling then says so at once and asks you to update the CLI.

What the job card can say about a device job besides its status:

  • The device’s client restarted (interrupted). The client crashed or was killed while the command ran and can’t tell how it ended; the command may still be running on the machine, and the card gives its process id. Check before retrying.
  • The device’s client shut down (failed). The client was stopped and stopped the command, which may have partly run.
  • Output was truncated. The device kept at most 1 MiB of unsent output while it couldn’t reach the server and dropped the oldest; the exit code is still exact.
  • This device’s client can’t cancel (cancelled). The command may still be running; update docsgpt-cli.

A client that resends its report numbers every chunk, and DocsGPT keeps each chunk once, so a report sent twice after a lost response never duplicates output.

Scheduled runs and monitor checks keep running commands in the foreground.

Webhook secrets in commands

A command can use a webhook link’s secret without the agent seeing it: the agent writes the link’s secret reference, {{link_secret:REF}}, and the server fills in the value when you approve the command. Such a command always asks for approval, even in Full access mode, and can’t be approved with “don’t ask again”. The activity log records the reference, and any output that echoes the secret shows the reference instead.

Manage a device

Open the device from Settings -> Tools to:

  • See its status (online or offline, with last-seen time), host, OS, and CLI version.
  • Change its name, description, or approval mode.
  • View recent activity (the command audit log).
  • Revoke it.

From the CLI:

docsgpt-cli host status # live status from the server docsgpt-cli host revoke # revoke on the server and clear local state docsgpt-cli host reset # clear local pairing only (leaves the server-side device)

Revoking a device stops its daemon: the next time it checks in it sees the revocation, prints a message, and exits. Under a service manager it will not be restarted.

Security notes

  • The machine connects outward only. No inbound ports are opened.
  • Each device has its own token, stored hashed on the server and revocable at any time.
  • Prefer Ask mode for any machine with sensitive data on it. Use Full access only on machines you are comfortable letting an agent drive unattended, and remember that the denylist is the only automatic guard in that mode.
  • Every command is logged on the server and visible in the device’s activity log.
Last updated on