Skip to main content

Getting Started

Run the whole Clippy Chat app locally. You need Node 22+, Docker (for the dev Postgres), and access to a vLLM OpenAI-compatible endpoint for live replies.

1. Clone and install​

git clone https://git.cdot.io/cdot.io/clippy-chat.git
cd clippy-chat
npm install

2. Start the dev database​

A Postgres 17 container on localhost:5433 (see docker-compose.yml):

docker compose up -d db

3. Configure the environment​

Copy the template and fill it in. Every value in .env.example is a placeholder:

cp .env.example .env

The minimum to boot:

.env
DATABASE_URL=postgres://clippy:clippy@localhost:5433/clippy
APP_URL=http://localhost:3000
INFERENCE_BASE_URL=http://<vllm-host>:8000
INFERENCE_MODEL=@vllm2/unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_XL
# INFERENCE_AUTH_MODE=gateway # against AIRS; omit for a direct vLLM
# INFERENCE_API_KEY=... # direct mode only if vLLM runs with --api-key
# Gateway mode credential: a Keycloak client_credentials identity scoped
# completions.write. Falls back to INFERENCE_API_KEY when unset.
# INFERENCE_TOKEN_URL=https://auth.example.com/realms/myrealm/protocol/openid-connect/token
# INFERENCE_CLIENT_ID=clippy-inference-client
# INFERENCE_CLIENT_SECRET=...
KC_ISSUER=https://auth.example.com/realms/myrealm
KC_CLIENT_ID=clippy-web
KC_CLIENT_SECRET=changeme
SESSION_SECRET=<openssl rand -base64 32>
ADMIN_USERNAME=admin
ADMIN_PASSWORD=changeme
M2M_SCOPE=clippy-api
# Expected aud on machine bearer tokens. Verify a real token carries this value
# before setting it — arming it against a missing aud 401s every machine caller.
# M2M_AUDIENCE=clippy-api

See Configuration for every variable, its purpose, and defaults.

:::tip No Keycloak handy? You don't need a live OIDC provider to try the app. The local break-glass admin (ADMIN_USERNAME / ADMIN_PASSWORD) logs in without Keycloak — see Authentication. :::

4. Apply migrations​

npm run db:migrate

5. Run the dev server​

npm run dev

Open http://localhost:3000. Unauthenticated requests redirect to /login; sign in with the local admin account, start a new chat, and send a message — the reply streams in token by token.

Test, typecheck, build​

npm test # vitest; integration tests need the dev db (docker compose up -d db)
npm run typecheck # tsc --noEmit
npm run build && npm start

Next steps​