Skip to content
Documentation Run locally ▾

Install & self-host

Docs / Install & self-host / Run locally

Run RecallHQ locally

Start Postgres with pgvector, load the synthetic Beacon corpus, run the API and tests, and point the docs site at your local API.

Requirements

  • Python 3.12 and uv
  • Docker, for Postgres 16 with pgvector
  • Node 22 or newer with corepack, for the docs site and demo
  • An OpenAI API key with access to text-embedding-3-small and gpt-5.4-mini. An OpenRouter key is optional and turns on reranking.

Backend quickstart

Clone the repository, add your keys to .env (see below), then run from the repository root:

Shell
uv sync --locked
docker compose up -d
uv run python -m recallhq.cli migrate
uv run python -m recallhq.cli ingest data/synthetic/corpus.jsonl
uv run uvicorn recallhq.api:app --reload
uv run pytest -q
  1. uv sync installs the Python dependencies from the lockfile.
  2. docker compose up -d starts pgvector/pgvector:pg16 on port 5432. The API and Slack worker containers sit behind the slack profile and do not start here.
  3. migrate applies migrations/*.sql once each, under an advisory lock, and creates the recallhq_reader and recallhq_ingestor roles.
  4. ingest loads the synthetic Beacon corpus, builds message and thread chunks, and embeds them. It is re-runnable: unchanged chunks keep their embeddings.
  5. uvicorn serves the public API on http://127.0.0.1:8000.

Environment

Settings are read from .env (and .env.slack for the bot). Local defaults match compose.yaml.

VariableRequiredPurpose
OPENAI_API_KEYYesEmbeddings for ingest and queries, and answer generation
DATABASE_URLNoQuery login. Defaults to postgresql://recallhq:recallhq@localhost:5432/recallhq
OPEN_ROUTERNoOpenRouter key for Decisions API reranking. Without it, results keep RRF order
DATABASE_WRITE_URLProductionSlack service login (ingestor role). Falls back to DATABASE_URL
DATABASE_MIGRATION_URLProductionSchema owner, used only by migrate

Try the API

The public endpoint accepts the same three commands as the playground, scoped to the synthetic corpus.

Shell
curl -s http://127.0.0.1:8000/commands \
  -H 'Content-Type: application/json' \
  -d '{"input": "/ask Why did the team switch from MongoDB to Postgres for the pilot?"}'

/search <terms> returns ranked hits, and /catchup YYYY-MM-DD YYYY-MM-DD [#channel] recaps a date range of up to 32 days. Anonymous commands are limited to 3 per minute and 20 per day per IP, plus 200 per day site-wide.

Tests

The default suite runs offline. Postgres integration tests need a disposable PG16 + pgvector admin URL; they create and drop their own database and never touch DATABASE_URL.

Shell
uv run pytest -q
RECALLHQ_TEST_DATABASE_URL=postgresql://recallhq:recallhq@localhost:5432/recallhq uv run pytest -q

To measure retrieval quality, see Evaluations.

Frontend

The docs, playground, and Beacon demo are a Next.js app in frontend/, adapted from an MIT-licensed Slack clone.

Shell
cd frontend
echo 'NEXT_PUBLIC_API_URL=http://127.0.0.1:8000' > .env.local
corepack pnpm install --frozen-lockfile
corepack pnpm dev

Open http://localhost:3000, which the API already allows through CORS. Without NEXT_PUBLIC_API_URL, the site uses the hosted API.

VariablePurpose
NEXT_PUBLIC_API_URLRecallHQ API base URL for the playground and demo
NEXT_PUBLIC_BASE_PATHServe the site under a sub-path, for example /recallhq. Leave empty at the domain root

Before shipping a change to the site, check it against a production build:

Shell
corepack pnpm lint
corepack pnpm build && corepack pnpm start
node scripts/check-docs-site.cjs   # routes, overflow, playground states

Next: connect your own Slack bot.