Architecture
OpenMem connects coding agents and a shared indexer to one active memory provider. Agents use the stable memory_* MCP and session hooks; the indexer writes sources to the same provider. This page shows the full runtime paths and optional integrations. Setup (npx @bcmyguest/openmem) configures them but is outside the runtime data path. Switching providers does not migrate memories.
Runtime data flow
Section titled “Runtime data flow”Two paths share one active provider API (Hindsight, mem0, or Cognee — never more than one). Setup (npx @bcmyguest/openmem) is not on this diagram; see How openmem interfaces with providers.
| Path | What moves |
|---|---|
| Indexing | Git, Obsidian, markdown trees, feed cache → indexer → provider HTTP sink (MEMORY_SINK from manifest) |
| Agents | Cursor/Claude/Codex → session hooks and/or MCP → same provider API |
| Unified MCP | install-mcp registers openmem on the host; tools delegate to the active provider |
| LiteLLM | Optional sidecar on Hindsight stacks; also used for cross-provider reflect synthesis when PM_LLM_URL / stack LiteLLM is reachable (memory_reflect on mem0/Cognee) |
| NotebookLM sync | Opt-in, any active provider. Background sync writes into notebooklm::* via the same indexer sinks (Hindsight / mem0 / Cognee); not the same as the NotebookLM MCP |
| Provider MCP | Native mem0 or Cognee tool names (install-mcp --provider-only); same API as unified MCP, different stdio server |
| NotebookLM MCP | Read-only list/search over synced notebooks; separate entry in mcp.json, not a memory provider |
Only one provider is active at a time (MEMORY_PROVIDER). The indexer uses that provider’s HTTP sink (MEMORY_SINK / manifest).
How openmem interfaces with providers
Section titled “How openmem interfaces with providers”Product framing: Concepts.
OpenMem connects the indexer, Compose, wizard, and MCP to the selected provider through its manifest and adapter. Provider support levels come from Provider status.
Integration layers
Section titled “Integration layers”| Layer | What it is | Repo location |
|---|---|---|
| Manifest | Status, compose services, ports, indexer sink id, smoke HTTP templates | providers/<id>/manifest.json |
| Wizard hooks | Provider-specific env, keys, smoke, coding-agent notes | providers/<id>/wizard.mjs |
| Indexer sink | Poll/vault → retain/update/delete on the provider API | indexer/ (driver id in manifest, e.g. hindsight-rest-v1, mem0-rest) |
| Unified MCP | Stable memory_* tools → provider HTTP |
cli/mcp/memory-facade.mjs, cli/openmem-mcp.mjs |
| Native agent paths | Session hooks + optional plugin/MCP | cli/coding-agent/hook-runner.mjs; optional Hindsight plugin; cli/mem0-mcp.mjs, cli/cognee-mcp.mjs, NotebookLM |
Adding a provider means a new manifest + hooks + sink driver; agents can keep using memory_* once the facade implements that backend.
Runtime wiring (env and config)
Section titled “Runtime wiring (env and config)”| Input | Resolves |
|---|---|
MEMORY_PROVIDER |
Active provider (wizard.conf, optional config.toml) |
Stack .env |
API URLs, ports, MEMORY_SINK, indexer → provider URL |
| Provider secret files | e.g. ~/.config/personal-memory/mem0.env (never committed; not written to mcp.json) |
~/.config/hindsight/index.yml |
What the indexer watches |
npx @bcmyguest/openmem switch <id> updates provider selection and restarts compose; it does not migrate memories (export/import is for that).
Example: unified MCP on mem0
Section titled “Example: unified MCP on mem0”npx @bcmyguest/openmem switch mem0 --yes— compose and env point the indexer and unified MCP atMEM0_API_URL.npx @bcmyguest/openmem install-mcp --yes— merges theopenmemserver into~/.cursor/mcp.json(NotebookLM MCP only if you enabled sync or pass--notebooklm).- The agent calls
memory_addwith{ content: "…", bank: "my-project" }. The facade sendsPOST /memorieswithuser_id=my-projectandinfer: false.
install-mcp --provider-only is a different stdio server: same mem0 API, but upstream mem0 tool names from @yeyuan98/mem0-mcp. NotebookLM MCP is different again — search over notebooks synced into Hindsight, not a substitute for mem0/Cognee/Hindsight memory.
Unified MCP → provider HTTP
Section titled “Unified MCP → provider HTTP”The openmem MCP server delegates each tool to the active provider:
| Unified tool | Hindsight (HINDSIGHT_URL) |
mem0 (MEM0_API_URL + key file) |
Cognee (COGNEE_API_URL) |
|---|---|---|---|
memory_add |
POST /v1/default/banks/{bank}/memories |
POST /memories (infer: false, user_id from bank arg) |
POST /api/v1/add |
memory_search / memory_recall |
POST /v1/default/banks/{bank}/memories/recall |
POST /search with filters.user_id |
POST /api/v1/search |
memory_reflect |
Same recall path | Search + optional LiteLLM synthesis | Search + optional LiteLLM synthesis |
memory_consolidate |
LiteLLM / Hindsight consolidate routes | Skipped (no equivalent) | POST /api/v1/cognify |
memory_forget |
DELETE /v1/default/banks/{bank} (bank scope) |
DELETE /memories/{id} |
Not exposed yet |
memory_provider_status |
Returns provider id + loopback URL | Same | Same |
memory_export / memory_import |
PMM envelope; mem0 list/add — see Portable memory (PMM) |
Default scope key for MCP-created rows: bank / user_id openmem-mcp unless the tool passes bank.
Native agent paths (optional, alongside unified MCP)
Section titled “Native agent paths (optional, alongside unified MCP)”| Provider | Session / tools | Install |
|---|---|---|
| All providers | In-repo session hooks → unified memory_* |
install-coding-agent --yes |
| Hindsight (optional) | @vectorize-io/hindsight-coding-agents plugin |
install-coding-agent --hindsight-plugin |
| mem0 | @yeyuan98/mem0-mcp tools |
install-mcp --provider-only |
| Cognee | cognee_health, cognee_search |
install-mcp --provider-only |
| NotebookLM | notebooklm_list_banks, notebooklm_search |
install-mcp when sync enabled or --notebooklm |
install-mcp merges the unified openmem server by default (--no-unified-mcp to skip).
How file changes become memory
Section titled “How file changes become memory”The indexer does not watch your editor — it watches configured sources on disk (poll, inotify, or periodic re-list).
| Source | Detection | What gets sent to the provider |
|---|---|---|
| Git repo | Poll every poll_seconds (default 60): HEAD + tracked-file status |
Tree-sitter outlines + text for changed files → retain on the active sink |
| Obsidian vault | inotify; re-index after vault_quiet_seconds (default 30) without edits |
Vault documents → provider-specific banks |
| Notes / papers / bookmarks | notes.paths, papers.paths, bookmarks.paths; inotify on .md (bookmarks also .html, .txt) |
Markdown (and bookmark exports) → notes::, papers::, bookmarks:: banks |
| Feed cache | feeds.out_dir after npx @bcmyguest/openmem feed-sync (RSS / OpenAlex) |
Generated markdown → feed:: banks |
| New sources under scan roots | Re-list every relist_seconds (default 600) |
Picked up without restarting the stack |
Configuration: ~/.config/hindsight/index.yml (wizard writes this on first setup). Full source list and examples: index-sources.md · sources-feeds.md · sources-zotero.md · sources-readwise.md. Filters such as optInPaths in ~/.hindsight/coding-agent.json can limit which discovered sources are indexed.
Bank prefixes include coding-agent::, obsidian::, notes::, papers::, bookmarks::, feed::, and optional notebooklm::*. mem0 uses user_id / agent_id / run_id; Cognee uses datasets mapped from indexer banks.
Industry context
Section titled “Industry context”There is no cross-vendor standard for agent memory APIs. MCP standardizes tool transport, not memory semantics — each product exposes different tool names and shapes. openmem’s answer is a stable facade on your chosen backend so agents keep the same verbs when you switch providers.
Unified openmem MCP (beta)
Section titled “Unified openmem MCP (beta)”cli/openmem-mcp.mjs registers as the openmem server in ~/.cursor/mcp.json when you run install-mcp (unless --no-unified-mcp). It delegates to the active provider:
| Tool | Purpose |
|---|---|
memory_add |
Store text (Hindsight bank, mem0 user scope, Cognee dataset add) |
memory_search / memory_recall |
Query memories on the active backend |
memory_reflect |
Session-style context (recall or search + optional LiteLLM) |
memory_consolidate |
Cognee cognify; Hindsight notes; mem0 skip |
memory_forget |
Delete by id (mem0) or drop a Hindsight bank |
memory_provider_status |
Active provider and loopback URL (no secrets) |
memory_export / memory_import |
PMM portable format — Portable memory (PMM) |
Session hooks (all providers) call the unified MCP via cli/coding-agent/hook-runner.mjs. Optional @vectorize-io/hindsight-coding-agents with --hindsight-plugin adds a second hook set on Hindsight stacks.
Other MCP integrations
Section titled “Other MCP integrations”| Integration | Tools / path | Role |
|---|---|---|
| Session hooks | SessionStart / prompt / Stop → memory_* |
Default in-IDE session memory (all providers) |
| Hindsight plugin (optional) | Upstream retain / recall / reflect | --hindsight-plugin only |
notebooklm (install-mcp) |
notebooklm_list_banks, notebooklm_search |
Opt-in synced notebooks |
mem0 (--provider-only) |
mem0 REST tools via @yeyuan98/mem0-mcp |
Native mem0 tool names |
cognee (--provider-only) |
cognee_health, cognee_search |
Native Cognee read-only MCP |
Related
Section titled “Related”- Portable memory (PMM) — export/import
- MCP setup — unified and provider-native MCP
- Provider status — manifest status and ports
- mem0 operator guide — URL-only mem0 setup
- Cognee operator guide — loopback container + LLM env
- Configuration file —
config.tomlfor provider and stack defaults
Contributor-only guides (wizard phases, hooks, manual compose, indexer sinks, pluggable providers) live under docs/ in git and are not all published on the site. Day-to-day MCP install is on MCP setup.