Skip to Content
DocsInstallAgent (headless)

Install the Long-Running Agent

For servers, VPSes, and any always-online box (a vps-audi or a build host), CMDOP runs as a long-lived daemon. This page is the headless install path: pair the machine, start the daemon, install a service unit, and let auto-update keep it current.

What “agent” means here

The agent is the daemon — the background cmdop process that:

  • Holds an outbound TLS connection to the relay.
  • Writes ~/.cmdop/daemon.status so other surfaces can read state.
  • Exposes a local gRPC server for the CLI / desktop / SDK to attach.
  • Optionally exposes the MCP server (--with-mcp).

Without the daemon a machine is not online. CLI commands still work for local-only operations.

1. Install the binary

Headless boxes have no GUI; install the CLI:

curl -sSL https://cmdop.com/install.sh | bash cmdop --version

See Install the CLI for Homebrew and manual options.

2. Pair the machine

cmdop register

This is the foreground sign-in flow: it prints a device URL, asks you to complete the OAuth flow in any browser (laptop is fine), and saves credentials to ~/.cmdop/.

For automation:

cmdop register --api-key <WORKSPACE_API_KEY> --workspace acme-prod

Skips the browser flow and stores the key in ~/.cmdop/ssh_workspaces.json (mode 0600).

cmdop register does not start the daemon. It only stores credentials and ensures the machine record exists in the fleet (the --workspace flag keeps its legacy name).

3. Start the daemon

Foreground (handy for debugging):

cmdop agent start --foreground

Background (the normal mode):

cmdop agent start cmdop agent status

Verdict should be ONLINE. If STARTING lingers, cmdop agent logs -f.

Stop with:

cmdop agent stop # marks machine offline immediately (3-second RPC) cmdop agent restart # graceful restart

4. Install a service unit

To survive reboots:

cmdop service install

Behavior per platform:

PlatformUnit
Linuxsystemd user unit at ~/.config/systemd/user/cmdop.service, loginctl enable-linger <user> so it runs without an active session.
macOSlaunchd LaunchAgent at ~/Library/LaunchAgents/com.cmdop.agent.plist.
WindowsService registered as cmdop-agent.

System-wide install (Linux only, run as root):

sudo cmdop service install --system

That writes /etc/systemd/system/cmdop@<user>.service and runs the daemon under that user without lingering.

Uninstall:

cmdop service uninstall # user sudo cmdop service uninstall --system # system

Useful flags

cmdop agent start --mode strict # apply a permission mode at startup cmdop agent start --no-power-blocker # do not prevent system sleep cmdop agent start --with-mcp # also expose MCP server in the daemon

See permissions concept for --mode and the MCP overview for --with-mcp.

Auto-update

The daemon polls for releases daily and stages binaries to ~/.cache/cmdop/updates/. Apply with:

cmdop update apply

For unattended hosts you can configure the schedule:

cmdop update schedule --auto-apply

That makes the daemon apply staged updates on its own (it will re-exec the new binary).

sudo cmdop update apply after a non-sudo cmdop update fails because home directories differ. Either run both as the same user, or use --cache-dir to point both at the same location.

Logs and observability

PathWhat
~/.cmdop/daemon.statusJSON status (connected, session, version, pid).
~/.cmdop/cmdop.pidPer-euid PID file.
Linux: ~/.cache/cmdop/logs/cmdop.logDaemon log (size-rotated by lumberjack).
macOS: ~/Library/Logs/cmdop/cmdop.logSame.
~/<log-dir>/audit.logPermission-gate audit log.

Each daemon session is marked with a grep-friendly line: === DAEMON SESSION START ===.

cmdop agent logs -f # tail cmdop agent logs --tail 500 # last 500 lines

Multiple daemons on one host

PID files are per-euid, not host-wide. Two daemons under different users (e.g., mark and root) are legitimate — different OAuth identities, different agent records.

If cmdop agent start detects another daemon under a different uid, it prints a hint to stderr but does not block. Server-side enforcement of “one token, one active session” is the real guard.

Suggested security baseline for a server

# Lock the gate cmdop permissions mode strict # Allow read-only inspection cmdop permissions allow 'read_logs' cmdop permissions allow 'read_file(/var/log/**)' cmdop permissions allow 'execute_command(uptime)' cmdop permissions allow 'execute_command(systemctl status *)' # Tighten audit cmdop permissions audit --tail 50 -f &

See Agent Permissions guide for per-environment patterns.

Updating from a script

#!/usr/bin/env bash set -euo pipefail cmdop update check && cmdop update apply || true cmdop agent restart cmdop agent status

Run it from cron or a systemd timer.

Troubleshooting

  • cmdop register never gets the token. Browser flow stalled; copy the device URL to a working browser and resubmit.
  • Daemon DEGRADED. Process alive, status file stale or relay disconnected. cmdop agent logs -f will say which.
  • cmdop service install reports “no init system found”. The host is missing systemd / launchd. Run cmdop agent start from a process supervisor (supervisord, runit) instead.
Last updated on