Skip to main content

Local daemon for cloudagent — bridges Claude Code subprocesses to the cloudagent backend over WebSocket.

Project description

cloudagent-daemon

Local daemon for cloudagent — runs on user's machine, bridges Claude Code subprocesses to the cloudagent backend so that agents can work locally with your machine's filesystem and tools.

Architecture: spawn-on-message model — daemon receives a deliver frame over WebSocket, spawns claude --resume <session_id>, claude uses an MCP server (also embedded in this daemon) to send_message / list_messages back to the backend, and exits when its work is done.

Quick start (no clone)

The fastest way to run cloudagent-daemon, slock-style:

Each command below is a SINGLE LINE — copy the whole line as-is. Multi-line snippets with \ continuations are fragile across copy-paste (some terminals / web <pre> blocks drop the trailing \ and break the command into separate statements).

Tag-pinned releases. The @daemon-vX.Y.Z ref below points at a frozen daemon release (annotated git tag). To upgrade later, re-run the same command with the latest tag — see git ls-remote --tags origin "daemon-v*" on the cloudagent repo, or the releases list. Don't replace the tag with a branch name (e.g. cy / m5); branches move and can drag in unrelated work-in-progress.

# One-shot run (no install) — single line
uvx --from "git+ssh://git@codeup.aliyun.com:/69bd0a4d29ad98af4065ce71/cloudagent.git@daemon-v0.2.1#subdirectory=daemon_cli" cloudagent-daemon start --server-url https://api-fr.cloudagent.chat --api-key sk_machine_***
# Or install persistently — single line, install + start chained with &&
uv tool install --from "git+ssh://git@codeup.aliyun.com:/69bd0a4d29ad98af4065ce71/cloudagent.git@daemon-v0.2.1#subdirectory=daemon_cli" cloudagent-daemon && cloudagent-daemon start --server-url https://api-fr.cloudagent.chat --api-key sk_machine_***

