Local setup
Install Brain locally with Node 24, pnpm, Postgres, and a model.
Install the tools, fork and clone the repo, then keep going in this terminal or in VS Code. After each command, run the Check. Skip a step if that check already passes.
Pick macOS, Windows, or Linux in the OS tabs. After you clone, pick This terminal or VS Code. Both choices stick for the rest of this page.
No Vercel account, Neon, or Vercel AI Gateway.
What Brain needs
Brain runs with these four.
Node 24
pnpm
Postgres
A model
COMMAND_CODE_API_KEY.To follow this guide
These are for installing and cloning. They are not part of Brain.
Terminal
Git
GitHub account
Homebrew
openssl
Editor
1. Open a terminal
- Press Command (⌘) + Space
- Type
Terminal - Press Enter
A window with a prompt (% or $) appears. Paste commands here. After you clone (step 8), you can stay in this terminal or open VS Code (step 9).
2. Compiler tools and Git
Apple’s Command Line Tools include a compiler. Homebrew needs them.
xcode-select --installA system dialog may appear. Click Install and wait. If it says already installed, continue.
Check — you should see a path, not an error:
xcode-select -pTypical output: /Library/Developer/CommandLineTools or a path under /Applications/Xcode.app.
Install Homebrew. On macOS this guide uses brew for Git, nvm, and pnpm.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"Enter your Mac password if asked (you will not see characters as you type). Wait until it finishes.
On Apple Silicon (M1/M2/M3/M4) the installer often says Homebrew is not on your PATH. Paste these two commands, one at a time:
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofileeval "$(/opt/homebrew/bin/brew shellenv)"On Intel Macs, use /usr/local/bin/brew instead of /opt/homebrew/bin/brew if the installer printed that path.
Check
brew --versionYou should see Homebrew 4.x (or similar), not command not found.
brew install gitCheck Git
git --versionYou should see git version 2.x.
Tell Git who you are (once)
Use your real name and the email on your GitHub account. Replace the quoted text, then paste.
git config --global user.name "Your Name"git config --global user.email "[email protected]"git config --global init.defaultBranch mainCheck
git config --global --get user.namegit config --global --get user.emailThose two lines should print the name and email you just set.
3. nvm (Node Version Manager)
nvm installs a specific Node.js version. Brain requires Node 24. Other versions (18, 20, 22) will fail.
brew install nvmmkdir -p ~/.nvmecho 'export NVM_DIR="$HOME/.nvm"' >> ~/.zshrcecho '[ -s "$(brew --prefix)/opt/nvm/nvm.sh" ] && . "$(brew --prefix)/opt/nvm/nvm.sh"' >> ~/.zshrcClose Terminal completely (Command+W). Open Terminal again. nvm only loads in new windows.
Check that nvm exists
command -v nvmThat should print nvm. If it prints nothing:
source ~/.zshrcThen run command -v nvm again. If it still fails, close Terminal and reopen.
Check the nvm version
nvm --versionYou should see a number like 0.40.3.
4. Node 24
Install Node 24, make it the default, and turn it on:
nvm install 24nvm alias default 24nvm use 24Check
node -vMust start with v24. — for example v24.19.0. If you see v18, v20, or v22, run nvm use 24 again.
5. pnpm
pnpm installs the project’s JavaScript dependencies. Brain blocks npm and yarn — if you run npm install it will error on purpose.
brew install pnpmCheck
pnpm --versionYou need 11 or higher. On macOS, if brew gave an older pnpm: brew upgrade pnpm.
6. Docker
Docker runs Postgres (Brain’s database) in a container. You do not install Postgres by hand.
- Open https://www.docker.com/products/docker-desktop/
- Download Docker Desktop for Mac (Apple Silicon or Intel — match your laptop)
- Open the installer and drag Docker to Applications
- Open Docker from Applications (whale icon in the menu bar)
- Accept the service agreement if asked
- Wait until the whale is steady and the app says Engine running
Leave Docker Desktop open whenever you use Brain.
Check
docker versiondocker compose versionEach should print a version. If you see Cannot connect to the Docker daemon, Docker is not running yet — wait and try again.
7. openssl
Used to generate login secrets.
macOS already has it.
openssl versionYou should see LibreSSL or OpenSSL, not command not found.
8. Fork, then clone
Do not clone akhil-naidu/brain directly. Fork it to your GitHub account, then clone your fork.
Fork on GitHub
- Open https://github.com/akhil-naidu/brain in a browser
- Sign in to GitHub if asked
- Click Fork (top right)
- Keep yourself as the owner and click Create fork
- Wait until the URL looks like
https://github.com/YOUR_GITHUB_USERNAME/brain
Clone your fork
On Windows, stay in Ubuntu. Do not clone into /mnt/c or C:\.
mkdir -p ~/devcd ~/devReplace YOUR_GITHUB_USERNAME with the GitHub username from the fork URL. You can also copy the URL from the green Code button on your fork.
HTTPS (works for most people):
git clone https://github.com/YOUR_GITHUB_USERNAME/brain.gitOr SSH (only if you already use GitHub SSH keys) — skip this if you used HTTPS:
git clone [email protected]:YOUR_GITHUB_USERNAME/brain.gitIf GitHub asks you to sign in, use your GitHub login, a personal access token, or an SSH key.
cd brainPoint upstream at the original repo so you can pull updates later:
git remote add upstream https://github.com/akhil-naidu/brain.gitCheck
pwdThe path should end with /brain.
git remote -vorigin should be your fork. upstream should be akhil-naidu/brain.
cat .nvmrcMust print 24.
git statusShould mention On branch main.
9. Continue here, or open VS Code
The next commands (pnpm install, Docker, .env, pnpm dev) run in a terminal inside the brain folder. You can stay in this terminal, or open the folder in an editor for a better view of the files.
Cursor, Antigravity, Windsurf, Zed, and similar editors work like VS Code: open the folder, then use the built-in terminal.
Stay in this terminal
You should already be in the repo from step 8. If the prompt is somewhere else:
cd ~/dev/brainCheck
pwdThe path should end with /brain. Skip to step 10.
Install VS Code
Skip this if code --version already works.
brew install --cask visual-studio-codeOpen Visual Studio Code from Applications once so macOS allows it.
Check
code --versionIf you see command not found: in VS Code press Command+Shift+P, run Shell Command: Install 'code' command in PATH, then open a new terminal.
Open in VS Code
From inside ~/dev/brain:
code .That opens this repo in VS Code.
Then open VS Code’s terminal:
- Click the terminal icon in the top-right (panel layout), or click Terminal in the bottom panel
- Or press Control+` (Control and the backtick key, under Escape)
- Or menu Terminal → New Terminal
A prompt appears at the bottom. It should already be in brain.
Check
pwdThe path should end with /brain. Then go to step 10 and paste the rest of the commands in this VS Code terminal.
For a second long-running command (the Ollama SSH tunnel later), use Terminal → New Terminal again.
If code . fails, use File → Open Folder and pick ~/dev/brain.
10. Install JavaScript packages
Use the same terminal you chose in step 9. Pick This terminal or VS Code in the tabs — the choice sticks. pwd must end with /brain.
cd ~/dev/brainnvm usenode -vMust still be v24.x. Then:
Skip corepack — pnpm already came from Homebrew.
pnpm installThis can take several minutes. Lines about Fumadocs / postinstall are normal.
Check: the command ends with no error, and this prints a path:
ls node_modulesIf you see Use pnpm to install, you used npm install. Stop. Use pnpm install only.
11. Start Postgres
Docker must be running. Same terminal as step 10 (pwd still ends with /brain). Do not cd again if you are already there.
docker compose up -d dbWait a few seconds.
docker compose psThe db row should look running or healthy.
docker compose exec db pg_isready -U brain -d brainShould print accepting connections.
This creates:
- Database
brain— userbrain, passwordbrain(the app) - Database
brain_test— for automated tests only (will not wipe your login)
If port 5432 is already used by another Postgres: stop that other Postgres, or change the host port in docker-compose.yml and use the new port in BRAIN_DATABASE_URL.
12. Create .env
This file holds secrets. It is not committed to Git.
Same folder as step 10:
cp .env.example .envGenerate a session secret. Copy the whole line of output (letters, numbers, +, /, =):
openssl rand -base64 32Generate a bootstrap secret. Run this again so you get a different string:
openssl rand -base64 32Pick This terminal (edit with nano) or VS Code (click .env in the sidebar). Same tab as step 9.
Open .env with:
nano .envIn nano: save with Ctrl+O, Enter, then Ctrl+X.
These next boxes are lines to put in that file, not commands for the shell. If a key is already there with a # in front, delete the # and set the value. Paste your two openssl outputs. Do not reuse one string for both secrets.
BETTER_AUTH_SECRET=paste-first-openssl-outputBRAIN_BOOTSTRAP_TOKEN=paste-second-openssl-outputBRAIN_DATABASE_URL=postgres://brain:[email protected]:5432/brainBRAIN_PUBLIC_URL=http://localhost:3000BETTER_AUTH_URL=http://localhost:3000| Variable | Why |
|---|---|
BETTER_AUTH_SECRET | Signs your login cookie |
BRAIN_BOOTSTRAP_TOKEN | You will paste this on /setup |
BRAIN_DATABASE_URL | Points at Docker Postgres |
BRAIN_PUBLIC_URL / BETTER_AUTH_URL | This laptop’s site origin |
Leave COMMAND_CODE_API_KEY= empty if you will use Ollama only.
Do not send these values in Slack or email.
Check — all five lines should print with values after =:
grep -E '^(BETTER_AUTH_SECRET|BRAIN_BOOTSTRAP_TOKEN)=' .envgrep -E '^(BRAIN_DATABASE_URL|BRAIN_PUBLIC_URL|BETTER_AUTH_URL)=' .envOptional later (not needed for first chat)
| Variable | When |
|---|---|
COMMAND_CODE_API_KEY | Built-in models in the picker |
BRAIN_INTERNAL_TOKEN | Schedules only — unattended timers. Another openssl rand -base64 32 |
BRAIN_INTERNAL_URL | Schedules only — already defaults to http://127.0.0.1:3000 |
| MCP client ids | Only if you skip in-app Connect. Environment |
13. Run Brain
Same terminal as step 10. Do not cd if pwd already ends with /brain.
nvm usepnpm devLeave this Terminal running. You should see Next.js ready on port 3000.
Open a browser:
- Empty database → you go to setup
- Operator already exists → sign-in
If the page errors, read the pnpm dev window: Docker not running, empty BETTER_AUTH_SECRET, or wrong BRAIN_DATABASE_URL are the usual causes.
14. Create the operator account
- Open http://localhost:3000/setup
- Title should be Create operator
- Fill in:
- Name — how you want to appear
- Email — you will sign in with this
- Password — at least 8 characters
- Bootstrap token — paste
BRAIN_BOOTSTRAP_TOKENfrom.env(exact match)
- Click Create account
You land on /chat. Brain creates a personal workspace. You are the instance admin. Other people stay invite-only until you change policy — Accounts and sign-in.
If you see Setup closed, someone already created the operator. Use http://localhost:3000/sign-in.
To wipe local users and start /setup again:
docker compose down -vdocker compose up -d dbThen open /setup again.
15. Ollama on a VPS (the model)
Brain sends chat to an OpenAI-compatible URL. Ollama provides that at http://HOST:11434/v1.
Your laptop must reach Ollama (discovery waits only 4 seconds).
Keep Ollama private
On the VPS, leave Ollama on localhost. From the laptop, use an SSH tunnel. Do not open port 11434 to the whole internet for a first test.
15.1 On the VPS
From your laptop, log into the server (replace user and host):
ssh YOUR_USER@YOUR_VPS_HOSTInstall Ollama:
curl -fsSL https://ollama.com/install.sh | shDownload a model that fits the VPS RAM. Example:
ollama pull llama3.2Smaller if RAM is tight: llama3.2:1b, qwen2.5:3b, phi4-mini.
Check on the VPS
ollama listcurl -sS http://127.0.0.1:11434/api/tagsYou should see the model name in the JSON. Stay logged in or keep Ollama running as a service, then you can leave this SSH session.
15.2 On the laptop — SSH tunnel
This makes the VPS look like 127.0.0.1:11434 on your machine.
Open a new terminal (Ubuntu on Windows). Do not stop pnpm dev.
Paste (same user and host as above):
ssh -N -L 11434:127.0.0.1:11434 YOUR_USER@YOUR_VPS_HOST-N means “forward ports only, no remote shell”. Leave this window open.
Open another terminal window and check:
curl -sS http://127.0.0.1:11434/api/tagsYou should see the same JSON as on the VPS.
If that fails: tunnel window closed, Ollama down, or something else already using 11434 on this machine.
If 11434 is already used on the laptop, forward a different local port:
ssh -N -L 11435:127.0.0.1:11434 YOUR_USER@YOUR_VPS_HOSTThen in Brain use base URL http://127.0.0.1:11435/v1.
15.3 Alternative: public URL
Only if you cannot use a tunnel: bind Ollama to 0.0.0.0:11434 (OLLAMA_HOST), firewall only your laptop IP, and use http://VPS_PUBLIC_IP:11434/v1 (or HTTPS). Prefer HTTPS + an allowlist.
16. Add Ollama in Brain
Stay signed in as the operator.
- In the left sidebar click Models, or open http://localhost:3000/models
- Under Start with a model, click the Ollama card (subtitle Running locally — that is correct with the tunnel). If you already have models, the header button is Add model.
- The Add model dialog opens with Ollama defaults already filled. Adjust if needed:
| Field | What to enter |
|---|---|
| Who can use this? | Defaults to This workspace. Choose Entire instance if every workspace should see it |
| Display name | Defaults to Ollama. Change to Ollama VPS if you want that label in the picker |
| Base URL | Already http://127.0.0.1:11434/v1 (keep the /v1) |
| API key (optional) | leave empty |
| Context window | Already 128000 |
- Click Fetch models (next to Base URL)
- Click the id you pulled (for example
llama3.2) so Model id fills in - Click Save
The model appears under Your models with All workspaces or This workspace, and No key.
If Fetch models fails: is the tunnel window still open? Did laptop curl to /api/tags work? Does the URL end with /v1? You can type Model id by hand from ollama list and still Save.
More: Custom models.
17. Send a test chat
- Sidebar New chat, or http://localhost:3000/chat
- In the composer, open the model menu and pick the display name you saved (for example Ollama VPS)
- Set mode to Ask (plain reply, no tools) or leave Agent. Shift+Tab switches modes — Ask vs Agent
- Paste this into the box:
Reply with exactly: Brain is running.- Press Enter
A streamed reply means install worked. Next: First chat.
Chat isn't available means no custom model and no COMMAND_CODE_API_KEY. Finish section 16, or add a Command Code key and restart pnpm dev.
Turn errors usually mean the tunnel dropped, the model id is wrong, the VPS is out of memory, or the base URL is missing /v1.
18. Quick tour of the rest of the app
You do not need to configure these on day one. Click each once so you know where it lives:
| Open | What it is |
|---|---|
/chat | Main chat. Search chats with ⌘K / Ctrl+K |
| Composer Ask / Agent | Ask = talk only. Agent = tools |
| Composer Tools (hammer icon) | Which connected apps this chat may use |
/models | Built-in and custom models |
/tools | MCP apps — Connections |
/workspaces | Switch or create workspaces |
/playbooks | Saved prompts. Click a playbook name to drop it into chat |
/schedules | Timers — automatic runs need optional BRAIN_INTERNAL_TOKEN |
/projects | Folders for chats |
/chats | Full list |
/settings/account | Name, password, sessions |
/settings/instance | Admin: policies, users, license |
/docs | This documentation |
When you connect tools later: /tools → Connect (Notion, ClickUp, …) or admin Set up then Connect (GitHub, Slack). Turn the app on for the chat. Use Agent. Writes may ask for approval. Local OAuth callback origin is http://localhost:3000.
Optional playbook test: /playbooks → add a prompt Say hello from a playbook. → click that playbook’s name.
Local pnpm dev does not run the minute cron. Use Run now (playbook schedules) or Run once (morning brief) on /schedules. Production unattended runs need BRAIN_INTERNAL_TOKEN — Schedules.
19. Next time you open the laptop
Start Docker (Docker Desktop on macOS/Windows) and wait until the engine is running.
Pick This terminal or VS Code, same as before.
cd ~/dev/brainThen:
nvm usedocker compose up -d dbpnpm devSign in at http://localhost:3000/sign-in.
If you use VPS Ollama, in a second terminal (Terminal → New Terminal in VS Code), before chatting:
ssh -N -L 11434:127.0.0.1:11434 YOUR_USER@YOUR_VPS_HOSTStop Brain with Ctrl+C in the pnpm dev window. Postgres can stay running.
20. Troubleshooting
| Symptom | What to do |
|---|---|
code: command not found | macOS: Command+Shift+P → Shell Command: Install 'code' command in PATH. Windows: reinstall VS Code with Add to PATH, then use Ubuntu |
nvm: command not found | Close the terminal and reopen. macOS: source ~/.zshrc (Homebrew nvm needs NVM_DIR in that file). Windows/Linux: source ~/.bashrc |
| Wrong Node version | cd into brain, then nvm use, then node -v must be v24 |
Use pnpm to install | Do not use npm. macOS: brew install pnpm. Windows/Linux: corepack enable, then pnpm install |
| Docker daemon error | Start Docker (Desktop on macOS/Windows, Engine on Linux) and wait |
| Database URL errors | docker compose up -d db and check .env |
/setup says Setup closed | Operator exists → /sign-in. To reset: docker compose down -v, then docker compose up -d db |
| Bootstrap token rejected | Must match BRAIN_BOOTSTRAP_TOKEN in .env exactly |
| Chat unavailable | Save a custom model, or set COMMAND_CODE_API_KEY and restart pnpm dev |
Fetch models / ECONNREFUSED 11434 | Tunnel window must stay open; curl api/tags on the laptop |
| Fetch models empty | Type the id from ollama list by hand |
| OAuth redirect mismatch | BRAIN_PUBLIC_URL and BETTER_AUTH_URL must be http://localhost:3000 |
If brain_test is missing (old Docker volume):
docker compose exec db psql -U brain -d brain -c 'CREATE DATABASE brain_test;'Optional quality gate:
export BRAIN_DATABASE_URL=postgres://brain:[email protected]:5432/brainpnpm run verifyMore: Self-hosting troubleshooting.
21. Optional: Command Code built-in models
If you have a Command Code API key, add this line to .env (not in Terminal):
COMMAND_CODE_API_KEY=paste-your-keyStop pnpm dev with Ctrl+C, then:
pnpm devOpen /models. Your models lists custom endpoints first. Built-in models lists each Command Code model with an In chat switch. Turn one off to hide it from this workspace's composer.
You can use Command Code and Ollama. Chat does not require Command Code when a custom model exists. Models overview.
Checklist
- Terminal opens
-
git --versionworks, name and email set -
nvm --versionworks after a new Terminal -
node -visv24.x -
pnpm --versionis 11+ - Docker running;
docker compose versionworks - Repo forked; cloned your fork;
pwdends with/brain - Still in this terminal or repo open in VS Code with
pwdending/brain -
pnpm installfinished -
docker compose up -d dbhealthy -
.envhas the five required values -
pnpm dev→ http://localhost:3000 -
/setupwith bootstrap token →/chat - VPS Ollama + laptop tunnel +
curlto/api/tags -
/models→ Ollama → Fetch models → Save -
/chat→ that model → a reply
Next
- Local quickstart (short command list)
- Accounts and sign-in
- First chat
- Settings map
- Production deploy
