Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

cps

cps gives you a hardware-isolated Linux microVM that boots instantly: root over SSH, a persistent disk, and a public HTTPS ingress — all driven from a single CLI. Machines are ephemeral by default, with automatic resource reclamation: spin one up, do your work, forget it — the TTL cleans up after you.

Under the hood it’s Firecracker + jailer: every machine is a real VM with its own kernel, isolated at the hardware level — not a container sharing a kernel with its neighbours.

Where to next

  • Getting started — from install to a running machine in a couple of minutes.
  • CLI reference — every command: new, ssh, expose, snapshot, backup, and more.
  • API & authentication — tokens, org-scoping, and the REST API for automation beyond the CLI.

What a microVM gives you

  • Instant start — boots in ~a second, not the tens of seconds of a full VM.
  • Strong isolation — a dedicated kernel per machine (Firecracker + jailer); guest-to-guest networking is isolated. Not a “shared-kernel container”.
  • Real Linux — root, arbitrary packages, syscalls, your own disk. Not a stripped-down sandbox.
  • Persistent & portable — the disk survives restarts; snapshots/backups restore on another host.
  • Ephemeral by default — a TTL reclaims resources automatically; persistent machines are opt-in (--ttl 0).

This is an invite-only alpha. Questions, bugs, ideas → the community chat @cps_run on Telegram.

Getting started

The path from zero to a running machine. You need an access token — the cps team issues these (invite-only alpha).

1. Install the CLI

curl -fsSL https://cps.run/install.sh | sh

The script downloads the cps binary for your OS/arch and installs it into ~/.local/bin. If that directory isn’t on your PATH:

export PATH="$HOME/.local/bin:$PATH"

Supported: Linux and macOS, x86_64 or arm64. Verify:

cps version

2. Log in

cps login --token <your-token>

The API defaults to https://cps.run. Select your org’s project:

cps project list          # shows the "default" project created for your org
cps project use <prj_id>  # from the list above

3. Launch a machine

cps new ubuntu --name dev --start --wait

Defaults: 1 vCPU, 512 MiB RAM, a 4 GiB disk, and a 24h TTL (the machine auto-deletes after a day so nothing is left running by accident). Override with --cpu, --ram 2G, --disk 10G, --ttl 2h. Use --ttl 0 for a persistent machine that is never auto-deleted.

4. Use it

cps ssh dev                       # root shell over SSH
cps exec dev -- uname -a          # run a one-off command
cps cp ./file dev:/root/          # copy a file in
cps expose dev 8080               # publish a port over public HTTPS
cps metrics dev                   # live CPU / memory
cps ps                            # list your machines

cps expose returns a public URL like https://rte-….cps.run that proxies to the given port inside the machine.

5. Snapshots and backups

The machine must be stopped (cps stop):

cps stop dev
cps snapshot create dev --name base --wait     # fast restore point
cps backup create dev --name daily --wait      # durable off-host copy (S3)
cps snapshot restore <snap> --name dev2 --start --wait

A snapshot is a fast disk image (a restore point). A backup is a durable copy in off-host storage (S3) — it survives host loss and restores on any host in the fleet.

6. Clean up

cps rm dev --yes

Limits & etiquette (alpha)

  • Your org has a resource quota and a machine-count cap. cps will tell you if you hit them.
  • Machines are hardware-isolated (Firecracker + jailer) and cannot see each other.
  • Please don’t use machines for abuse (spam, scanning, mining). This is a private alpha.
  • Questions, bugs, ideas → the @cps_run chat on Telegram.

Troubleshooting

  • cps ssh hangs → Ctrl-C and retry; report persistent hangs in the chat.
  • 401/403 → your token expired or you’re pointed at the wrong project (cps project use).
  • cps whoami shows who you’re authenticated as.

CLI reference

Every command runs in the context of the active project (see cps project use) and requires login (cps login). The global --json flag emits machine-readable JSON instead of tables.

