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.statusso 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 --versionSee Install the CLI for Homebrew and manual options.
2. Pair the machine
cmdop registerThis 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-prodSkips 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 --foregroundBackground (the normal mode):
cmdop agent start
cmdop agent statusVerdict 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 restart4. Install a service unit
To survive reboots:
cmdop service installBehavior per platform:
| Platform | Unit |
|---|---|
| Linux | systemd user unit at ~/.config/systemd/user/cmdop.service, loginctl enable-linger <user> so it runs without an active session. |
| macOS | launchd LaunchAgent at ~/Library/LaunchAgents/com.cmdop.agent.plist. |
| Windows | Service registered as cmdop-agent. |
System-wide install (Linux only, run as root):
sudo cmdop service install --systemThat 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 # systemUseful 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 daemonSee 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 applyFor unattended hosts you can configure the schedule:
cmdop update schedule --auto-applyThat 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
| Path | What |
|---|---|
~/.cmdop/daemon.status | JSON status (connected, session, version, pid). |
~/.cmdop/cmdop.pid | Per-euid PID file. |
Linux: ~/.cache/cmdop/logs/cmdop.log | Daemon log (size-rotated by lumberjack). |
macOS: ~/Library/Logs/cmdop/cmdop.log | Same. |
~/<log-dir>/audit.log | Permission-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 linesMultiple 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 statusRun it from cron or a systemd timer.
Troubleshooting
cmdop registernever 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 -fwill say which. cmdop service installreports “no init system found”. The host is missing systemd / launchd. Runcmdop agent startfrom a process supervisor (supervisord, runit) instead.