HUG Server
The hug server is a standalone Node.js service that stores active reviews, serves the review UI, hosts real-time chat via WebSocket, and captures human verdicts. It requires PostgreSQL for storage.
The hug server is a necessary component to run teams that have Human Gates in their workflows.
The server is stateless at the process level — all review state lives in the database. Any server instance can serve any request. Multiple cliq instances can point to the same hug server.
Prerequisites
Section titled “Prerequisites”- Node.js 18+ (for npm) or Docker
- PostgreSQL 13+ — the schema is auto-created on first startup
Installation
Section titled “Installation”Docker (recommended)
Section titled “Docker (recommended)”docker run -d --name hug-server \ -p 3100:3100 \ -e DATABASE_URL=postgres://user:pass@host:5432/hug \ -e HUG_JWT_SECRET=$(openssl rand -hex 32) \ -e HUG_ADMIN_KEY=$(openssl rand -hex 32) \ ghcr.io/elanamir/hug-server:latestnpx @cliqhub/hug-server \ --database-url postgres://user:pass@host:5432/hug \ --jwt-secret $(openssl rand -hex 32) \ --admin-key $(openssl rand -hex 32) \ --port 3100Local development with Docker Postgres
Section titled “Local development with Docker Postgres”If you don’t have a Postgres instance handy:
docker run -d --name hug-pg \ -p 5433:5432 \ -e POSTGRES_PASSWORD=hug \ -e POSTGRES_DB=hug \ postgres:16-alpine
npx @cliqhub/hug-server \ --database-url postgres://postgres:hug@localhost:5433/hug \ --jwt-secret my-dev-secret \ --admin-key my-admin-keyDocker Compose
Section titled “Docker Compose”For production or when running alongside the cliq server:
services: hug-server: image: ghcr.io/elanamir/hug-server:latest restart: unless-stopped ports: - "3100:3100" environment: DATABASE_URL: postgres://user:pass@host:5432/hug HUG_JWT_SECRET: ${HUG_JWT_SECRET} HUG_ADMIN_KEY: ${HUG_ADMIN_KEY}CLI Reference
Section titled “CLI Reference”| Flag | Env var | Default | Description |
|---|---|---|---|
--database-url | DATABASE_URL | (required) | PostgreSQL connection string |
--port | PORT | 3100 | HTTP port |
--jwt-secret | HUG_JWT_SECRET | (required) | Secret used to sign and verify JWTs |
--admin-key | HUG_ADMIN_KEY | (none) | Key for the admin API (token issuance). Required when integrated with CliqHub |
--cors-origin | HUG_CORS_ORIGIN | (none) | CORS origin header (for cross-domain UIs) |
--retention-days | HUG_RETENTION_DAYS | 30 | Days to keep completed/expired reviews before purging |
Health check
Section titled “Health check”curl http://localhost:3100/health# {"status":"ok","service":"hug-server"}Connecting Cliq to the Server
Section titled “Connecting Cliq to the Server”Run cliq hub login to authenticate with CliqHub. If the HUG server is integrated with CliqHub, this automatically provisions a HUG user JWT and writes both hug.server_url and hug.token to ~/.cliqrc/settings.json.
For standalone HUG server setups (no CliqHub), generate a user JWT via the admin API and configure manually:
# Generate a user JWT via the admin APIcurl -s -X POST http://localhost:3100/admin/tokens \ -H 'Content-Type: application/json' \ -H 'X-Admin-Key: <your-admin-key>' \ -d '{"user_id":"local-dev","label":"dev"}' | jq -r .token
# Write the token and server URL into settingscliq settings hug.server_url http://localhost:3100 --globalecho '<token-from-above>' | cliq settings hug.token --stdin --globalSee Settings & Troubleshooting for the full HUG settings reference.
Review Lifecycle
Section titled “Review Lifecycle”Reviews follow a lifecycle managed by the server:
- pending — awaiting a human verdict
- decided — verdict submitted, agent hasn’t acknowledged yet
- completed — agent acknowledged; review remains accessible as a read-only archive
- purged — automatically deleted after
--retention-days(default 30)
During the retention period, anyone with the review link can still view the verdict, comment, artifacts, and chat transcript. After the retention period, a background job purges old records hourly.
The permanent audit trail lives in .cliq/reviews/ on the cliq instance — see Audit Trail.
Scaling
Section titled “Scaling”The server is stateless — scale horizontally behind a load balancer. Use sticky sessions at the load balancer for WebSocket connections, or add a pub/sub layer for cross-instance relay.