Environment overrides config: CPS_API_URL, CPS_TOKEN, CPS_PROJECT_ID.

Authentication & context

CommandPurpose
cps login --token <t>Save the token and API URL to config.
cps whoamiShow the current user/org.
cps versionCLI version.
cps project listProjects in your org.
cps project use <prj_id>Make a project active.
cps project create <name>Create a project.

Machines

cps new <image> --name <n> [--start] [--wait] [options]
FlagDefaultDescription
--cpu <n>1vCPUs.
--ram <n>512 (MiB)Memory; accepts 2G, 512M.
--disk <n>4Disk in GiB.
--ttl <d>24hLifetime; 0 means persistent. Accepts 2h, 30m, 7d.
--ssh-key <path>—Public key to inject.
--region <r>—Preferred region/host.
--require <label>—Required host labels (repeatable).
--start—Start right after create.
--wait—Block until ready.
CommandPurpose
cps ps [--all]List machines (--all includes deleted).
cps status <m>Detailed machine status.
cps start <m> / cps stop <m>Start / stop.
cps rm <m> --yesDelete a machine.
cps wait <m> --timeout <s>Block until ready.
cps clone <src> --name <n> [--start] [--wait]Clone a machine.
cps console <m>Attach to the serial console.

Access & files

CommandPurpose
cps ssh <m> [--identity <key>] [-- <cmd>]Root shell over SSH (via tunnel); with a command, run and exit.
cps exec <m> [--timeout <s>] -- <cmd>One-off command, returns stdout/stderr.
cps cp [--recursive] <src> <dst>Copy files (m:/path is a path inside the machine).
cps ssh-proxy <project> <m>Print a ProxyCommand for native ssh/scp.

Publishing ports (ingress)

CommandPurpose
cps expose <m> <port>Public HTTPS URL to an internal port; prints https://rte-….cps.run.
cps routesActive routes.
cps unexpose <selector>Remove a route.

Snapshots & backups

The machine must be stopped. A snapshot is a fast restore point; a backup is a durable copy in S3 (portable across hosts).

CommandPurpose
cps snapshot create <m> --name <n> [--wait]Take a snapshot.
cps snapshot list [<m>]List snapshots.
cps snapshot show <snap>Details.
cps snapshot restore <snap> --name <n> [--start] [--wait]Restore into a new machine.
cps snapshot rm <snap> [--yes]Delete.
cps backup create <m> --name <n> [--wait]Create a backup.
cps backup list [<m>] / show <b> / restore <b> … / rm <b> [--yes]Manage backups.

Metrics

CommandPurpose
cps metrics <m>Current CPU / memory.
cps metrics <m> --history [--window <s>]History over a window (from ClickHouse).
cps operationsRecent async operations in the project.

Secrets

Project secrets are encrypted at rest and available to the project’s machines.

CommandPurpose
cps secret set KEY=VALUE …Set secrets.
cps secret listSecret names (no values).
cps secret rm <name>Delete.

Tokens

CommandPurpose
cps token create [--name <n>] [--ttl <d>]Issue a token (the secret is shown once).
cps token listYour tokens.
cps token rm <token_id>Revoke.

Images

An image registry backed by S3; hosts pull an image on demand (see also the API).

CommandPurpose
cps image push <id> --kernel <vmlinux> --rootfs <ext4> [--name] [--version] [--arch] [--boot-args]Upload and register an image.
cps image listAvailable images.
cps image rm <id> [--yes]Remove an image from the registry and S3.

Administration

Requires an admin token. Not available to regular users.

CommandPurpose
cps admin org create <name> --cpu --ram --disk --max-machinesCreate an org with a quota (auto-creates a default project).
cps admin org list / usage <org>List orgs / consumption vs quota.
cps admin org quota set <org> …Change a quota.
cps admin user create <org> --name [--email] / user rm <user>Users.
cps admin token issue <org> <user> [--name] [--ttl]Issue a user token.
cps admin hosts / cps admin host <inspect|drain|cordon|uncordon|tag> <host>Fleet management.

