Getting started
Two ways to run the same brain: hosted at brainz.brownmatter.ai (free, remote MCP
over HTTP) or local-first from a folder of markdown (open source CLI, MCP over stdio). Both
expose the identical vault toolset, so your orchestrator doesn't care which one it's talking
to.
Hosted: remote MCP in two minutes
- Sign up — it's free — and create a vault.
- In the vault's settings, create an API key. Keys look like
bz_…, are scoped to that one vault, and are shown exactly once — store it like a secret. - Add the server to your MCP client. In a project's
.mcp.json:
{
"mcpServers": {
"brainz": {
"type": "http",
"url": "https://brainz.brownmatter.ai/mcp",
"headers": { "Authorization": "Bearer bz_..." }
}
}
} Or with the Claude Code CLI:
claude mcp add --transport http brainz https://brainz.brownmatter.ai/mcp \
--header "Authorization: Bearer bz_..." That's the whole integration. Your orchestrator can now call vault_stats to orient
itself, search_concepts to explore, and get_context to brief
subagents. Clients that support MCP discovery can also find the server themselves via /.well-known/mcp.json (registry name ai.brownmatter/brainz).
Agent-driven signup: human in the loop, not in the way
An orchestrator doesn't need a pre-made account. Point it at https://brainz.brownmatter.ai/mcp without an Authorization header and it gets a public MCP server exposing
two tools — signup and sign_in (the fourteen vault tools stay behind
authentication):
# 1. connect UNAUTHENTICATED — no Authorization header
# initialize → tools/list shows two public tools: signup and sign_in
# 2. provision a workspace — no email, no human action required
→ tools/call signup { "vaultName": "Acme brain" }
# 3. the result is everything the agent needs — and no URL of any kind
← {
"apiKey": "bz_…", // works immediately — keep it secret
"vaultSlug": "acme-brain",
"expiresAt": "2026-07-18T…", // workspace expires in 7 days unless claimed
"claimEmailSent": false
}
# 4. keep it: the claim tool (authenticated) emails YOUR HUMAN an approval link
→ tools/call claim { "email": "you@company.com" }
← { "status": "sent", "expiresAt": "…" } // link goes to the inbox, never to the agent The apiKey works immediately — the agent reconnects to the same endpoint with Authorization: Bearer bz_… and can start seeding the vault right away. The
workspace is provisional: it expires in 7 days unless a human
claims it. To keep it, the agent calls the claim tool with its human's email — the
approval link is emailed to the human and never returned to the agent, so an
agent can never see, open, or leak it. Passing email to signup fires
the same claim request in one call. Returning humans use the sign_in tool instead:
a one-time magic sign-in link lands in their inbox — no password to choose, ever (Brainz is passwordless). Signups are rate-limited to 5 per hour per IP.
Bring your team
A vault isn't a solo brain. From the vault's settings, owners invite teammates by email — each
invite is a single-use link that expires in 14 days — and
assign a role: owner (everything, including keys, members, and invites), editor (read and write concepts and tasks), or viewer (read-only).
Roles are enforced on every REST route and MCP call, so a colleague in the dashboard and an
agent holding an API key play by the same rules. Humans and agents share one brain.
Onboard your product
A fresh vault is an empty brain. The onboard tool fixes that without you writing a
single note: your orchestrator calls onboard with {"action": "start"} and receives a playbook — fan subagents out over
the codebase, distill what they find into the product ontology, and write it back with upsert_concept.
The ontology is eleven concept types, and five of them carry the structure: domain (high-level product areas — the top of the graph), feature (concrete capabilities, part_of a domain), story (user stories, realized_by the
features that deliver them), spec (the rules that govern features and
stories), and workflow (multi-step journeys across features) — plus task (a unit of work not yet in the codebase, claimed off a real-time Kanban board via take_task) and the classics: concept, decision, constraint, pattern, glossary. Every concept can carry code_areas — rough paths or globs
pointing at where that knowledge lives in the codebase — so a subagent briefed by get_context learns the rules and where to apply them.
Onboarding is a loop, not a one-shot: the agent indexes an area of the codebase, calls onboard with {"action": "status", "areaList"} to see
which areas are covered and which aren't, and keeps going until coverage is broad — expect
hundreds of concepts on a real codebase, not dozens. {"action": "complete",
"summary", "areaList"} is coverage-gated: it rejects if too many areas are still
uncovered. Until it succeeds, search_concepts and get_context responses carry a one-line reminder — a nudge, never a wall. Local vaults get the same flow via brainz onboard.
Local-first: a vault is just a folder
The open-source CLI runs the same engine against a directory of markdown. Notes are plain files
with YAML frontmatter; the search index is derived SQLite in .brainz/ — gitignored,
safe to delete, rebuilt from your files.
# scaffold a vault (config + concepts/ + a sample note)
npx brainz init my-vault
# add concepts and link them
npx brainz add "Billing Engine" --vault my-vault --type feature --body "Handles invoicing."
npx brainz add "Ledger" --vault my-vault --body "Double-entry ledger."
npx brainz link billing-engine ledger --relation depends_on --vault my-vault
# query it
npx brainz search "billing" --vault my-vault
npx brainz context --query "billing" --budget 800 --vault my-vault Serve the vault to your agents over stdio MCP:
{
"mcpServers": {
"brainz": {
"command": "npx",
"args": ["brainz", "mcp", "--vault", "/absolute/path/to/my-vault"]
}
}
} (Running the brainz-mcp binary directly? It can take the vault directory from the BRAINZ_VAULT environment variable instead of a flag.)
Search is hybrid (full-text + embeddings, fused by reciprocal rank); if an embedding provider
isn't configured or available, it degrades gracefully to keyword-only.
The fourteen MCP tools
These names and descriptions are the exact text your orchestrator sees — lifted from the tool registry that both the hosted and local servers register from, so they never drift.
| Tool | Description |
|---|---|
search_concepts Search concepts | Search the product knowledge vault by free-text query. Use this first, whenever you need product knowledge but don't yet know which concept ids exist — e.g. before planning work that touches a feature, decision, or constraint. Returns ranked hits (id, title, type, score, snippet) only; follow up with get_concept for one full note or get_context for an injectable bundle. Never errors on odd queries — an empty hit list just means nothing matched. |
get_concept Get concept | Fetch one concept by exact id: full markdown body, metadata, and its direct graph neighbors (each with the relation that connects it). Use after search_concepts or when another note wiki-links an id you need in full. The neighbors list tells you what to fetch next. If you don't know the id, use search_concepts instead. |
get_related Get related concepts | Walk the knowledge graph outward from a concept and return everything within `depth` hops, with distance and the edge path that reached it. Use to map the blast radius before changing a feature (what depends on it, what constrains it, which decisions apply) or to discover structure that keyword search misses. Filter by relation names (e.g. depends_on) to follow only one kind of edge. |
get_context Assemble context bundle | THE tool to call before delegating a coding task: assembles a ready-to-inject markdown briefing of the most relevant concepts (seeded by a search query and/or explicit ids, expanded through the graph) trimmed to a token budget. Paste the returned markdown straight into a subagent's prompt so it gets curated product knowledge without you relaying individual notes. The final JSON line reports which concept ids were included, whether the bundle was truncated, and its approximate token count. Provide at least one of `query` or `ids`. |
upsert_concept Create or update concept | Write a concept note into the vault (creates or overwrites the markdown file, then reindexes it). Use to capture new product knowledge discovered during a task — a decision made, a constraint hit, a pattern adopted — so future agents can find it. Omit `id` to derive a slug from the title; pass an existing id to update that note. Body is markdown; [[wiki-links]] to other concept ids create graph edges. Returns the saved concept's metadata. |
delete_concept Delete concept | Remove a concept from the vault and all of its outgoing edges. Use to clear a note that is wrong, obsolete, or junk (e.g. a probe or test node that shouldn't be in the graph). Idempotent: deleting an id that doesn't exist is a no-op success (deleted:false), not an error. Deletion is permanent — prefer upsert_concept to correct a note you want to keep. Returns { deleted, id }. |
link_concepts Link concepts | Add a typed, directed edge between two existing concepts by editing the `from` note's frontmatter (e.g. lead-scoring depends_on contact-model). Use when you notice a relationship the vault is missing. Both concepts should already exist; use upsert_concept first if not. |
list_concepts List concepts | Enumerate concept metadata (no bodies), optionally filtered by product, type, or a single tag. Use to get the lay of the land in an unfamiliar vault, to audit what exists (e.g. all decisions for a product), or when search vocabulary isn't matching. For content, follow up with get_concept or get_context. |
vault_stats Vault stats | Cheap orientation call: counts of concepts and edges, the products and tags in use, a breakdown by concept type, and whether semantic search is available. Call once when connecting to an unfamiliar vault to calibrate how much knowledge is here and which product/tag filters exist. |
onboard Onboard this vault | Step 1 on any new vault: onboarding turns an existing product's codebase into the knowledge graph your whole agent fleet shares. Call {action: "start"} to receive the onboarding playbook — instructions for fanning subagents out over the codebase and distilling product knowledge (domains, features, stories, specs, workflows, decisions, constraints) into concepts via upsert_concept, each anchored to the code with codeAreas. There is NO flat concept cap — size the effort from the codebase; for a large project expect 200–800+ concepts and do NOT stop at a few dozen. Onboarding is a LOOP: index an area, then call {action: "status", areaList} (you supply your repo's source areas — Brainz can't read the repo) to see covered vs uncovered areas; keep indexing the uncovered ones until coverage is broad. When it is, call {action: "complete", summary, areaList} to mark the vault onboarded and store the summary — complete is coverage-gated and rejects if too many areas are still uncovered. {action: "status"} reports onboarded state, concept counts, and (with areaList) coverage. Until onboarding completes, search_concepts and get_context results carry a reminder to run it. |
list_tasks List tasks | List the vault's work pile: `task`-type concepts with their lifecycle (open/taken/done), oldest first. Call to survey what's outstanding before claiming work, to check what a teammate agent is already doing (taskStatus "taken" with takenBy), or to audit completed work. Filter by taskStatus or by the domain the tasks are part_of. To actually pick up work, use take_task — don't just read. |
take_task Take a task off the pile | Claim a unit of work and get briefed in one call. Pass an `id` to claim a specific task, or omit it to claim THE next open task (deterministic: oldest open by createdAt then id) — safe to call repeatedly to drain the pile. Atomically flips the task to "taken" and records takenBy/takenAt; errors if it's already taken or done. Returns the task AND an auto-assembled get_context-grade briefing for its part_of domain plus the concepts it realizes / is governed_by (with code_areas) — paste that straight into your implementation. THE CONTRACT: after implementing, verify the artifact matches every spec that governs the task; fix or file a new task for any discrepancy; then index the new/changed knowledge via upsert_concept and call complete_task. |
complete_task Complete a task | Mark a task done once the work is in the artifact. Sets taskStatus=done + doneAt and appends your `outcome` to the task body as an Outcome section. The result reminds you to index what changed via upsert_concept so the knowledge graph stays true to the codebase — do that before moving on. |
create_task Create a task | Turn a finding into first-class work: creates a `task`-type concept with taskStatus=open and the given relations — part_of a domain, `realizes` stories/features, `governed_by` specs — plus codeAreas pointing at where the work lands. Use when you discover work that isn't reflected in the codebase yet (a gap, a needed fix, a follow-up). The task then shows up in list_tasks / take_task and on the Kanban board. |
One convention worth knowing: get_context responds with two text blocks — first the
assembled markdown briefing (paste it straight into a subagent prompt), then a single-line JSON
footer { included, truncated, approxTokens }. Every other tool
responds with one JSON text block — except onboard {"action": "start"},
which returns the playbook as one markdown block.
Where to go next
- Create a free vault and point an orchestrator at it — the fastest way
to feel the
get_contextloop. - Or just tell your agent to set itself up: point it at https://brainz.brownmatter.ai/skill.md — one pasted prompt and it walks itself through signup, key configuration, claiming the workspace for you, and onboarding.
- Onboard your product: point your orchestrator at the vault and have it
call the
onboardtool — it maps your codebase into domains, features, stories, specs, and workflows, each anchored to the code that implements it. - Tell your orchestrator (e.g. in
CLAUDE.md) to callget_contextbefore delegating, andupsert_conceptwhen it learns something worth keeping.