What the stack is
Docker Compose runs three services plus an optional virtual agent:
The React dashboard (port 5173) runs natively via
./dev.sh (Vite HMR) or as a container through the development override compose file. Real rig agents run natively on your bench machines, not in Docker — they connect outbound to the server over WebSocket.
Prerequisites
- Docker and Docker Compose (v2 plugin or v1 standalone — both are detected)
curlorwget, andpython3(used by the bootstrap script)
Bootstrap with setup.sh
From the project root:
- Validates prerequisites (docker, docker compose)
- Creates
.envfrom.env.exampleand generatesSECRET_KEYandREGISTRATION_TOKENautomatically - Starts
db+serverand waits for health (Alembic migrations run on startup) - Registers a
default-rigand saves its API key to.envasCRUCIHIL_API_KEY - Starts all services (control plane + MCP server)
- Control plane:
http://localhost:8000(API docs at/docs) - MCP server:
http://localhost:8001/sse
Environment variables
All configuration lives in.env (created from .env.example):
string
PostgreSQL username, used by the
db service. Default: crucihil.string
PostgreSQL password. Must be changed from the default
changeme for production.string
Database name. Default:
crucihil.string
Full connection string used by the server and Alembic, e.g.
postgresql://crucihil:changeme@db:5432/crucihil. The hostname must match the compose service name db.string
JWT signing secret. Generated automatically by
setup.sh (or create one with python -c "import secrets; print(secrets.token_hex(32))"). Must be changed before production use.string
Static token required to register new rigs (
POST /api/v1/rigs). Generated automatically by setup.sh. Keep it private.string
API key the MCP server uses to authenticate to the control plane. Written by
setup.sh after it registers the default rig.First org and admin — the one-shot /setup bootstrap
The dashboard and API use org-scoped users. Create the first organisation and admin account with a single call:
409 to prevent accidental re-initialisation. Admins can then invite team members from Settings → Team → Invite member.
Local development — dev.sh
For working on CruciHiL itself: backend in Docker, dashboard natively with Vite HMR.
Installing agents on bench machines
Each HiL bench machine runs a native agent that connects outbound to your control plane. Register the rig first (viaPOST /api/v1/rigs with the REGISTRATION_TOKEN, the dashboard, or the register_rig MCP tool) to get its API key, then install:
- Creates a
crucihilsystem user and installs the package into a venv at/opt/crucihil - Copies the rig TOML to
/opt/crucihil/rigs/<name>.toml - Writes
CRUCIHIL_BASE_URLandCRUCIHIL_API_KEYto/etc/crucihil/<name>.env(chmod 600) - Installs the systemd template unit
crucihil-agent@.service - Enables and starts
crucihil-agent@<name>
--dir (install directory, default /opt/crucihil) and --user (service user, default crucihil).
Manage the service afterwards:
Agents can also self-register: set
registration_token in the rig TOML’s [rig.cloud] section, and on first boot the agent exchanges it for a permanent API key stored in ~/.crucihil/credentials.toml. The CRUCIHIL_BASE_URL / CRUCIHIL_API_KEY environment variables take precedence over [rig.cloud]. See Rig Configuration.Connecting an AI client
Point any MCP client at your self-hosted MCP server. For Claude Desktop, add toclaude_desktop_config.json:
Deploying to Fly.io + Vercel
The repo ships Fly configs for the two backend services:SECRET_KEY must match the control plane — set it with fly secrets set SECRET_KEY=... --app crucihil-mcp.
See also
- Installation — installing the
crucihilpackage - Quickstart — first test against the virtual rig
- Rig Configuration — the
[rig.cloud]section and agent registration crucihil agent— running the agent by hand