How it works
ccr-cloud has two parts: a control plane that you talk to, and one runner per task that runs Claude Code. Everything runs on your own server.
Browser / installed app Discord bot (optional)
│ owner token │ owner's Discord ID
▼ ▼
┌──────────────────────────────────────────────┐
│ control plane (ccr-cloud) │
│ HTTP API · task records · event logs · push │
└──────────────────────────────────────────────┘
▲ runner connects out over a WebSocket
│ (events and commands are acknowledged)
┌──────────┴───────────┐ ┌──────────────────────┐
│ runner → Claude Code │ │ runner → Claude Code │ one per task
│ task workspace │ │ task workspace │
└──────────────────────┘ └──────────────────────┘
#The control plane
The control plane serves the web app and the HTTP API, stores each task's record and an append-only log of everything that happened, and sends notifications. It listens on 127.0.0.1:8787 by default, and every API call needs the owner token.
#Runners
Each task has a runner process. It prepares the workspace, starts Claude Code in headless mode (other agents, such as Codex, aren't supported yet; see #19), and relays Claude's output and permission requests to the control plane. The runner always dials out to the control plane, so a task never needs an open port.
Nothing is lost when a connection drops. Runner events are numbered and resent until the control plane stores them, and your messages and approvals are resent until the runner confirms them. When you reopen the app, it replays the task's log.
#Execution modes
| Host mode (default) | Docker mode | |
|---|---|---|
| Runs Claude Code | As your server user, in tmux | In one container per task |
| Model access | Your server user's Claude login or API config, or optionally a CCR gateway | A Claude Code Router gateway |
| Git credentials | Your server user's SSH keys and helpers | An optional GH_TOKEN |
| Workspaces | A Git worktree per task, or a scratch folder | A volume per task, cloned from a URL |
| Isolation | None beyond separate folders | Non-root container, no capabilities, resource limits |
| Set up with | Getting started | Docker and CCR sessions |
#What a task can access
- Host mode tasks have everything your server user has: files, credentials, cloud permissions and network. A worktree keeps files apart; it isn't a sandbox. Use a dedicated account you trust for coding work.
- Docker mode tasks get only a CCR client key and, if you set it,
GH_TOKEN. Your model provider keys stay in the CCR gateway, and the host's SSH keys and Claude login are never mounted. The agent can readGH_TOKENfrom its shell. - In both modes, the runner's own session token is removed from Claude's environment, so the agent can't act as the runner.
ccr-cloud serves one owner. Don't use it to give untrusted people access to a server.
#Where data lives
Everything is in the data directory, ~/.local/share/ccr-cloud by default: configuration and owner token (server.env), task records and event logs, task workspaces (host/SESSION_ID/), saved projects, push keys and registered devices. Keep it private and back it up.
#Your agreements stay yours
ccr-cloud is software you run. It doesn't host agents or sell model access. You use Claude Code, and any provider behind CCR, under your own agreements with them.