Architecture
brainjar is a client-server system. The CLI is a thin client that manages your agent configuration. The server stores all content and state.
Components
Section titled “Components”CLI (@brainjar/cli)
Section titled “CLI (@brainjar/cli)”The command-line tool you interact with. It handles:
- Creating and managing souls, personas, rules, and brains
- Composing prompts for subagent orchestration
- Syncing active configuration into your agent’s config file (
CLAUDE.mdorAGENTS.md) - Downloading and managing the server binary
The CLI makes HTTP requests to the server for every operation. It stores almost nothing locally — just a small config file at ~/.brainjar/config.yaml.
Server (brainjar-server)
Section titled “Server (brainjar-server)”A Go binary that provides the REST API and stores all content. It connects to a Postgres database that you provide. It runs in one of two modes:
| Mode | Description |
|---|---|
| Local | Managed by the CLI. Auto-downloaded, auto-started. Requires Postgres on localhost:2724. |
| Remote | You run the server yourself (Docker, bare metal, cloud). CLI connects to it by URL. |
Local mode is the default. When you run brainjar init, the CLI downloads the server binary from get.brainjar.sh, starts it in the background, and creates your workspace. The server auto-creates the brainjar database and runs migrations on first connect.
You can also install the server binary manually:
curl -fsSL https://get.brainjar.sh/install.sh | shLocal files
Section titled “Local files”The only thing stored locally:
~/.brainjar/ config.yaml # server contexts, backend bin/brainjar-server # server binary (local mode only) server.pid # process ID (local mode only) server.log # server logs (local mode only) server-version # installed version trackerAll content (souls, personas, rules, brains) and state (what’s active) lives on the server.
Config file
Section titled “Config file”~/.brainjar/config.yaml uses named contexts to manage multiple servers:
version: 2current_context: localcontexts: local: url: http://localhost:7742 mode: local bin: ~/.brainjar/bin/brainjar-server pid_file: ~/.brainjar/server.pid log_file: ~/.brainjar/server.log workspace: default staging: url: https://staging.brainjar.example.com mode: remote workspace: defaultbackend: claudeThe local context is always present. Each context has its own URL, mode, and workspace. Switch between them with brainjar context use <name>.
Server modes
Section titled “Server modes”Local mode (default)
Section titled “Local mode (default)”brainjar init --defaultThe CLI:
- Creates the config file at
~/.brainjar/config.yaml - Downloads the server binary from
get.brainjar.sh - Starts it in the background (connects to Postgres on
localhost:2724) - Creates the
defaultworkspace - Seeds starter content (if
--defaultis passed) - Writes
CLAUDE.mdwith the active configuration
If Postgres isn’t running, the CLI will suggest a Docker one-liner to start it.
Manage the local server with:
brainjar server status # check health, PID, mode, server versionbrainjar server logs # view server logsbrainjar server stop # stop the daemonbrainjar server start # start the daemonRemote mode
Section titled “Remote mode”Add a remote server as a named context:
brainjar context add staging https://brainjar.example.combrainjar context use stagingThis is useful for teams sharing a single server, or for running the server in Docker:
docker run -d \ -e BRAINJAR_POSTGRES_HOST=your-postgres-host \ -e BRAINJAR_POSTGRES_PORT=2724 \ -e BRAINJAR_POSTGRES_USERNAME=brainjar \ -e BRAINJAR_POSTGRES_PASSWORD=brainjar \ -e BRAINJAR_POSTGRES_DATABASE=brainjar \ -p 7742:7742 \ ghcr.io/brainjar-sh/server:latestOr use the included docker-compose.yml to run both the server and Postgres together:
docker compose up -dSwitch back to local:
brainjar context use localManaging contexts
Section titled “Managing contexts”brainjar context list # list all contextsbrainjar context add prod <url> # add a remote contextbrainjar context use staging # switch active contextbrainjar context show # show active context detailsbrainjar context rename old new # rename a contextbrainjar context remove staging # remove a contextWorkspaces
Section titled “Workspaces”A workspace is an isolated namespace for all your content. By default, brainjar init creates a workspace called default. All content operations happen within your active workspace.
How sync works
Section titled “How sync works”When you change the active soul, persona, or rules, the CLI fetches the composed configuration from the server and writes it to your agent’s config file:
- Claude Code:
~/.claude/CLAUDE.md(global) or.claude/CLAUDE.md(project) - Codex:
~/.codex/AGENTS.md(global) or.codex/AGENTS.md(project)
Sync runs automatically after any state-changing command (use, drop, add, remove). You can also trigger it manually:
brainjar syncUpgrading
Section titled “Upgrading”Upgrade both CLI and server in one command:
brainjar upgradeOr upgrade selectively:
brainjar upgrade --cli-only # just the CLIbrainjar upgrade --server-only # just the server binaryThe server upgrade always targets the local binary, regardless of which context is active.
Version compatibility
Section titled “Version compatibility”The CLI checks the server version on connect. If the server is too old for the CLI, you’ll get a clear error:
Server v0.2.3 is incompatible with this CLI (requires >= 0.2.4).Run `brainjar upgrade` to update both CLI and server.Check the current server version with brainjar server status.