Skip to content
Pilotoo
v0.1

Run the standalone service

apps/brain-api is Brain as a service: NestJS and PostgreSQL, the REST API, the MCP endpoint at /mcp, Google sign-in, and the built web app (apps/brain-web) served from the same port. It is the example host for embedding Brain.

  • PostgreSQL with the pgvector extension available. On boot the service runs CREATE EXTENSION IF NOT EXISTS vector, creates the pilotoo_brain schema with its tables, and creates the sign-in tables beside them. Both steps are idempotent and locked, so several instances may start together.
  • A Google OAuth client of type Web application, with https://<your host>/auth/google/callback as an authorised redirect URI.
  • Optional: a Bedrock API key (or another provider’s key) for a chat model, and an embeddings provider.

Build from the repository root:

Terminal window
docker build -f apps/brain-api/Dockerfile -t pilotoo-brain .
docker run --env-file brain.env -p 4320:4320 pilotoo-brain

The image runs as an unprivileged user and listens on PORT (4320). Put it behind a proxy that terminates TLS; BRAIN_PUBLIC_URL must be https outside localhost.

brain.env
DATABASE_URL=postgres://user:password@db:5432/pilotoo_brain
BRAIN_PUBLIC_URL=https://brain.example.com
BRAIN_SESSION_SECRET=<32 or more random characters>
GOOGLE_CLIENT_ID=<web client id>
GOOGLE_CLIENT_SECRET=<web client secret>
BRAIN_ALLOWED_EMAILS=ada@example.com,grace@example.com
BRAIN_ADMIN_EMAILS=ada@example.com

Boot fails naming every required setting that is missing or malformed, never a value.

Variable Default Meaning
DATABASE_URL required PostgreSQL with pgvector.
BRAIN_PUBLIC_URL required Public origin people reach the service at. Sign-in derives from it; https outside localhost.
BRAIN_SESSION_SECRET required At least 32 characters. Signs the session and login cookies.
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET required The Google OAuth client.
PORT 4320 Listening port.
BRAIN_ALLOWED_EMAILS nobody Comma-separated emails that may sign in. * admits every verified Google account.
BRAIN_ADMIN_EMAILS none Comma-separated emails that are workspace admins.
BRAIN_MODEL off Chat model as provider:modelId, for page compilation, answers and label suggestions. Unset: those features are off.
ANTHROPIC_BEDROCK_REGION none Region for the anthropic-bedrock provider.
AWS_BEARER_TOKEN_BEDROCK none Bedrock API key. Also the default key for Titan embeddings.
OPENAI_API_KEY, OPENAI_BASE_URL, ANTHROPIC_API_KEY, ANTHROPIC_BASE_URL, AI_DEEPSEEK_API_KEY, AI_DEEPSEEK_BASE_URL none Keys and base URLs of the other model providers.
BRAIN_EMBEDDINGS_PROVIDER off bedrock-titan or openai-compatible. Unset: search is full-text only.
BRAIN_EMBEDDINGS_REGION none Required for bedrock-titan. Independent of the chat model’s region.
BRAIN_EMBEDDINGS_API_KEY AWS_BEARER_TOKEN_BEDROCK for bedrock-titan Embeddings key. Required for openai-compatible.
BRAIN_EMBEDDINGS_MODEL amazon.titan-embed-text-v2:0 for bedrock-titan Required for openai-compatible.
BRAIN_EMBEDDINGS_DIMENSIONS 1024 for bedrock-titan Vector width, a whole number from 1 to 16000.
BRAIN_EMBEDDINGS_BASE_URL OpenAI openai-compatible only: the server’s base URL, such as https://api.openai.com/v1.
BRAIN_TENANT brain Tenant name recorded for signed-in people.
BRAIN_WEB_DIST /app/web in the image Directory of the built web app to serve.
BRAIN_OIDC_ISSUER Google Override of the OIDC issuer.
BRAIN_ENV_FILE none A file of settings loaded at start, for local runs.

When BRAIN_EMBEDDINGS_PROVIDER is unset but both an embeddings key and model are set, openai-compatible is used.

People sign in with Google at /auth/google/start. The session is a signed cookie; a person not in BRAIN_ALLOWED_EMAILS is sent back to /?error=not_allowed. Signing in creates the person’s personal memory. Agents do not use the cookie; they use pb_ tokens on /mcp, see Use it from an agent.

GET /health answers {"status":"ok"} without a session, for a proxy or orchestrator health check.