# Connect a worker

Create a worker invitation, enroll a machine into a pool and start accepting jobs.

Register a machine (laptop, lab server, or cloud VM) as a worker so it can execute jobs for your organization's pool.

## 1. List existing workers

Sign in with your account and inspect the workers registered in your organization:

```bash
ct-cli login
ct-cli worker list
```

```text
ID                                    NAME         POOL  PLATFORM                   ENABLED
0195f3a0-1234-7000-8000-000000000001  cpu-worker   cpu   linux-x86_64-py3.13-cpu    true
```

> **Note:** `ct-cli worker list` shows registered worker records and whether they are enabled. If you belong to multiple organizations, pass `--organization ORGANIZATION_UUID`.

## 2. Create a worker invitation

On an administrator machine, generate a one-time `invitation.json` for the target pool (for example, `cpu` or `gpu`):

```bash
ct-cli worker invite \
  --organization ORGANIZATION_UUID \
  --name "Lab CPU worker" \
  --pool cpu \
  --output invitation.json
```

Copy `invitation.json` to the new worker machine and restrict its file permissions (`chmod 600 invitation.json`).

## 3. Enroll and start the worker

On the worker machine, install the worker runtime, consume `invitation.json` with `ct-cli worker join`, and start the worker loop:

```bash
uv sync --project compute/platform --frozen --extra worker
alias ct-cli="$PWD/compute/platform/.venv/bin/ct-cli"

ct-cli worker join invitation.json \
  --configuration worker.toml \
  --cpus 4 \
  --memory 4096

ct-cli worker start worker.toml
```

What `worker join` does:

- Exchanges `invitation.json` for a dedicated worker credential and writes `worker.toml` plus local state.
- Advertises the machine's capacity (`--cpus 4`, `--memory 4096` MiB) to the scheduler.
- Requires no user login on the worker machine itself.

## 4. Install scientific dependencies (optional)

A basic worker can run standalone Python scripts and managed `uv` packages out of the box. If your worker will run scientific native-profile jobs (ASE, PySCF, MD, or TS search):

1. Sync the shared scientific runtime:
   ```bash
   uv sync --project compute/runtime --frozen
   ```
2. For container jobs, ensure Docker is installed and running.
3. For GPU pools, verify NVIDIA drivers and CUDA 13 device visibility before starting the worker. See [Choose code and dependencies](/operate/environments/) for how jobs select an environment.

## 5. Drain or stop a worker safely

Before upgrading dependencies or shutting down a machine, inspect or drain the worker so active jobs finish cleanly:

```bash
ct-cli worker status WORKER_UUID
ct-cli worker drain WORKER_UUID
```

Always stop the worker process before running `uv sync` or editing packages in its native runtime environment. Keep the worker's state directory intact across restarts so it can recover any in-flight artifact uploads (see [Inspect and recover a run](/operate/recovery/)).
