Skip to Content

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

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