INITE Brain
Open-source bitemporal knowledge graph β long-term memory for AI agents.
Typed facts on a graph, two clocks per fact, hybrid retrieval, conflict-aware ingest,
and a GDPR forget that actually deletes. Over REST and a native MCP endpoint.
Website Β·
Docs Β·
Blog Β·
Quick start Β·
Contributing
Most "memory" for AI agents is a vector store: embed text, return what looks
similar. That can't tell you when something was true, can't reconcile two
sources that disagree, and can't truly delete a user on request. Brain is
a per-tenant knowledge graph built for those jobs β a system of insight, not
a system of record.
flowchart LR
subgraph ingest ["Ingest"]
facts["facts Β· mentions Β· links"]
docs["documents<br/>Source β Indexer β Candidates"]
end
ext["external indexers β³<br/>pull work API"] --> docs
packs["Domain Packs β³<br/>registry Β· marketplace"] -. "predicates Β· indexers<br/>seed documents" .-> ingest
facts --> resolver["conflict resolver<br/>+ trust snapshot"]
docs --> resolver
resolver --> kg[("bitemporal graph<br/>two clocks per fact")]
kg --> entry["entry legs β doors into the graph<br/>vector + BM25 over typed facts"]
entry --> rank["graph-native ranking<br/>ontology router β entity buckets β<br/>edge walk β PPR β rerank"]
rank --> rest["REST /v1"]
rank --> mcp["MCP per tenant<br/>+ pack tools β³"]
β³ = extension points for third parties β see Build on Brain.
Why Brain
- Two clocks per fact. Every fact carries valid time (when it was true)
and transaction time (when Brain learned it). Query
now, or replay
exactly what the graph knew on any past date. History is replayed, never
rewritten.
- Graph-first retrieval, not a cosine match. The unit of retrieval is a
typed fact on the graph β never a text chunk. Vector + BM25 (+ HyPE) are
only the doors in: they seed candidate facts from a free-text query, and
everything after is graph-native β ontology-driven predicate/type router,
per-entity bucketing with degree boost, 1-hop edge expansion, tier-aware
PPR over the candidate subgraph, then cross-encoder + listwise LLM rerank,
with bitemporal closure and trust/corroboration multipliers throughout.
Queries that already name their anchors skip the doors entirely:
graph_retrieve and the multi-hop planner walk the graph from entities.
- Conflict-aware ingest. Two ingests for one fact go through a scored
ladder; close calls land as
COMPETING, not a silent overwrite.
- Source-aware trust. A fact isn't true β it's claimed by a source,
trusted under context. Every fact records who claimed it plus a reputation
snapshot taken at write time; reputation is domain-scoped (a source strong
on one predicate isn't trusted blindly on another), agreement across sources
corroborates, and the trust that moves a ranking is stored with its
"because" decomposition β never recomputed behind your back.
- Per-key access policies (ABAC). Scopes say may this key search;
policy sets say what it may see: allow/deny rules over MCP tools and REST
actions, plus row-level read filtering by predicate, PII class, source
vertical, projected document metadata (
data_class: pii), numeric trust
thresholds, and corroboration. Deny-overrides, report-only rollout, per-rule
explain, and a visual policy editor + Key Lens simulator in the admin UI.
See docs/abac.md.
- Pluggable ontology β as a platform. Domain Packs extend the predicate
registry without forking core: signed, versioned JSON manifests that carry
predicates, extraction tuning, eval fixtures, indexer descriptors, seed
documents, and MCP tools. A six-pack industry library ships in-repo
(real-estate, fintech, medical, legal, insurance, HR); a global registry
with immutable versions, verified-publisher badges, download counters, and
pull-only mirroring closes the publish β discover β install loop.
- An execution seam for third parties. External indexers contribute
knowledge over a pull work API β poll β claim β read content β submit
candidates β without ever running inside Brain's process. Every submitted
span is re-grounded against the stored document text, and indexer trust is
earned through the nightly refit, not granted.
- Pack-declared MCP tools. A pack can extend a tenant's MCP surface:
declarative query tools locked to its own predicates, or HMAC-signed proxies
to a publisher-operated endpoint. Registered only with explicit operator
consent, flag-gated, never in-process code.
- A marketplace with honest defaults. Featured curation, publisher
profiles, and paid packs via a central billing service (per-pack
entitlements, self-describing 402 β checkout β retry, fail-closed when
billing is unreachable). With billing off β the default β every pack
installs free: the self-hosted posture.
- A document pipeline, not an upload button. Ingestion is split into four
layers β Source (a normalized document; Brain doesn't know what a PDF is) β
Indexer (composable domain readers: one meeting can be read by the meetings,
sales, and tasks indexers at once) β Candidates ("this MIGHT be a fact" β a
staged hypothesis, not yet memory) β Brain (merge, dedupe, conflict-resolve,
then commit). Stored documents can be re-indexed when a new pack lands,
and corroboration is keyed on the origin document, so two indexers reading
the same source never masquerade as independent evidence.
- Per-user memory scope, provenance-first. A fact can belong to one end
user, and that scope survives the whole pipeline β episode ingest, derived
worlds, retrieval, profiles, retraction (ownership-fenced). Every derived
fact keeps pointers to the verbatim turns it came from:
GET /v1/facts/:id/provenance shows why the system remembers, and
GET /v1/users/:id/profile assembles a deterministic, prompt-ready profile
from one user's own memory β no silent fact-mining, nothing you can't
inspect or erase.
- Versioned derived worlds. Memory can be re-derived from the raw episode
substrate (session-window derivation: the whole conversation as the unit of
understanding, not one turn) into a NEW versioned world β built in a
per-run staging namespace under a lease and promoted with one atomic flip β
while readers stay pinned to the previous world until the swap.
- A forget that deletes. GDPR erasure is a synchronous hard cascade β
facts, edges, and embeddings gone, only an HMAC tombstone left to prove it.
Works at entity scope and at end-user scope (
POST /v1/users/:id/forget).
- Native MCP. A per-tenant Streamable HTTP endpoint with scope-aware tools.
Hermes, Claude Desktop, Cursor, Goose, n8n β same URL, no glue code; stdio-only
harnesses connect via the
@inite/brain-mcp connector.
- Eval-gated in CI. Every push re-runs the retrieval + memory-lifecycle
suite; a regression past tolerance blocks the merge.
Quick start
Self-host the whole stack with Docker:
git clone https://github.com/inite-ai/inite-brain-service
cd inite-brain-service
docker compose up -d surrealdb # storage
pnpm install
cp .env.example .env # set OPENAI_API_KEY + BRAIN_API_KEYS
pnpm start:dev
Ingest a fact, then search for it:
curl -X POST localhost:3000/v1/ingest/fact \
-H "Authorization: Bearer $BRAIN_KEY" -H "Content-Type: application/json" \
-d '{ "entityRef": {"vertical":"rent","id":"cust_42"},
"predicate": "complained_about", "object": "late maintenance",
"validFrom": "2026-05-05T10:00:00Z",
"source": {"vertical":"rent","messageId":"msg_1"} }'
curl -X POST localhost:3000/v1/search \
-H "Authorization: Bearer $BRAIN_KEY" -H "Content-Type: application/json" \
-d '{ "query": "maintenance issues", "limit": 5 }'
Prefer not to run it? The same API is hosted at brain.inite.ai.
Full walkthrough: Getting started.
Connect an agent
Brain is an MCP server, so any MCP-capable agent gets long-term memory by
pointing at the per-tenant URL with a Bearer key β no glue code.
- Harnesses with native remote MCP (Hermes, Claude Desktop, Cursor, Goose v2,
n8n, Continue.dev) connect directly. Add brain to the harness's MCP config with
url: https://brain.inite.ai/mcp/<companyId> and an Authorization: Bearer <key>
header. Example for Hermes
(~/.hermes/config.yaml):