Installation
Docker Compose runs the platform and web UI as two containers. This is the recommended method for single-machine deployments.
-
Create a project directory
Terminal window mkdir nimblebrain && cd nimblebrain -
Create
nimblebrain.jsonnimblebrain.json {"$schema": "https://schemas.nimblebrain.ai/v1/nimblebrain-config.schema.json","version": "1"}This is runtime config only (model, limits, features). Installed apps are not listed here — per-workspace app installs live in
workspace.json, which the runtime manages. See the configuration reference for all options. -
Create
docker-compose.ymldocker-compose.yml services:platform:image: ghcr.io/nimblebraininc/nimblebrain:latestrestart: unless-stoppedvolumes:- workspace:/data- ./nimblebrain.json:/data/nimblebrain.json:roenvironment:- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}- OPENAI_API_KEY=${OPENAI_API_KEY:-}- GOOGLE_GENERATIVE_AI_API_KEY=${GOOGLE_GENERATIVE_AI_API_KEY:-}networks:- internalweb:image: ghcr.io/nimblebraininc/nimblebrain-web:latestrestart: unless-stoppedports:- "27246:8080"environment:- PLATFORM_URL=http://platform:27247depends_on:platform:condition: service_healthynetworks:- internalvolumes:workspace:networks:internal:The platform image is built on
python:3.13-slimand bundles Bun, Node.js 24, and the mpak CLI — the toolchain MCP server bundles shell out to at runtime. The runtime working directory inside the container is/data(set viaNB_WORK_DIR), so the config mount lands at/data/nimblebrain.json. -
Start the services
Terminal window export ANTHROPIC_API_KEY=sk-ant-api03-...docker compose upThe platform API runs on port 27247 (internal). The web UI is published on port 27246. Health is checked internally at
http://localhost:27247/v1/health.With no
instance.jsonpresent, the platform runs in dev mode — unauthenticated, single built-in user. To require real auth, add aninstance.jsonnext to your config with anoidcorworkosadapter (see Authentication below).
Build from local source
Section titled “Build from local source”To build the images from a checkout instead of pulling :latest, add a build: key and use docker compose up --build:
services: platform: image: ghcr.io/nimblebraininc/nimblebrain:latest build: . # ... web: image: ghcr.io/nimblebraininc/nimblebrain-web:latest build: web/ # ...docker compose up --buildRun from source for development. Requires Bun 1.2.0 or newer (engines.bun is >=1.2.0).
-
Clone and install
Terminal window git clone https://github.com/NimbleBrainInc/nimblebrain.gitcd nimblebrainbun install -
Install web dependencies
Terminal window cd web && bun install && cd .. -
Set your API key
Terminal window export ANTHROPIC_API_KEY=sk-ant-api03-... -
Start development mode
Terminal window bun run devThis starts both the API server (with file watching and auto-restart) and the web client (Vite HMR) in a single terminal. The dev workdir is project-local (
.nimblebrain/). Dev mode runs unauthenticated — no auth setup required locally.
Other dev commands:
bun run dev:empty # Empty state — no apps, fresh workdir (:27249/:27248)bun run dev:minimal # Minimal — no apps, preset model config (:27251/:27250)bun run test # Run unit AND integration testsbun run eval # LLM evals (requires ANTHROPIC_API_KEY)Environment variables
Section titled “Environment variables”| Variable | Required | Description |
|---|---|---|
ANTHROPIC_API_KEY | Yes | Anthropic API key for Claude. At least one provider key is required. |
OPENAI_API_KEY | No | OpenAI provider key. |
GOOGLE_GENERATIVE_AI_API_KEY | No | Google provider key. |
PORT | No | HTTP port for the API server. Default: 27247. |
NB_PUBLIC_ORIGIN | No | Canonical public origin used to build absolute URLs (OAuth callbacks, post-login landing). Default in dev: http://localhost:27247. Set this in production. See Environment Variables. |
NB_WORK_DIR | No | Working directory for conversations, skills, and app state. Default: .nimblebrain/ (project-local) or ~/.nimblebrain (global serve). Set to /data in the Docker image. |
ALLOWED_ORIGINS | No | Comma-separated allowed CORS origins. Default: all origins. |
MCP_MAX_SESSIONS | No | Maximum concurrent MCP sessions. Above this, new sessions evict the least-recently-used transport. Default: 100. |
MCP_SESSION_TTL_SECONDS | No | MCP session idle TTL in seconds. Default: 28800 (8 hours). |
NB_TELEMETRY_DISABLED | No | Set to 1 to disable anonymous telemetry. |
DO_NOT_TRACK | No | Set to 1 to disable anonymous telemetry. |
Authentication
Section titled “Authentication”NimbleBrain’s auth mode is determined by the presence of an instance.json file alongside your config:
- No
instance.json— the platform runs in dev mode: requests are unauthenticated and resolve to a single built-in user. Fine for local development; not for shared or networked deployments. instance.jsonwith anauth.adapter— a real identity provider is used. Supported adapters areoidc(any OpenID Connect issuer) andworkos. On successful login the provider’s callback sets annb_sessioncookie.
{ "auth": { "adapter": "oidc", "issuer": "https://your-idp.example.com", "clientId": "your-client-id", "allowedDomains": ["example.com"] }}Minimal config file
Section titled “Minimal config file”NimbleBrain reads nimblebrain.json at startup. A minimal config:
{ "$schema": "https://schemas.nimblebrain.ai/v1/nimblebrain-config.schema.json", "version": "1"}See the configuration reference for all options.