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 CodeAs your server user, in tmuxIn one container per task
Model accessYour server user's Claude login or API config, or optionally a CCR gatewayA Claude Code Router gateway
Git credentialsYour server user's SSH keys and helpersAn optional GH_TOKEN
WorkspacesA Git worktree per task, or a scratch folderA volume per task, cloned from a URL
IsolationNone beyond separate foldersNon-root container, no capabilities, resource limits
Set up withGetting startedDocker 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 read GH_TOKEN from 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.

#Next steps

Edit this page on GitHub ↗