API & authentication

The CLI is a thin wrapper over the control-plane REST API. You can call the same API directly for automation.

Base URL & authentication

  • Base URL: https://cps.run (override with CPS_API_URL).
  • Auth: the Authorization: Bearer <token> header. Issue a token with cps token create (or, as an admin, cps admin token issue).
  • Scoping: a token is bound to your organization; you can only see and mutate your org’s resources.
  • A token is a secret: shown once, keep it out of git, revoke with cps token rm.

Liveness check (no auth):

curl -s https://cps.run/healthz
# {"status":"ok"}

Who am I:

curl -s https://cps.run/v1/whoami -H "Authorization: Bearer $CPS_TOKEN"

Resource model

org ──┬── project ──┬── machine ──┬── snapshot
      │             │             └── backup
      │             └── route (ingress) / secret
      └── (quota: cpu / ram / disk / max-machines)

Almost everything is project-scoped and lives under /v1/projects/{project_id}/…. The default project is prj_default.

Core endpoints

Method + pathPurpose
GET /v1/whoamiCurrent principal.
GET /v1/projectsOrg projects.
GET /v1/projects/{p}/machinesList machines (?include_deleted=true).
POST /v1/projects/{p}/machinesCreate a machine (JSON body: image, resources, ttl…).
POST /v1/projects/{p}/machines/{m}:start | :stopStart / stop (async operation).
DELETE /v1/projects/{p}/machines/{m}Delete.
GET /v1/projects/{p}/operations/{op}Async operation status.
GET | POST /v1/projects/{p}/snapshotsList / create snapshots.
GET | POST /v1/projects/{p}/backupsList / create backups.
GET | POST /v1/projects/{p}/routesIngress routes (expose).
GET | POST | DELETE /v1/tokensManage tokens.
GET | POST /v1/imagesImage registry.

Async operations

Mutating actions (create/start/stop/snapshot/backup/restore) return an operation and run asynchronously. Poll its status to wait for completion:

# create a machine → take operation_id from the response, then poll:
curl -s https://cps.run/v1/projects/prj_default/operations/$OP \
  -H "Authorization: Bearer $CPS_TOKEN"
# status moves pending → running → succeeded | failed

The CLI does this for you with --wait.

Example: list machines

curl -s https://cps.run/v1/projects/prj_default/machines \
  -H "Authorization: Bearer $CPS_TOKEN" | jq .

Error codes

CodeMeaning
401Missing/invalid token.
403Token valid, but no access to the resource (another org / an admin path).
404Resource not found in your scope.
409State conflict (e.g. an action on a machine in the wrong state).
429Rate limit exceeded; see the Retry-After header.

The API is under active development (alpha) and may change. For stable workflows, prefer the CLI. The full request/response contract lives in the contracts repository.

MCP & agent runtime

cps-mcp exposes cps as Model Context Protocol tools, so any MCP-capable agent (Claude Code, Claude Desktop, …) can create isolated Linux sandboxes, run code in them, publish ports, and tear them down — all over the public cps API.

A sandbox is the agent-facing name for an ephemeral machine at the MCP layer. It’s a Firecracker microVM with VM-level isolation, a persistent disk for the task, outbound networking, an optional HTTPS preview, and an automatic TTL — so an agent can run untrusted code and never leak resources.

cps-mcp speaks MCP over stdio and ships inside the cps CLI — installing the CLI installs cps-mcp too.

1. Install & get a token

Install the CLI (see Getting started for details):

curl -fsSL https://cps.run/install.sh | sh
cps version          # confirms both `cps` and `cps-mcp` are installed

Log in and create a token for the agent (shown once):

cps login --token <your-token>
cps token create --ttl 24h --name mcp

2. Configuration

cps-mcp reads its settings from the environment, and falls back to your cps CLI config after cps login (so CPS_TOKEN is optional once you’re logged in):