To upgrade an existing install to the newest tag (forces re-resolve of the git ref so a moved tag wouldn't silently stick on the old commit anyway — but tags are immutable here, so the bump in the URL is the real signal):

uv tool install --reinstall --force --from "git+ssh://git@codeup.aliyun.com:/69bd0a4d29ad98af4065ce71/cloudagent.git@daemon-v0.2.1#subdirectory=daemon_cli" cloudagent-daemon

Once published to PyPI, this becomes:

uvx cloudagent-daemon start --server-url https://api-fr.cloudagent.chat --api-key sk_machine_***
# or
pipx install cloudagent-daemon

Install

Requires Python 3.12+ and Claude Code CLI installed.

pip install -e ./daemon_cli
# or after release:
# pipx install cloudagent-daemon

Quick start

  1. Create a host machine in the cloudagent UI (or via REST):

    curl -X POST https://api.cloudagent.chat/v1/host-machines \
      -H "Authorization: Bearer <your_user_jwt>" \
      -H "Content-Type: application/json" \
      -d '{"name":"my-mac","hostname":"mbp.local","os":"darwin","daemon_version":"0.1.0"}'
    

    Capture the raw_key from the response — it starts with sk_machine_ and is shown only once.

  2. Login:

    cloudagent-daemon login --server https://api.cloudagent.chat
    # paste the sk_machine_*** key when prompted
    
  3. Register a local agent (the agent must already exist in cloudagent with runtime=local_daemon and host_machine_id=<your host>):

    cloudagent-daemon agent register --agent-id agent_01HXX --name Frontend
    
  4. Start the daemon:

    cloudagent-daemon start &
    cloudagent-daemon status
    

    You can also use a process manager like launchd (macOS) or systemd (Linux) — see "Running as a service" below.

  5. From the cloudagent UI / API: send a message to the agent. The daemon will spawn claude to handle it; check ~/.cloudagent/daemon/logs/ for traces.

One-shot mode

For ephemeral runs (CI / debug / quick demo), pass server + key inline — no login step required and nothing is written to ~/.cloudagent/:

cloudagent-daemon start \
  --server-url https://api.cloudagent.chat \
  --api-key sk_machine_***

# Output:
# Detected runtimes:
#   ✓ claude_code 2.1.137  (/opt/homebrew/bin/claude)
# Connecting to https://api.cloudagent.chat as host host_01HXX...

--server-url and --api-key must be passed together; passing one without the other exits with code 2. The daemon stops on Ctrl-C / SIGTERM and leaves no state behind. For persistent setups, use login once + start after.

Layout

~/.cloudagent/
├── daemon/
│   ├── config.json              # server URL + machine API key + host_id
│   ├── state.json               # last_seq + processed message IDs (for dedup)
│   ├── daemon.pid               # PID of running daemon
│   ├── bridge.sock              # unix socket for MCP bridge IPC
│   └── logs/
└── agents/
    └── <agent_id>/
        ├── MEMORY.md            # agent's long-term memory
        ├── notes/               # agent-managed
        ├── workspace/           # agent's working directory
        └── .meta/               # daemon-managed (identity, mcp config, etc.)

Commands

Command Description
cloudagent-daemon login --server URL Auth + persist machine key
cloudagent-daemon start Run the daemon (foreground)
cloudagent-daemon status Print PID + connection info
cloudagent-daemon stop Send SIGTERM, wait for clean exit
cloudagent-daemon install-service Install + start as launchd / systemd user service (auto-restart on crash, auto-start at login)
cloudagent-daemon uninstall-service Stop + remove the launchd / systemd service unit
cloudagent-daemon agent register --agent-id ID Create local workspace
cloudagent-daemon agent unregister --agent-id ID Archive workspace

Logs

~/.cloudagent/daemon/logs/daemon-YYYY-MM-DD.log. Tail with:

tail -F ~/.cloudagent/daemon/logs/daemon-*.log

Troubleshooting

  • Login failed: 401 — the sk_machine_*** key was revoked. Create a new one in the cloudagent UI (host machine settings).
  • daemon not running after start & — check the log file. Common causes: config missing (login first), backend unreachable, no claude binary on PATH.
  • claude: command not found — install Claude Code: see https://claude.ai/code
  • agent_status: crashed repeatedly — check ~/.cloudagent/agents/<id>/.meta/last-spawn.json for the stderr tail. Common causes: bad MCP config, claude binary version mismatch, agent's cwd doesn't exist.
  • Backpressure dropped — your daemon was offline for too long; the cloudagent backend dropped queued messages past 100k.

Running as a service

The daemon ships with install-service / uninstall-service commands that generate and load a launchd (macOS) or systemd (Linux) user unit configured to auto-restart on crash (KeepAlive / Restart=always) and auto-start at login. This is the commercial-grade default — the daemon never self-exits unless you explicitly run uninstall-service (or stop it via the OS).

macOS / Linux

# After login (server URL + key persisted in ~/.cloudagent/daemon/config.json):
cloudagent-daemon login --server https://api.cloudagent.chat --api-key sk_machine_***
cloudagent-daemon install-service

# Or one-shot — embed creds directly in the unit file:
cloudagent-daemon install-service \
  --server-url https://api.cloudagent.chat \
  --api-key sk_machine_*** \
  --insecure   # only if your server uses a self-signed cert

The command writes:

  • macOS: ~/Library/LaunchAgents/chat.cloudagent.daemon.plist (KeepAlive=true)
  • Linux: ~/.config/systemd/user/cloudagent-daemon.service (Restart=always, RestartSec=5)

…then bootstraps + kickstarts (macOS) / daemon-reload + enable --now (Linux). Logs:

# macOS
tail -F ~/.cloudagent/daemon/logs/launchd.{out,err}.log

# Linux
journalctl --user -u cloudagent-daemon -f

To remove:

cloudagent-daemon uninstall-service

Multi-profile (managing multiple backends)

You can register the same machine with several cloudagent backends (prod / fr / staging / dev …) by giving each its own --profile <name>. Each profile gets its own service unit, config, socket, workspace, and launchd / systemd label — they coexist on disk and run as independent processes.

# Default profile (no flag) keeps the legacy paths exactly as before:
cloudagent-daemon install-service \
  --server-url https://api.cloudagent.chat --api-key sk_machine_xxx

# Register a second backend under profile "fr":
cloudagent-daemon install-service --profile fr \
  --server-url https://api-fr.cloudagent.chat --api-key sk_machine_yyy --insecure

# Register a third under "staging":
cloudagent-daemon install-service --profile staging \
  --server-url https://api-staging.cloudagent.chat --api-key sk_machine_zzz

Inspect what's installed:

cloudagent-daemon list-profiles
# ● default
#     server:  https://api.cloudagent.chat
#     host_id: host_a1b2c3
#     status:  running pid=12345
# ● fr
#     server:  https://api-fr.cloudagent.chat
#     host_id: host_d4e5f6
#     status:  running pid=12350

All commands take --profile <name> (default is default):

cloudagent-daemon status     --profile fr
cloudagent-daemon doctor     --profile fr
cloudagent-daemon stop       --profile fr
cloudagent-daemon uninstall-service --profile fr
cloudagent-daemon agent register   --profile fr --agent-id a1

Profile names must match [a-z0-9][a-z0-9-]{0,30}. default is reserved.

Per-profile filesystem layout

Resource Default profile Named profile fr
Config / state ~/.cloudagent/daemon/{config,state}.json ~/.cloudagent/daemon/profiles/fr/{config,state}.json
IPC socket ~/.cloudagent/daemon/bridge.sock ~/.cloudagent/daemon/profiles/fr/bridge.sock
Workspace ~/.cloudagent/agents/ ~/.cloudagent/agents-fr/
Logs ~/.cloudagent/daemon/logs/launchd.{out,err}.log ~/.cloudagent/daemon/profiles/fr/logs/launchd.{out,err}.log
launchd label chat.cloudagent.daemon chat.cloudagent.daemon.fr
systemd unit cloudagent-daemon.service cloudagent-daemon-fr.service

The default profile keeps the original paths byte-for-byte — existing installs need no migration. Named profiles only show up after their first install-service --profile <name>.

The active profile pins itself in CLOUDAGENT_DAEMON_PROFILE for any child process the daemon spawns (mcp_bridge, claude subprocesses), so commands you run inside an agent shell pick up the right profile automatically.

Spec

See docs/superpowers/specs/2026-05-08-local-daemon-runtime-design.md.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cloudagent_daemon-0.2.1.tar.gz (136.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cloudagent_daemon-0.2.1-py3-none-any.whl (113.0 kB view details)

Uploaded Python 3

File details

Details for the file cloudagent_daemon-0.2.1.tar.gz.

File metadata

  • Download URL: cloudagent_daemon-0.2.1.tar.gz
  • Upload date:
  • Size: 136.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for cloudagent_daemon-0.2.1.tar.gz
Algorithm Hash digest
SHA256 ba848085d930aef5bcc9871919ebf5a64e207c73651ca3b638860033de73cced
MD5 6e4ed951a30652b4a61301ddb29541e5
BLAKE2b-256 68fcc4533e85a054e89eaad9255dfdc508bf889d322b9753fcab4f092382a666

See more details on using hashes here.

File details

Details for the file cloudagent_daemon-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: cloudagent_daemon-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 113.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for cloudagent_daemon-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1a5d5f4b7f1da3eff20ce1b8bfcb1fc7e57ec1ff19ecacb69753a150a1713453
MD5 81c8c1a383d4cf7f77fe0e9d24fb2627
BLAKE2b-256 f3777b6653b9ed0c28c404b163528ae1713677d06584d2e210e2de9807ae413d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page