Getting started

Set up a GPU server

Deploy the headless cradle-server on a Linux GPU VM, bootstrap it, and connect a Cradle client.

For anything beyond a single laptop you run Cradle Server — the headless cradle-server daemon. It holds the data, the connectors, and the inference, while thin clients (the desktop app or the cradle CLI) drive it over an authenticated HTTP API. This guide installs it on a Linux GPU VM.

Requirements

  • Linux x86_64 (builds are linux-x64).
  • Node 22 and pnpm (corepack enable, or npm install -g pnpm@9).
  • Root access for the installer and bootstrap.
  • For GPU inference: NVIDIA drivers + CUDA toolkit. CPU-only works with no extra dependencies.

Install from S3 (curl flow)

The server/CLI bundle is published to the same downloads bucket as the desktop app, under the cradle-cli prefix. The one-liner installer handles the rest:

curl -fsSL \
  https://download.opencradle.ai/cradle-cli/latest/cradle-cli-install.sh \
  | sudo sh

Override defaults with environment variables:

curl -fsSL -o cradle-cli-install.sh \
  https://download.opencradle.ai/cradle-cli/latest/cradle-cli-install.sh

sudo CRADLE_PORT=31416 CRADLE_DATA_DIR=/var/lib/cradle \
  sh cradle-cli-install.sh

The installer checks for Node 22 + pnpm, downloads the zip, extracts to /opt/cradle, installs production dependencies, rebuilds native modules for the target platform, and bootstraps the server.

Install without root

If you have no root on the box (a VM on someone else's hosting, a shared account), run the same installer without sudo. It detects the missing privileges and switches to rootless mode: everything goes under ~/.local/share/cradle, no systemd unit is installed, and the CLI is linked into ~/.local/bin.

curl -fsSL \
  https://download.opencradle.ai/cradle-cli/latest/cradle-cli-install.sh \
  | sh

Start the server yourself:

~/.local/share/cradle/dist/server/index.js \
  --data-dir ~/.local/share/cradle/data --port 31416 --bind 0.0.0.0

To survive logout, add a user unit at ~/.config/systemd/user/cradle-server.service and enable lingering:

systemctl --user enable --now cradle-server
loginctl enable-linger $USER   # if the host policy allows it

Rootless limits: the port must be above 1024 (31416 is fine), autostart on reboot only works with lingering, and --user cradle does not apply — the service runs as you.

Manual install (from the zip)

If you prefer to see each step, or you are on a locked-down host, do it by hand:

# 1. Resolve the current version and download the bundle
VERSION=$(curl -fsSL https://download.opencradle.ai/cradle-cli/latest/manifest.json \
  | grep -o '"version": *"[^"]*"' | cut -d'"' -f4)

curl -fsSL -o cradle-cli-${VERSION}-linux-x64.zip \
  https://download.opencradle.ai/cradle-cli/${VERSION}/cradle-cli-${VERSION}-linux-x64.zip

# 2. Extract to /opt/cradle
sudo mkdir -p /opt/cradle
sudo unzip -o cradle-cli-${VERSION}-linux-x64.zip -d /opt/cradle

# 3. Run the installer (creates the `cradle` user, installs prod deps,
#    rebuilds native modules, installs the systemd unit)
cd /opt/cradle
sudo ./install.sh

Bootstrap the server

Bootstrapping creates the data directory, initialises the SQLite database, and generates the first admin API key. This is operator-driven — you run it on the target host; nothing is pushed over SSH from a client.

sudo /opt/cradle/dist/cli/index.js server init \
  --data-dir /var/lib/cradle \
  --port 31416 \
  --bind 0.0.0.0 \
  --install-systemd

What it does:

  1. Creates --data-dir and fixes permissions.
  2. Runs the server in bootstrap mode to initialise the DB and generate an admin:* key.
  3. Writes a systemd unit and runs systemctl enable --now.
  4. Waits for /admin/health, then issues a scoped client key.
  5. Writes client-credentials.json (mode 0600) into the data directory.

Running server init again on the same data directory is idempotent: it detects the initialised DB and exits instead of minting a new admin key.

Where things live

Every path below depends on how you installed:

root installrootless install
Install dir/opt/cradle~/.local/share/cradle
Data and keys/var/lib/cradle~/.local/share/cradle/data
Servicesystem systemdsystemctl --user
sudorequirednever needed

Managing the service

Root install — system systemd:

sudo systemctl start cradle-server
sudo systemctl enable cradle-server
sudo systemctl status cradle-server
sudo journalctl -u cradle-server -f

Rootless install — a user service. The --user flag is required in every command, and sudo is never used:

systemctl --user start cradle-server
systemctl --user enable cradle-server
systemctl --user status cradle-server
journalctl --user -u cradle-server -f

Connect a client

Collect the credentials from client-credentials.json in the data directory — sudo cat /var/lib/cradle/client-credentials.json after a root install, plain cat ~/.local/share/cradle/data/client-credentials.json after a rootless one. Transfer them to the Cradle client through your secure channel, then log in:

cradle login --url http://<server>:31416 --key ck_live_...

The CLI probes /admin/health to verify the connection and stores the profile in ~/.cradle/cli-config.json.

Running the daemon directly

Outside of systemd you can run the server yourself:

cradle-server --port 31416 --data-dir ~/.cradle
cradle-server --bind 0.0.0.0            # listen on all interfaces
cradle-server --no-api-autostart        # skip auto-enabling the API channel

Graceful shutdown on SIGINT/SIGTERM stops channels, releases model runners, and closes the database.

Remote GPU nodes

To offload heavy inference to a separate GPU box, configure a remote node. The CLI only stores configuration — it never pushes SSH commands; the operator runs them on the organisation's jump host:

cradle remote set \
  --host gpu-1.local --user cradle \
  --ssh-key-path /root/.ssh/gpu-1 \
  --remote-port 8080 --model-path /models/qwen3-8b.gguf

cradle remote show

The node is then used by creating a model with provider=remote-gpu. For multiple nodes, cradle remote pool probe health-checks them and cradle remote pool plan prints an autoscaler plan — it never executes SSH or cloud calls itself.

See the CLI reference for the full command catalogue and remote-server deployment for the closed-network flow.