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 workspace.
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.