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)
Published to PyPI as cloudagent-daemon.
Requires Python 3.12+ and Claude Code CLI on PATH.
# One-shot run (no persistent install)
uvx cloudagent-daemon start --server-url https://api.cloudagent.chat --api-key sk_machine_***
# Persistent install — install + start chained with && (single line)
uv tool install cloudagent-daemon && cloudagent-daemon start --server-url https://api.cloudagent.chat --api-key sk_machine_***
# Or via pipx
pipx install cloudagent-daemon
To upgrade later:
uv tool upgrade cloudagent-daemon
# or
pipx upgrade cloudagent-daemon
Developer install (from source)
Contributors working off the cloudagent repo can install the unreleased dev
tip directly from the cy branch — requires SSH access to the codeup mirror:
uv tool install --from "git+ssh://git@codeup.aliyun.com:/69bd0a4d29ad98af4065ce71/cloudagent.git@cy#subdirectory=daemon_cli" cloudagent-daemon
Or editable install for local hacking:
pip install -e ./daemon_cli
Quick start
-
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_keyfrom the response — it starts withsk_machine_and is shown only once. -
Login:
cloudagent-daemon login --server https://api.cloudagent.chat # paste the sk_machine_*** key when prompted
-
Register a local agent (the agent must already exist in cloudagent with
runtime=local_daemonandhost_machine_id=<your host>):cloudagent-daemon agent register --agent-id agent_01HXX --name Frontend
-
Start the daemon:
cloudagent-daemon start & cloudagent-daemon status
You can also use a process manager like
launchd(macOS) orsystemd(Linux) — see "Running as a service" below. -
From the cloudagent UI / API: send a message to the agent. The daemon will spawn
claudeto 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— thesk_machine_***key was revoked. Create a new one in the cloudagent UI (host machine settings).daemon not runningafterstart &— check the log file. Common causes: config missing (loginfirst), backend unreachable, no claude binary on PATH.claude: command not found— install Claude Code: see https://claude.ai/codeagent_status: crashedrepeatedly — check~/.cloudagent/agents/<id>/.meta/last-spawn.jsonfor 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cloudagent_daemon-0.2.5.tar.gz.
File metadata
- Download URL: cloudagent_daemon-0.2.5.tar.gz
- Upload date:
- Size: 138.7 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70bd286292bfc74db08fea66d081529e959e14561b4554eebdaec9a6871fe316
|
|
| MD5 |
e5fa6a445519e0c23a8547f1ceb3e857
|
|
| BLAKE2b-256 |
c702c888efb28b7ea6e11c514bb9662961abe3809037c818be9aae52535c5f36
|
File details
Details for the file cloudagent_daemon-0.2.5-py3-none-any.whl.
File metadata
- Download URL: cloudagent_daemon-0.2.5-py3-none-any.whl
- Upload date:
- Size: 116.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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8cd42f8e7d48d2aaddd015f22a927011fac5756252487acc644650c629e5cb49
|
|
| MD5 |
1164c0125183d94b69b5cc19528e88c1
|
|
| BLAKE2b-256 |
2cf1e902b2cd2b618c28dd4bf974c45c46db8a0d632c920e99ac0c28c3533f5d
|