VariableRequiredDefaultPurpose
CPS_TOKENyes*—A cps token (cpsk_…). *Optional if cps login already configured the CLI.
CPS_API_URLnohttps://cps.runControl-plane base URL (e.g. a lab endpoint).
CPS_PROJECT_IDnoauto-detectedProject to create sandboxes in; inferred from the token’s org if unset.

3. Connect an MCP client

Claude Code — one command:

claude mcp add cps -e CPS_TOKEN=cpsk_your_token -- cps-mcp

Claude Desktop / generic MCP client — add to the client’s mcpServers config:

{
  "mcpServers": {
    "cps": {
      "command": "cps-mcp",
      "env": { "CPS_TOKEN": "cpsk_your_token", "CPS_API_URL": "https://cps.run" }
    }
  }
}

Verify the connection with /mcp — the cps server should show as connected with 8 tools.

4. Tools

ToolPurpose
create_sandbox(image?, ttl_seconds?)Boot an ephemeral microVM, wait until ready, return sandbox_id. Auto-deletes after the TTL (default 900s).
run(sandbox_id, command[], timeout_secs?)Run an argv array in the sandbox; returns exit_code, stdout, stderr. Not shell-parsed — use ["sh", "-c", "…"] for pipes/globs.
write_file(sandbox_id, path, content)Write a text file inside the sandbox.
read_file(sandbox_id, path)Read a text file from the sandbox.
expose(sandbox_id, port)Publish a port over a public HTTPS URL.
destroy(sandbox_id)Delete the sandbox and its routes.
fork_sandbox(sandbox_id, ttl_seconds?)Clone a sandbox’s disk into a new ready sandbox (briefly stops the source for a consistent copy).
list_sandboxes()List the sandboxes in the project.

Typical agent flow:

  1. create_sandbox → sandbox_id
  2. write_file(sandbox_id, "/root/app.py", "…")
  3. run(sandbox_id, ["python3", "/root/app.py"])
  4. expose(sandbox_id, 8080) → public HTTPS URL
  5. destroy(sandbox_id) (or let the TTL reap it)

5. Claude Code plugin & skill

For Claude Code, installing the cps-agent-runtime plugin gives an agent both the cps MCP tools and the cps-agent-runtime skill, which teaches the agent to use them correctly (TTL cleanup, argv vs shell, route reclaim on destroy).

The plugin registers the cps-mcp command — the binary must already be on PATH (step 1). Install from the Git remote:

/plugin marketplace add https://git.codelab.vc/cps/cli
/plugin install cps-agent-runtime@cps

Or from a local checkout of the cli repository:

/plugin marketplace add /absolute/path/to/cli
/plugin install cps-agent-runtime@cps

Then ask naturally — e.g. “run this script in an isolated cps sandbox and show the output” — and the skill drives create_sandbox → write_file/run → destroy.

6. Updating

cps-mcp, the CLI, and the plugin update independently — there is no cps update command yet.

CLI + cps-mcp (one binary, one step) — re-run the installer, which overwrites the binary in place, then restart your MCP client so it re-spawns cps-mcp:

curl -fsSL https://cps.run/install.sh | sh
cps version          # confirm the new version

From a source checkout instead:

git pull && cargo install --path . --locked --force

Plugin + skill — refresh Claude Code’s marketplace (re-pulls the cli repo), then re-enable the plugin:

/plugin marketplace update cps
/plugin install cps-agent-runtime@cps
/reload-plugins            # apply changes without restarting the session

The plugin only registers cps-mcp — updating the plugin does not update the binary. Update the CLI (above) to get new tool behavior.

Notes (alpha)

  • Public expose HTTPS previews need the cps routing layer. Single-host lab deployments create the route record but do not serve traffic yet.
  • cps-mcp talks only to the public cps API, so it works against any reachable control plane via CPS_API_URL.
  • New CLI versions reach https://cps.run/install.sh only after the cps team publishes a release — re-running the installer picks up whatever is current.