Brain MCP
by DevvGwardo
README.md
<div align="center">
<p align="center">
<img src="docs/brain-mcp-banner.png" alt="Hermes Brain banner" width="100%">
</p>
# Hermes Brain
**Multi-agent orchestration for [Hermes Agent](https://github.com/NousResearch/hermes-agent)**
Spawn parallel Hermes agents. Give them a shared brain. Ship in one command.<br>Backed by SQLite, coordinated by Python, zero tokens spent on coordination.
<br>
[](LICENSE)
[](https://python.org)
[](https://nodejs.org)
[](https://github.com/NousResearch/hermes-agent)
[](https://modelcontextprotocol.io)
<br>
[Install](#install) · [Quick Start](#quick-start) · [How It Works](#how-it-works) · [CLI](#the-hermes-brain-cli) · [Tools](#brain-tools) · [Memory Bank](#memory-bank-persistent-context) · [Development](#development)
<br>
</div>
---
## Install
**Option 1 — bootstrap from source (recommended for Hermes)**
```bash
curl -fsSL https://raw.githubusercontent.com/DevvGwardo/brain-mcp/main/install.sh | bash
```
The installer:
1. Builds the Node.js MCP server (`brain-mcp`)
2. Installs the Python orchestration package (`hermes-brain`)
3. Registers the brain as an MCP server in Hermes
**Option 2 — manual install**
```bash
git clone https://github.com/DevvGwardo/brain-mcp.git
cd brain-mcp
npm install
npm run build
pip install -e .
hermes mcp add brain --command node --args "$PWD/dist/index.js"
```
**Note:** the npm package is not published yet, so the repository install path is the supported path for now.
**Verify:**
```bash
hermes mcp list | grep brain
hermes mcp test brain
hermes-brain --help
```
**Prerequisites:** Python 3.10+, Node.js 18+, [Hermes Agent](https://github.com/NousResearch/hermes-agent)
**Sharing with friends?** Each person's brain is its own isolated SQLite DB — no network config needed. Same one-liner works anywhere.
**Docker users:** Spawn agents with `layout: "headless"` since tmux panes can't render in a headless container:
```python
brain_wake({ task: "...", layout: "headless" })
```
---
## Quick Start
**One command to orchestrate a fleet of Hermes agents:**
```bash
hermes-brain "Build a REST API with auth, users, and posts" \
--agents api-routes auth-layer db-models tests
```
What happens:
1. Python conductor spawns 4 background Hermes agents (`hermes -q`)
2. Each agent claims its files, publishes contracts, writes code, pulses heartbeats
3. Conductor runs an **integration gate** — compiles the project, routes errors back to responsible agents via DM
4. Agents self-correct. Gate retries until clean.
5. Summary printed: agents, contracts, memories, metrics, done.
**More ways to run it:**
```bash
# Auto-named agents
hermes-brain "Add error handling to the whole codebase"
# Mix models per task
hermes-brain "Build a game" --agents engine ui store --model claude-sonnet-4-5
# Cheap model for boilerplate
hermes-brain "Generate 10 test files" --model claude-haiku-4-5
# JSON pipeline with multiple phases
hermes-brain --config pipeline.json
```
**Or from inside Hermes (interactive):**
```
hermes> Use register, then wake to spawn 3 agents
that each refactor a different module.
```
---
## How It Works
<p align="center">
<img src="docs/brain-mcp-diagram-how-it-works.png" alt="How It Works diagram" width="90%">
</p>
### Architecture
This diagram shows the internal architecture of brain-mcp and how its components interact:
<p align="center">
<img src="docs/brain-mcp-diagram-architecture.png" alt="Architecture diagram" width="90%">
</p>
**pi-agent-core** is the LLM agent runtime — handles the model interaction loop, tool execution, and event subscription. **brain-mcp** provides the coordination layer (state, messaging, heartbeats, locks, contracts) as tools that pi agents call. The **conductor** ties it all together with phases, gates, and tmux layout.
**Zero-token coordination.** The conductor is pure Python — LLM tokens are only spent on the actual work. Heartbeats, claims, contracts, gates, retries all run locally.
**No server to manage.** Each agent opens its own stdio connection to the brain. SQLite WAL mode handles concurrent access safely.
**Same brain, any CLI.** Hermes, Claude Code, MiniMax — all clients hit the same SQLite DB. A mixed fleet of Hermes + Claude agents can coordinate on the same task.
---
## The `hermes-brain` CLI
```bash
hermes-brain <task> [options]
```
| Flag | Default | What it does |
|:-----|:--------|:-------------|
| `--agents <names...>` | `agent-1 agent-2` | Agent names to spawn in parallel |
| `--model <id>` | `claude-sonnet-4-5` | Model passed to each agent |
| `--no-gate` | off | Skip integration gate |
| `--retries <n>` | `3` | Max gate retry attempts |
| `--timeout <seconds>` | `600` | Per-agent timeout |
| `--config <file.json>` | | Load a multi-phase pipeline |
| `--db-path <path>` | `~/.claude/brain/brain.db` | Custom brain DB |
### Pipeline config file
```json
{
"task": "Build a todo app",
"model": "claude-sonnet-4-5",
"gate": true,
"max_gate_retries": 3,
"phases": [
{
"name": "foundation",
"parallel": true,
"agents": [
{ "name": "types", "files": ["src/types/"], "task": "Define all TS types" },
{ "name": "db", "files": ["src/db/"], "task": "Set up Prisma schema" }
]
},
{
"name": "feature",
"parallel": true,
"agents": [
{ "name": "api", "files": ["src/api/"], "task": "REST endpoints" },
{ "name": "ui", "files": ["src/ui/"], "task": "React components" }
]
},
{
"name": "quality",
"parallel": true,
"agents": [
{ "name": "tests", "task": "Write unit + integration tests" }
]
}
]
}
```
Phases run sequentially. Agents within a phase run in parallel. The integration gate runs between phases.
---
## Brain Tools
**35+ tools across 12 categories.** All available to Hermes, Claude Code, and any MCP-compatible agent.
### Identity & Health
| Tool | What it does |
|:-----|:-------------|
| `brain_register` | Name this session |
| `brain_sessions` | List active sessions |
| `brain_status` | Show session info + room |
| `brain_pulse` | Heartbeat with status + progress (returns pending DMs) |
| `brain_agents` | Live health of all agents (status, heartbeat age, claims) |
### Messaging
| Tool | What it does |
|:-----|:-------------|
| `brain_post` | Post to a channel |
| `brain_read` | Read from a channel |
| `brain_dm` | Direct message another agent |
| `brain_inbox` | Read your DMs |
### Shared State & Memory
| Tool | What it does |
|:-----|:-------------|
| `brain_set` / `brain_get` | Ephemeral key-value store |
| `brain_keys` / `brain_delete` | List / remove keys |
| `brain_remember` | Store persistent knowledge (survives `brain_clear`) |
| `brain_recall` | Search memories from previous sessions |
| `brain_forget` | Remove outdated memories |
### File Locking
| Tool | What it does |
|:-----|:-------------|
| `brain_claim` | Lock a file/resource (TTL-based mutex) |
| `brain_release` | Unlock |
| `brain_claims` | List active locks |
### Contracts (prevents integration bugs)
| Tool | What it does |
|:-----|:-------------|
| `brain_contract_set` | Publish what your module provides / expects |
| `brain_contract_get` | Read other agents' contracts before coding |
| `brain_contract_check` | Validate all contracts — catches param mismatches, missing functions |
### Integration Gate
| Tool | What it does |
|:-----|:-------------|
| `brain_gate` | Run compile + contract check, DM errors to responsible agents |
| `brain_auto_gate` | Run gate in a loop, wait for fixes, retry until clean |
### Task Planning (DAG)
| Tool | What it does |
|:-----|:-------------|
| `brain_plan` | Create a task DAG with dependencies |
| `brain_plan_next` | Get tasks whose dependencies are satisfied |
| `brain_plan_update` | Mark task done/failed (auto-promotes dependents) |
| `brain_plan_status` | Overall progress |
| `brain_workflow_compile` | Turn one natural-language goal into phases, agents, file scopes, and conductor config |
| `brain_workflow_apply` | Persist the compiled workflow into brain state + a task DAG, optionally write conductor JSON |
### Orchestration
| Tool | What it does |
|:-----|:-------------|
| `brain_wake` | Spawn a new agent (hermes, claude, or headless) |
| `brain_swarm` | Spawn multiple agents in one call |
| `brain_respawn` | Replace a failed agent with recovery context |
| `brain_metrics` | Success rates, duration, error counts per agent |
### Context Ledger (prevents losing track)
| Tool | What it does |
|:-----|:-------------|
| `brain_context_push` | Log action/discovery/decision/error |
| `brain_context_get` | Read the ledger |
| `brain_context_summary` | Condensed view for context recovery |
| `brain_checkpoint` | Save full working state |
| `brain_checkpoint_restore` | Recover after context compression |
---
## Heartbeat & Contract Protocol
Every spawned agent follows two protocols that the orchestrator enforces:
**Heartbeat** — agents call `brain_pulse` every 2-3 tool calls with their status and a short progress note. The conductor uses this to:
- Show live status in the terminal (`● working — editing src/api/routes.ts`)
- Detect stalled agents (no pulse in 60s → `stale`)
- Deliver pending DMs as pulse return values (no extra round-trip)
**Contracts** — before agents write code, they call `brain_contract_get` to see what other agents export. After writing, they publish their own contract with `brain_contract_set`. Before marking done, `brain_contract_check` validates the whole fleet — catches:
- Function signature mismatches (expected 2 args, got 3)
- Missing exports (agent A imports `getUser` but agent B never exported it)
- Type drift (expected `User`, got `{name, email}`)
This is the key to matching single-agent integration quality with a parallel fleet.
---
## Integration Gate
<p align="center">
<img src="docs/brain-mcp-diagram-integration-gate.png" alt="Integration Gate sequence diagram" width="90%">
</p>
The gate auto-detects the project language and runs the appropriate checker:
| Language | Checker |
|:---------|:--------|
| TypeScript | `npx tsc --noEmit` |
| Python | `mypy` |
| Rust | `cargo check` |
| Go | `go vet` |
Errors are parsed, matched to the agent that claimed the failing file, and routed as a DM. Agents pick up their errors on the next pulse and self-correct. The loop retries up to `--retries` times before giving up.
---
## Mixed Fleets
The brain DB is shared across all MCP clients. A single project can have:
<p align="center">
<img src="docs/brain-mcp-diagram-mixed-fleets.png" alt="Mixed Fleets diagram" width="70%">
</p>
Route by task type. Use Hermes for routine work, Claude for architectural decisions, cheaper models for boilerplate — all coordinating through the same brain, sharing contracts, gates, memory.
From Claude Code:
```
brain_wake({ task: "...", cli: "hermes", layout: "headless" })
brain_wake({ task: "...", cli: "claude", layout: "horizontal" })
```
---
# Advanced
Everything below covers the full technical depth.
---
## Performance
Run the benchmarks yourself:
```bash
node benchmark.mjs # SQLite direct layer (1000 iterations)
node benchmark-mcp.mjs # MCP tool layer (30 iterations per tool)
```
### SQLite Direct Layer (2026-04-06, M4 Pro, WAL mode)
| Operation | avg | p50 | p95 | p99 | throughput |
|:----------|:----|:----|:----|:----|:-----------|
| session_register | 0.021ms | 0.011ms | 0.027ms | 0.039ms | ~47K/s |
| message_post (1 msg) | 0.014ms | 0.011ms | 0.019ms | 0.031ms | ~70K/s |
| message_read (50 msgs) | 0.042ms | 0.042ms | 0.045ms | 0.066ms | ~24K/s |
| state_get | 0.002ms | 0.002ms | 0.002ms | 0.003ms | ~570K/s |
| claim_query (all) | 0.001ms | 0.001ms | 0.002ms | 0.002ms | ~670K/s |
| heartbeat_pulse (update) | 0.002ms | 0.002ms | 0.002ms | 0.003ms | ~464K/s |
| session_query (by id) | 0.002ms | 0.002ms | 0.002ms | 0.003ms | ~455K/s |
Direct SQLite: every core coordination operation is sub-millisecond. The KV store (state_get) sustains ~570K reads/s. High-frequency coordination (heartbeats, claims, state) stays well under 1ms.
### MCP Tool Layer (2026-04-06, stdio JSON-RPC, 30 calls each)
| Tool | avg | p50 | p95 | min | max |
|:-----|:----|:----|:----|:----|:----|
| brain_status | 12.2ms | 12.0ms | 15.6ms | 8.8ms | 21.2ms |
| brain_sessions | 1.9ms | 1.7ms | 3.6ms | 0.9ms | 4.7ms |
| brain_keys | 1.6ms | 1.6ms | 2.6ms | 0.8ms | 4.5ms |
| brain_claims | 2.0ms | 1.8ms | 3.4ms | 1.2ms | 4.9ms |
| brain_metrics | 2.0ms | 1.9ms | 4.0ms | 1.1ms | 4.4ms |
MCP tool calls include JSON-RPC framing, stdio IPC, TypeScript tool dispatch, and SQLite query. Most tools respond in 1-2ms once the server is warm. `brain_status` is slower (12ms) because it aggregates session data from all rooms — 3000+ sessions were present during the benchmark.
### What this means in practice
- **High-frequency coordination** (heartbeats every 2-3 agent turns, claim/release, state get/set): always goes through Python `hermes.db.BrainDB` directly — not the MCP layer. Sub-millisecond, no stdio overhead.
- **Agent-level operations** (spawn, gate, contract check, swarm): use MCP tools. 1-5ms per call is fine — these happen once per agent, not per turn.
- **Zero-token coordination overhead**: the entire coordination layer (messaging, locking, state, heartbeats) adds no LLM token cost. Tokens are only spent on actual work.
---
## Architecture Deep Dive
<p align="center">
<img src="docs/brain-mcp-diagram-deep-dive.png" alt="Architecture Deep Dive diagram" width="90%">
</p>
**Design decisions:**
- **Dual access paths** — Agents use MCP (stdio) via `brain-mcp`. The Python orchestrator uses `hermes.db.BrainDB` for direct, fast access to the same SQLite file.
- **One process per session** — No long-running daemon. Each agent opens its own stdio.
- **WAL mode + 5s busy timeout** — Multiple writers serialize safely.
- **Heartbeat-based liveness** — Agents dead in 60s = stale, dead in 5m = cleaned up.
- **Room scoping** — Working directory is the default room. Override with `BRAIN_ROOM`.
---
## Spawned Agent Lifecycle (Hermes Headless)
<p align="center">
<img src="docs/brain-mcp-diagram-lifecycle.png" alt="Spawned Agent Lifecycle diagram" width="90%">
</p>
---
## Auto-Recovery
If an agent crashes or goes stale, the orchestrator spawns a replacement with full context:
<p align="center">
<img src="docs/brain-mcp-diagram-auto-recovery.png" alt="Auto-Recovery sequence diagram" width="90%">
</p>
The replacement inherits the original task, knows what files the failed agent touched, and has context about their last known progress.
---
## Database Schema
<p align="center">
<img src="docs/brain-mcp-diagram-er-schema.png" alt="Database Schema ER diagram" width="90%">
</p>
## Database Schema Notes
**Database location:** `~/.claude/brain/brain.db`
The brain DB is a single [SQLite](https://sqlite.org) file with WAL mode enabled for concurrent access. 14 tables cover sessions, messaging, state, claims, contracts, memory, plans, metrics, and the context ledger.
---
## Configuration Reference
| Variable | Default | Description |
|:---------|:--------|:------------|
| `BRAIN_SESSION_NAME` | `session-{pid}` | Pre-set session name |
| `BRAIN_SESSION_ID` | uuid | Pre-set session id (used by orchestrator) |
| `BRAIN_ROOM` | Working directory | Override room grouping |
| `BRAIN_DB_PATH` | `~/.claude/brain/brain.db` | Custom database path |
| `BRAIN_DEFAULT_CLI` | `claude` | Default CLI for `brain_wake` (`hermes`/`claude`) |
| `HERMES_MODEL` | | Model passed to spawned hermes agents |
---
## Using Brain Tools Directly From Hermes
If you don't want the Python CLI, you can orchestrate directly from inside a Hermes session:
```
hermes> register with name "lead"
hermes> set key="task" value="refactor auth" scope="room"
hermes> wake name="worker-1" task="..." cli="hermes" layout="headless"
hermes> wake name="worker-2" task="..." cli="hermes" layout="headless"
hermes> agents # monitor health
hermes> auto_gate # run gate loop until clean
```
If Hermes shows namespaced picker entries such as `mcp_brain_wake`, use the
exact picker name. Do not prepend `brain_` yourself.
The tools work identically in interactive mode, headless mode, and across mixed fleets.
---
## Claude Code (Visible tmux Panes)
Brain also supports spawning Claude Code sessions in tmux split panes for visual orchestration:
<p align="center">
<img src="docs/brain-mcp-diagram-tmux-warroom.png" alt="Claude Code tmux warroom diagram" width="80%">
</p>
From Claude Code, say *"Refactor the API with 3 agents"* — the lead splits the work, spawns 3 Claude sessions in tmux panes, each with a unique colored border, and coordinates through the brain.
**Layouts:** `headless` (Hermes default), `horizontal`, `vertical`, `tiled`, `window`
---
## Memory Bank (Persistent Context)
brain-mcp handles coordination between agents — but it doesn't hold context between waves. Subagents are spawned, do their work, post results, and exit. The orchestrator collects everything.
**The problem:** If you run 5 waves of agents, each new wave starts with zero memory of what happened before. The brain KV store is ephemeral.
**The solution:** GSD-inspired memory bank pattern. One file, one source of truth, orchestrator as memory bank.
```
Orchestrator
│
│ MAINTAINS: ~/.hermes/.brain/STATE.md
│
│ PER WAVE:
│ brain-export-context() → brain_set("task_context", $SLICE)
│ brain_wake(agent, goal + context)
│
│ AFTER RESULTS:
│ brain-read-results() → update STATE.md
│ brain-record-done() / brain-record-decision()
│
└── Subagents: read context, do work, post results, exit
```
### Quick Start
```bash
# 1. Source the helper script
source ~/brain-mcp/scripts/brain-memory.sh
# 2. Initialize a session
brain-init "my-project" "session-123"
# 3. Before each wave — get context slice
CTX=$(brain-export-context "auth" "fix login bug")
brain_set "task_context" "$CTX"
brain_wake "agent-1" "fix auth bug"
# 4. After results — update state
brain-record-done 1 "agent-1" "Fixed race condition in token refresh"
brain-complete-agent "agent-1"
# 5. Dump state anytime
brain-dump
```
### State File Structure
```markdown
## Session → Project, session ID, status
## Current Phase → init | planning | executing | reviewing | complete
## Orchestrator Memory → Accumulated context (the "memory")
## Agent Context → Per-agent status and work tracking
## Files Under Work → Who is editing what (claim/release)
## Session Log → Wave-by-wave history for resume
```
### Key Principles
| Principle | Why |
|-----------|-----|
| One file, not KV | STATE.md is the source of truth. brain KV is transport only. |
| Orchestrator writes | Subagents read + propose. Orchestrator updates state. |
| Slices, not dumps | Each agent gets only what it needs. Keep it lean. |
| Git-diffable | STATE.md is human-readable, git-tracked, resumable. |
| Persistent | Survives agent restarts. Brain KV does not. |
### What's Included
```
skills/brain-memory-bank/ # Full skill documentation
├── SKILL.md # Pattern guide + examples
scripts/
├── brain-memory.sh # Bash helpers (source this in your workflow)
│
.brain/ # (created at runtime)
└── STATE.md # Persistent session state
```
### Before vs After
| Without Memory Bank | With Memory Bank |
|---------------------|------------------|
| Wave 3 agent asks "what did wave 1 do?" | Reads STATE.md — knows exactly |
| Orchestrator forgets blocker from wave 2 | Blockers persist in STATE.md |
| No shared context between waves | Context accumulated across waves |
| Agents start cold every wake | Agents get relevant context slice |
---
## Development
```bash
# Node.js MCP server
npm run dev # watch mode
npm run build # compile TypeScript
npm start # run server
# Python orchestrator
pip install -e . # install hermes-brain
python -m hermes.cli "task" --agents a b c
```
**Repo layout:**
```
brain-mcp/
├── src/ # TypeScript MCP server (brain-mcp)
│ ├── index.ts # Tool definitions (30+ tools)
│ ├── db.ts # SQLite layer
│ ├── conductor.ts # brain_wake / brain_swarm logic
│ └── gate.ts # Integration gate
├── hermes/ # Python orchestration (hermes-brain)
│ ├── cli.py # hermes-brain CLI entry point
│ ├── orchestrator.py # Conductor — spawn, wait, gate, retry
│ ├── db.py # Direct SQLite access (shares brain.db)
│ ├── gate.py # Compiler + contract checks
│ └── prompt.py # Agent prompt templates
├── skills/
│ └── brain-memory-bank/ # GSD-style persistent context skill
│ └── SKILL.md # Memory bank pattern documentation
├── scripts/
│ └── brain-memory.sh # Bash helpers for orchestrator workflows
├── benchmark.mjs # SQLite layer benchmark (1000 iterations)
├── benchmark-mcp.mjs # MCP tool layer benchmark (30 calls per tool)
├── setup-hermes.sh # Full installer
└── pyproject.toml # Python package config
```
---
<div align="center">
<br>
Python 3.10+ · Node.js 18+ · [Hermes Agent](https://github.com/NousResearch/hermes-agent) · [MCP Protocol](https://modelcontextprotocol.io)
[MIT License](LICENSE)
<br>
</div>
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues