Skip to Content
Kai

Local setup

Run Kai from a checkout, with fake providers for working offline.

You need Node 22+, pnpm 10 and Docker. psql is optional; the scripts fall back to the Postgres container.

make init     # .env with generated secrets, pnpm install, services, roles, migrations
make dev      # the API and the web app

make init starts Postgres (port 5440), Redis (6390) and SeaweedFS (9010) in Docker, writes .env with generated secrets, creates the database roles and applies the migrations.

make dev (pnpm dev) starts two processes:

Port
API (apps/api)KAI_API_PORT, default 3001Hono on Node, restarted on change (tsx watch).
Web (apps/web)KAI_WEB_PORT, default 3000The Vite dev server, which forwards /api to the API.

Open the web port, and make sure KAI_APP_URL matches it: sign-in checks the origin. The library service runs on its own when you need it:

pnpm --filter @kai/library dev   # :4100, then set KAI_LIBRARY_URL=http://localhost:4100

Verification codes and invitation links are printed to the API's log, since email goes to the local adapter.

Working without real keys

scripts/ has fakes that speak the real wire formats:

pnpm --dir scripts fake-providers   # :4010 — Anthropic and OpenAI
pnpm --dir scripts fake-mcp         # :4020 — an MCP server, with header and OAuth variants
pnpm --dir scripts demo-mcp-notes   # :4030 — a Notes MCP server (Bearer notes-alice / notes-bob)

Add a key with base URL http://127.0.0.1:4010/anthropic or http://127.0.0.1:4010/openai/v1, any key, and Allow private network (which needs KAI_ALLOW_PRIVATE_NETWORK=true). The fake models reply "You said: …", call a tool when a message contains call <tool name> {json}, and can play scripted replies posted to /__control/script.

Commands

Command
pnpm devAPI and web app.
pnpm typecheckType-check every package and tier.
pnpm lintLint, including the import rules between tiers and packages.
pnpm testUnit tests.
make test-rlsThe row-level security suite against a throwaway Postgres.
make test-liveReal provider calls, with your own keys.
make migrateApply migrations (safe to run again).
pnpm --filter @kai/web buildBuild the web app (apps/web/dist).
pnpm --filter @kai/api buildBundle the server (apps/api/dist/server.mjs).
pnpm --filter @kai/docs devThis documentation site.

On this page