Skip to content

Run the server

Chorus needs two processes: a SurrealDB database and the Chorus server. This page runs both from source. (For a containerized variant, see Docker.)

  • Bun 1.3+
  • Node.js 24.18.0 when running the repository typecheck and distribution gates (.node-version is pinned)
  • SurrealDB 2.x or 3.x

The Chorus server itself runs on Bun; Node is a development and release-verification toolchain requirement.

Chorus connects to ws://localhost:8000 by default, but it deliberately has no password default. Generate a local password in an ignored, owner-only file, then use it for both processes:

Terminal window
mkdir -p .secrets
chmod 700 .secrets
openssl rand -base64 36 > .secrets/surreal_password
chmod 600 .secrets/surreal_password
surreal start --user root --pass "$(cat .secrets/surreal_password)" --bind 127.0.0.1:8000 memory

memory keeps everything in RAM (great for a first run; data is lost on restart). For persistence, swap it for rocksdb://chorus.db.

Terminal window
bun install
SURREAL_PASS="$(cat .secrets/surreal_password)" bun run src/index.ts

On first boot against an empty database, Chorus provisions an admin identity and prints a startup banner — see First identity & key. When you see Chorus Protocol listening on port 3000, it’s up:

Terminal window
curl http://localhost:3000/health
# {"status":"healthy","meta":{...}}

All config is environment variables; the defaults live in src/index.ts:35-43:

Variable Default Notes
SURREAL_ENDPOINT ws://localhost:8000 SurrealDB websocket URL
SURREAL_NS chorus Namespace
SURREAL_DB protocol Database
SURREAL_USER root Must match how you started SurrealDB
SURREAL_PASS required 16–1024 bytes; must match SurrealDB; known placeholder values are rejected
PORT 3000 Chorus HTTP port

Optional integrations (artifacts via S3-compatible storage e.g. Garage, an embedding provider, a reranker) are off unless their env vars are set — the boot log tells you which are unconfigured.

A Chorus process keeps some state in-process — the signal stream (SSE), lease/approval reapers, and the memory body cache. Run one Chorus process per instance; it does not yet fan out horizontally behind a load balancer. SurrealDB is the durable store; the Chorus process is replaceable but singular.