Skip to Content

Agent Daemon

cmdop agent is the long-lived background process that holds an outbound gRPC stream to the relay. Without it, this machine is invisible to other machines, the desktop, and the web cabinet.

The daemon is what makes a machine reachable. CLI invocations like cmdop chat or cmdop connect are ephemeral clients that attach to the local daemon over a Unix socket (~/.cmdop/local.sock on Unix; named pipe on Windows).

Why a daemon?

cmdop machines stay “online” by holding an outbound gRPC stream to the relay. The daemon owns that stream. When the daemon is down, the machine goes offline approximately 90 seconds later (server-side heartbeat TTL).

The daemon also owns:

  • The local SDK gRPC server (~/.cmdop/local.sock) that CLI/desktop/SDK clients attach to
  • The OAuth token refresher (rotates tokens about 5 minutes before expiry)
  • The trigger scheduler (cron-like agent tasks)
  • Optional MCP server (--with-mcp) for Claude Desktop / Cursor integration

Start, stop, restart, status

cmdop agent start # background daemon cmdop agent start --foreground # for debugging — attaches to current TTY cmdop agent start --with-mcp # also expose MCP server cmdop agent start --no-power-blocker # don't prevent system sleep on laptops cmdop agent stop # graceful; marks the machine offline immediately cmdop agent restart # pick up new binary or config cmdop agent status # ONLINE / DEGRADED / STARTING

Top-level shortcuts: cmdop start, cmdop stop, cmdop restart, cmdop status — same effect.

Status verdicts

cmdop agent status reads ~/.cmdop/daemon.status (JSON) and renders a verdict:

  • ONLINE — relay stream is up; status file fresh (less than 30s old)
  • DEGRADED — process alive, but status file is stale, or the relay is reconnecting
  • STARTING — process running, status file present, but connected_at not yet populated

Example output:

$ cmdop agent status Verdict: ONLINE PID: 12345 Hostname: vps-audi Workspace: acme-prod Mode: prod Version: v1.2.0 Connected: 2026-04-27T10:15:30Z (4h23m) Updated: 1.2s ago

The UpdatedAt field is bumped on every connection event and on every successful heartbeat — that prevents idle-but-healthy connections being flagged DEGRADED.

Logs

cmdop logs # last 200 lines cmdop logs -n 1000 # last 1000 lines cmdop logs -f # follow (tail -f) cmdop logs --raw # no formatting cmdop agent logs # same thing under the agent subtree

Log files (per platform):

PlatformPath
macOS~/Library/Logs/cmdop/cmdop.log
Linux~/.cmdop/logs/cmdop.log
Windows%APPDATA%\cmdop\logs\cmdop.log

Session boundaries are marked with === DAEMON SESSION START === (grep-friendly). Logs are size-rotated by lumberjack — they accumulate across restarts rather than being truncated on every start.

Mode (dev vs prod)

Each cmdop installation can run against the production cluster or a developer cluster. Tokens, workspaces, and endpoints are stored separately per mode.

cmdop mode # show current cmdop mode dev cmdop mode prod cmdop mode toggle

Token storage path follows mode: ~/.cmdop/token_prod.json vs ~/.cmdop/token_dev.json. The daemon reloads on mode switch. See ./mode for the standalone reference.

Monitor

cmdop monitor opens a live TUI showing daemon health: connection state, recent RPC calls, in-flight sessions, recent permission decisions, and the last few log lines. Quit with q.

cmdop monitor

See ./monitor for the standalone reference.

—with-mcp flag

Adding --with-mcp to cmdop agent start exposes an MCP (Model Context Protocol) server bound to the daemon. This lets Claude Desktop, Cursor, or other MCP hosts discover cmdop’s tools (terminal, files, agent) without an extra process. Off by default — it adds attack surface.

cmdop agent start --with-mcp

For per-invocation stdio MCP without a long-lived server, see ./mcp.

Cross-user warning

Two daemons can run on the same host under different UIDs (e.g., your normal user and root). cmdop does not lock host-wide because legitimate multi-user setups exist (a shared VM with multiple OAuth identities). On startup, cmdop prints a Note: if it detects another agent under a different UID. Server-side enforcement of “one OAuth identity = one active session” is the real guard.

If you run sudo cmdop agent start after starting one as your normal user, you will have two daemons. The most common reason this happens accidentally is sudo cmdop update apply — see ./update for the recommended split.

Clean shutdown

cmdop agent stop sends SIGTERM to the daemon. Before exit, the daemon makes a 3-second best-effort RPC to mark this machine offline immediately. UI pickers, TUI badges, and machine lists flip right away — without this, a stopped daemon would linger as a “ghost” entry until the 90-second heartbeat TTL expires.

Last updated on