{
  "markdown": "<p align=\"center\">\n  <a href=\"https://brain.inite.ai\">\n    <img src=\"https://brain.inite.ai/api/og?title=Memory%20that%20keeps%20time&kind=brand\" alt=\"INITE Brain — memory that keeps time\" width=\"100%\">\n  </a>\n</p>\n\n<h1 align=\"center\">INITE Brain</h1>\n\n<p align=\"center\">\n  <b>Open-source bitemporal knowledge graph — long-term memory for AI agents.</b><br>\n  Typed facts on a graph, two clocks per fact, hybrid retrieval, conflict-aware ingest,<br>\n  and a GDPR forget that actually deletes. Over REST and a native MCP endpoint.\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/inite-ai/inite-brain-service/actions/workflows/ci.yml\"><img src=\"https://github.com/inite-ai/inite-brain-service/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"></a>\n  <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-AGPL--3.0-blue.svg\" alt=\"License: AGPL-3.0\"></a>\n  <a href=\"https://github.com/inite-ai/inite-brain-service/stargazers\"><img src=\"https://img.shields.io/github/stars/inite-ai/inite-brain-service?style=flat\" alt=\"Stars\"></a>\n  <a href=\"CONTRIBUTING.md\"><img src=\"https://img.shields.io/badge/PRs-welcome-brightgreen.svg\" alt=\"PRs welcome\"></a>\n  <img src=\"https://img.shields.io/badge/TypeScript-3178c6.svg\" alt=\"TypeScript\">\n  <img src=\"https://img.shields.io/badge/MCP-native-ffb938.svg\" alt=\"MCP native\">\n</p>\n\n<p align=\"center\">\n  <a href=\"https://brain.inite.ai\">Website</a> ·\n  <a href=\"https://brain.inite.ai/en/docs\">Docs</a> ·\n  <a href=\"https://brain.inite.ai/en/blog\">Blog</a> ·\n  <a href=\"#quick-start\">Quick start</a> ·\n  <a href=\"#contributing\">Contributing</a>\n</p>\n\n---\n\nMost \"memory\" for AI agents is a vector store: embed text, return what looks\nsimilar. That can't tell you *when* something was true, can't reconcile two\nsources that disagree, and can't truly delete a user on request. **Brain** is\na per-tenant knowledge graph built for those jobs — a *system of insight, not\na system of record*.\n\n```mermaid\nflowchart LR\n  subgraph ingest [\"Ingest\"]\n    facts[\"facts · mentions · links\"]\n    docs[\"documents<br/>Source → Indexer → Candidates\"]\n  end\n  ext[\"external indexers ✳<br/>pull work API\"] --> docs\n  packs[\"Domain Packs ✳<br/>registry · marketplace\"] -. \"predicates · indexers<br/>seed documents\" .-> ingest\n  facts --> resolver[\"conflict resolver<br/>+ trust snapshot\"]\n  docs --> resolver\n  resolver --> kg[(\"bitemporal graph<br/>two clocks per fact\")]\n  kg --> entry[\"entry legs — doors into the graph<br/>vector + BM25 over typed facts\"]\n  entry --> rank[\"graph-native ranking<br/>ontology router → entity buckets →<br/>edge walk → PPR → rerank\"]\n  rank --> rest[\"REST /v1\"]\n  rank --> mcp[\"MCP per tenant<br/>+ pack tools ✳\"]\n```\n\n✳ = extension points for third parties — see [Build on Brain](#build-on-brain).\n\n## Why Brain\n\n- **Two clocks per fact.** Every fact carries *valid time* (when it was true)\n  and *transaction time* (when Brain learned it). Query `now`, or replay\n  exactly what the graph knew on any past date. History is replayed, never\n  rewritten.\n- **Graph-first retrieval, not a cosine match.** The unit of retrieval is a\n  typed fact on the graph — never a text chunk. Vector + BM25 (+ HyPE) are\n  only the *doors in*: they seed candidate facts from a free-text query, and\n  everything after is graph-native — ontology-driven predicate/type router,\n  per-entity bucketing with degree boost, 1-hop edge expansion, tier-aware\n  PPR over the candidate subgraph, then cross-encoder + listwise LLM rerank,\n  with bitemporal closure and trust/corroboration multipliers throughout.\n  Queries that already name their anchors skip the doors entirely:\n  `graph_retrieve` and the multi-hop planner walk the graph from entities.\n- **Conflict-aware ingest.** Two ingests for one fact go through a scored\n  ladder; close calls land as `COMPETING`, not a silent overwrite.\n- **Source-aware trust.** A fact isn't *true* — it's *claimed by a source,\n  trusted under context*. Every fact records who claimed it plus a reputation\n  snapshot taken at write time; reputation is **domain-scoped** (a source strong\n  on one predicate isn't trusted blindly on another), agreement across sources\n  **corroborates**, and the trust that moves a ranking is stored with its\n  \"because\" decomposition — never recomputed behind your back.\n- **Per-key access policies (ABAC).** Scopes say *may this key search*;\n  policy sets say *what it may see*: allow/deny rules over MCP tools and REST\n  actions, plus row-level read filtering by predicate, PII class, source\n  vertical, projected document metadata (`data_class: pii`), numeric trust\n  thresholds, and corroboration. Deny-overrides, report-only rollout, per-rule\n  explain, and a visual policy editor + Key Lens simulator in the admin UI.\n  See [`docs/abac.md`](docs/abac.md).\n- **Pluggable ontology — as a platform.** Domain Packs extend the predicate\n  registry without forking core: signed, versioned JSON manifests that carry\n  predicates, extraction tuning, eval fixtures, indexer descriptors, seed\n  documents, and MCP tools. A six-pack industry library ships in-repo\n  (real-estate, fintech, medical, legal, insurance, HR); a global registry\n  with immutable versions, verified-publisher badges, download counters, and\n  pull-only mirroring closes the publish → discover → install loop.\n- **An execution seam for third parties.** External indexers contribute\n  knowledge over a pull work API — poll → claim → read content → submit\n  candidates — without ever running inside Brain's process. Every submitted\n  span is re-grounded against the stored document text, and indexer trust is\n  earned through the nightly refit, not granted.\n- **Pack-declared MCP tools.** A pack can extend a tenant's MCP surface:\n  declarative query tools locked to its own predicates, or HMAC-signed proxies\n  to a publisher-operated endpoint. Registered only with explicit operator\n  consent, flag-gated, never in-process code.\n- **A marketplace with honest defaults.** Featured curation, publisher\n  profiles, and paid packs via a central billing service (per-pack\n  entitlements, self-describing 402 → checkout → retry, fail-closed when\n  billing is unreachable). With billing off — the default — every pack\n  installs free: the self-hosted posture.\n- **A document pipeline, not an upload button.** Ingestion is split into four\n  layers — *Source* (a normalized document; Brain doesn't know what a PDF is) →\n  *Indexer* (composable domain readers: one meeting can be read by the meetings,\n  sales, and tasks indexers at once) → *Candidates* (\"this MIGHT be a fact\" — a\n  staged hypothesis, not yet memory) → *Brain* (merge, dedupe, conflict-resolve,\n  then commit). Stored documents can be **re-indexed** when a new pack lands,\n  and corroboration is keyed on the *origin document*, so two indexers reading\n  the same source never masquerade as independent evidence.\n- **Per-user memory scope, provenance-first.** A fact can belong to one end\n  user, and that scope survives the whole pipeline — episode ingest, derived\n  worlds, retrieval, profiles, retraction (ownership-fenced). Every derived\n  fact keeps pointers to the verbatim turns it came from:\n  `GET /v1/facts/:id/provenance` shows *why the system remembers*, and\n  `GET /v1/users/:id/profile` assembles a deterministic, prompt-ready profile\n  from one user's own memory — no silent fact-mining, nothing you can't\n  inspect or erase.\n- **Versioned derived worlds.** Memory can be re-derived from the raw episode\n  substrate (session-window derivation: the whole conversation as the unit of\n  understanding, not one turn) into a NEW versioned world — built in a\n  per-run staging namespace under a lease and promoted with one atomic flip —\n  while readers stay pinned to the previous world until the swap.\n- **A forget that deletes.** GDPR erasure is a synchronous hard cascade —\n  facts, edges, and embeddings gone, only an HMAC tombstone left to prove it.\n  Works at entity scope and at end-user scope (`POST /v1/users/:id/forget`).\n- **Native MCP.** A per-tenant Streamable HTTP endpoint with scope-aware tools.\n  Hermes, Claude Desktop, Cursor, Goose, n8n — same URL, no glue code; stdio-only\n  harnesses connect via the [`@inite/brain-mcp`](https://www.npmjs.com/package/@inite/brain-mcp) connector.\n- **Eval-gated in CI.** Every push re-runs the retrieval + memory-lifecycle\n  suite; a regression past tolerance blocks the merge.\n\n## Quick start\n\nSelf-host the whole stack with Docker:\n\n```bash\ngit clone https://github.com/inite-ai/inite-brain-service\ncd inite-brain-service\n\ndocker compose up -d surrealdb     # storage\npnpm install\ncp .env.example .env               # set OPENAI_API_KEY + BRAIN_API_KEYS\npnpm start:dev\n```\n\nIngest a fact, then search for it:\n\n```bash\ncurl -X POST localhost:3000/v1/ingest/fact \\\n  -H \"Authorization: Bearer $BRAIN_KEY\" -H \"Content-Type: application/json\" \\\n  -d '{ \"entityRef\": {\"vertical\":\"rent\",\"id\":\"cust_42\"},\n        \"predicate\": \"complained_about\", \"object\": \"late maintenance\",\n        \"validFrom\": \"2026-05-05T10:00:00Z\",\n        \"source\": {\"vertical\":\"rent\",\"messageId\":\"msg_1\"} }'\n\ncurl -X POST localhost:3000/v1/search \\\n  -H \"Authorization: Bearer $BRAIN_KEY\" -H \"Content-Type: application/json\" \\\n  -d '{ \"query\": \"maintenance issues\", \"limit\": 5 }'\n```\n\nPrefer not to run it? The same API is hosted at **[brain.inite.ai](https://brain.inite.ai)**.\nFull walkthrough: [Getting started](https://brain.inite.ai/en/docs/getting-started).\n\n## Connect an agent\n\nBrain is an MCP server, so any MCP-capable agent gets long-term memory by\npointing at the per-tenant URL with a Bearer key — no glue code.\n\n- **Harnesses with native remote MCP** (Hermes, Claude Desktop, Cursor, Goose v2,\n  n8n, Continue.dev) connect directly. Add brain to the harness's MCP config with\n  `url: https://brain.inite.ai/mcp/<companyId>` and an `Authorization: Bearer <key>`\n  header. Example for [Hermes](https://hermes-agent.nousresearch.com)\n  (`~/.hermes/config.yaml`):\n\n  ```yaml\n  mcp_servers:\n    brain:\n      url: \"https://brain.inite.ai/mcp/<companyId>\"\n      headers:\n        Authorization: \"Bearer <api-key>\"\n  ```\n\n- **stdio-only harnesses** that can't attach an auth header (openclaw, Goose 1.x)\n  spawn the first-party [`@inite/brain-mcp`](https://www.npmjs.com/package/@inite/brain-mcp)\n  connector, which transparently proxies every scoped tool over Streamable HTTP:\n\n  ```json\n  { \"mcp\": { \"servers\": { \"brain\": {\n    \"command\": \"npx\", \"args\": [\"-y\", \"@inite/brain-mcp\"],\n    \"env\": { \"BRAIN_API_KEY\": \"brain_xxx\", \"BRAIN_COMPANY_ID\": \"<companyId>\" }\n  }}}}\n  ```\n\nFull per-client guide: [MCP setup](https://brain.inite.ai/en/docs/mcp/setup).\nInstalled Domain Packs can extend the tool surface with their own consented,\nflag-gated tools — see [MCP pack tools](docs/mcp-pack-tools.md).\n\n## Feed it documents\n\nBeyond single facts and 16K mentions, Brain ingests whole normalized documents\nthrough the **Source → Indexer → Candidates → Brain** pipeline (flagged off by\ndefault — set `DOCUMENT_INGEST_ENABLED=1`):\n\n```bash\ncurl -X POST localhost:3000/v1/ingest/document \\\n  -H \"Authorization: Bearer $BRAIN_KEY\" -H \"Content-Type: application/json\" \\\n  -d '{ \"kind\": \"markdown\", \"title\": \"Q3 review with Acme\",\n        \"text\": \"<normalized document text, up to 512K chars>\",\n        \"occurredAt\": \"2026-07-01T10:00:00Z\",\n        \"contextRef\": {\"vertical\": \"crm\"} }'\n```\n\nThe document is stored (content-hash deduped, PII-redacted, chunked), read by\nthe generalist indexer — plus any Domain Pack that opted into a **dedicated\nrun** and matched the relevance router — staged as candidates you can audit at\n`GET /v1/documents/:id/candidates`, and only then committed through the same\nconflict-resolution ladder as every other fact. Connectors own raw formats\n(PDF, email, chat exports); Brain owns understanding what was read.\n\nWhat that buys:\n\n- **Composable indexers.** Every pack's facts are attributed by predicate\n  namespace out of the union extraction call at zero extra LLM cost; packs\n  that need their own prompt budget or model declare\n  `indexer: { mode: \"dedicated\" }` in their manifest and are routed per\n  document (`DOCUMENT_MULTI_INDEXER_ENABLED=1`).\n- **Re-indexing.** Install a new pack and replay it over stored documents —\n  `POST /v1/admin/documents/reindex` or automatically with\n  `REINDEX_ON_PACK_INSTALL=1`. The run ledger skips whatever a pack version\n  already processed.\n- **Honest corroboration.** Facts carry `originKey = doc:<contentHash>`;\n  agreement only counts as independent evidence when it comes from a\n  *different document*, not a different reader of the same one.\n- **A privacy dial.** `storeContent: false` keeps only the content hash and\n  metadata — extraction still runs, but nothing to re-index or leak later.\n\n## Build on Brain\n\nBrain is a platform, not just a service: third parties extend the ontology,\nthe ingestion plane, and the tool surface without a PR to this repo.\n\n- **Author a Domain Pack.** `pnpm pack:init` scaffolds a valid manifest;\n  edit → `pack:validate` → `pack:sign` (ed25519) → `pack:publish` →\n  `pack:install`. A pack is JSON — no compiled module, no fork.\n  [Domain Packs](docs/domain-packs.md).\n- **Publish to the global registry.** Immutable versions, yank-not-delete,\n  verified-publisher badges, download counters, and pull-only cross-instance\n  mirroring (`REGISTRY_UPSTREAM_URL`). Public catalogue at `GET /registry/ui`.\n  [Registry](docs/domain-packs.md#the-registry-global-catalogue).\n- **Sell it on the marketplace.** Hosting instances can feature packs, render\n  publisher profiles, and price packs through the central billing service —\n  the entitlement `domain_pack:<packId>` gates the install, and a refused\n  install is a self-describing 402 with the checkout path. Billing off =\n  everything installs free. [Marketplace](docs/domain-packs.md#marketplace).\n- **Run an external indexer.** A plain HTTP client polls for routed documents,\n  claims a lease, reads stored text, and submits candidate facts that Brain\n  re-grounds and adjudicates. Protocol: [indexer-protocol.md](docs/indexer-protocol.md);\n  dependency-free reference client: [`examples/reference-indexer.ts`](examples/reference-indexer.ts)\n  (`pnpm indexer:reference`).\n- **Declare MCP tools.** Packs contribute query tools over their own\n  predicates or HMAC-proxied external tools, installed only with explicit\n  operator consent (`acceptMcpTools`). [MCP pack tools](docs/mcp-pack-tools.md).\n- **Ship knowledge with the pack.** `seedDocuments` in the manifest are\n  ingested through the normal document pipeline on install — same chunking,\n  staging, conflict resolution, and provenance as any connector's document.\n  [Seed documents](docs/domain-packs.md#seed-documents-consumed).\n\nThe platform surface is machine-described in\n[`docs/openapi.json`](docs/openapi.json) (OpenAPI 3.1, regenerate with\n`pnpm openapi:build`).\n\n## Quality (latest gate run)\n\n```\nrecall@1                 0.962  [0.94–0.98]   n=262\nrecall@3                 0.989  [0.97–1.00]   n=262\nMRR                      0.976  [0.96–0.99]   n=262\nNDCG@10                  0.973  [0.96–0.99]\nidentity-resolution-f1   1.000\npii-gating-correctness   1.000\nmemory-lifecycle         1.000\nfaithfulness pass-rate   1.000  n=3\n```\n\nCI floors: recall@1 ≥ 0.6, recall@3 ≥ 0.8, MRR ≥ 0.5, identity-F1 ≥ 0.8,\npii-gating = 1.0, memory-lifecycle = 1.0, faithfulness ≥ 0.8. Bootstrap-CI on\nevery retrieval metric, with a per-predicate breakdown and per-vertical +\ntemporal/current split in the report. Numbers from the multi-vertical scenario\nsuite plus 180 wikidata queries (90 Latin + 90 Cyrillic).\nMethodology: [`docs/eval.md`](docs/eval.md).\n\n## Stack\n\nNestJS 11 + TypeScript on Node 22 · SurrealDB 3.x (HNSW + BM25, one database\nper tenant) · BGE-M3 embeddings (ONNX, runs locally in a worker thread) ·\nOpenAI `gpt-4o-mini` for extraction / synthesize / verifier · optional Cohere\nRerank or a local ONNX cross-encoder · a SurrealDB-native job queue ·\nOpenTelemetry. CPU-heavy work (embeddings, cross-encoder, NLI intent routing,\nlocal NER, label propagation, token counting) runs in `worker_threads` so the\nevent loop keeps serving HTTP, and `PROCESS_ROLE=api|worker` splits one image\ninto an HTTP pod and a jobs pod when a deployment outgrows a single process.\nShips as a Docker image; runs on any host.\n\n## Documentation\n\nThe hub with per-persona routing lives at [`docs/README.md`](docs/README.md).\n\n| | |\n|---|---|\n| **Get going** | [Getting started](docs/getting-started.md) · [Migration guide](docs/migration-guide.md) |\n| **Understand it** | [Architecture](docs/architecture.md) · [API reference](docs/api.md) · [OpenAPI 3.1 spec](docs/openapi.json) (platform surface, generated) · [Data model](docs/data-model.md) · [Bitemporal semantics](docs/bitemporal-semantics.md) · [Source reputation & trust](docs/source-reputation.md) · [ABAC access policies](docs/abac.md) · [Document pipeline](docs/document-pipeline.md) · [Fact provenance API](docs/fact-provenance-api.md) · [User profile API](docs/user-profile-api.md) |\n| **Extend it** | [Domain Packs](docs/domain-packs.md) (registry + marketplace + seed documents) · [External indexer protocol](docs/indexer-protocol.md) · [MCP pack tools](docs/mcp-pack-tools.md) · [Listing playbook](docs/distribution.md) · [Code memory](docs/roadmap/code-memory-domain.md) |\n| **Run it** | [Operations](docs/operations.md) · [Operator playbook](docs/operator-playbook.md) · [Deploy runbook](docs/DEPLOY.md) |\n| **Measure it** | [Eval methodology](docs/eval-methodology.md) (strict-judge protocol + measured judge inflation) · [Eval harness](docs/eval.md) · [LoCoMo benchmark](docs/locomo.md) |\n\nA reader-friendly version of the docs lives at\n**[brain.inite.ai/en/docs](https://brain.inite.ai/en/docs)** (also in Russian).\n\n## Contributing\n\nPRs are welcome — from typo fixes to new retrieval legs. Good first issues are\ntagged [`good first issue`](https://github.com/inite-ai/inite-brain-service/issues?q=is%3Aopen+label%3A%22good+first+issue%22).\n\n```bash\npnpm install\ndocker compose up -d surrealdb\ncp .env.example .env          # OPENAI_API_KEY needed for ingest/search\npnpm start:dev                # run the service\npnpm test                     # unit tests — must pass before a PR\npnpm test:eval                # retrieval-quality eval (needs an OpenAI key)\n```\n\nTwo hard bars for every PR: **tests + the eval gate pass** (a retrieval\nregression past tolerance blocks merge), and **schema changes ship as new\nnumbered migrations** in `src/db/migrations/`. Details in\n[`CONTRIBUTING.md`](CONTRIBUTING.md). Please also read the\n[`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md). Found a vulnerability? Don't open a\npublic issue — see [`SECURITY.md`](SECURITY.md).\n\n## Roadmap\n\nShipped: bitemporal graph, hybrid retrieval pipeline, conflict resolution,\ndomain-scoped source reputation + cross-source corroboration + a read-only\ntrust-inputs API, identity merge, GDPR forget, native MCP, per-key ABAC\npolicy sets, the document pipeline with an external-indexer protocol\n(pull work API + signed webhook hints + reference client), Domain Packs\n(industry library, signed global registry with verified badges, download\ncounters and pull-only mirroring, marketplace with paid packs, pack-declared\nMCP tools, seed documents), OpenAPI 3.1 platform spec, worker-thread offloads\n+ `PROCESS_ROLE` api/worker split, code memory (record *why* a decision was\nmade, drift-resistant symbol anchors), eval-gated CI, off-hours\nself-improvement (dreams), the raw episode substrate with versioned derived\nworlds (atomic per-run staged rebuilds, lease-fenced promotion, read pins),\nend-to-end per-user memory scope (episode ingest → derivation → retrieval →\nprofile → ownership-fenced retraction), fact-provenance + rolling\nuser-profile read APIs, measured genre presets over the retrieval profile,\nand long-horizon conversational memory benchmarks run under a strict judge\n([LoCoMo](docs/locomo.md), LongMemEval, BEAM — protocol in\n[docs/eval-protocol.md](docs/eval-protocol.md)).\n\nExploring (issues + ideas welcome): a non-conversational (document / KG) eval\naxis on the same harness, failure-memory for agents (distill what went wrong\ninto reusable strategies), prospective-memory / preference-drift benchmarks,\nextractor span-grounding offload, and worker-pool right-sizing as more\nhandlers move to threads. Temporal was evaluated and deliberately not\nadopted — the re-evaluation triggers live in\n[docs/roadmap/platform-gap-2026-07.md](docs/roadmap/platform-gap-2026-07.md).\nHave a use case? Open an issue.\n\n## License\n\n[AGPL-3.0-or-later](LICENSE). Brain is a hosted backend service, so AGPL is the\nhonest choice: if you run Brain (modified or not) for users over a network, you\nmake the corresponding source available to them under the same terms. If AGPL is\nincompatible with your downstream needs, open an issue — we may relicense specific\nmodules when the request is reasonable.\n",
  "bytes": 20885,
  "sha": "9cf12c7eecc8a96ef8d5c4fb9c1adab6aa3846ba28f31413da7ccafb37d29657",
  "repo_slug": "inite-ai/inite-brain-service",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_inite_ai_inite_brain_service_bbe375e3/readme"
}