@bcmyguest/openmem 0.0.0-stage → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +136 -2
  3. package/bin/hindsight-project-index +530 -0
  4. package/cli/coding-agent/access-policy.mjs +38 -0
  5. package/cli/coding-agent/agents.mjs +34 -0
  6. package/cli/coding-agent/bank-from-cwd.mjs +140 -0
  7. package/cli/coding-agent/capabilities.mjs +23 -0
  8. package/cli/coding-agent/hook-harnesses.mjs +87 -0
  9. package/cli/coding-agent/hook-runner.mjs +260 -0
  10. package/cli/coding-agent/install-access.mjs +93 -0
  11. package/cli/coding-agent/install-shim.mjs +97 -0
  12. package/cli/coding-agent/opencode-config.mjs +91 -0
  13. package/cli/coding-agent/opencode-plugin.mjs +96 -0
  14. package/cli/coding-agent/runtime.mjs +39 -0
  15. package/cli/coding-agent/session-facade.mjs +62 -0
  16. package/cli/cognee-mcp.mjs +260 -0
  17. package/cli/feed-sync.mjs +11 -0
  18. package/cli/install-coding-agent.mjs +165 -0
  19. package/cli/install-memory-mcp.mjs +426 -0
  20. package/cli/is-main.mjs +18 -0
  21. package/cli/mcp/context.mjs +61 -0
  22. package/cli/mcp/export/cognee-dataset-name.mjs +12 -0
  23. package/cli/mcp/export/cognee.mjs +119 -0
  24. package/cli/mcp/export/hindsight.mjs +48 -0
  25. package/cli/mcp/export/index.mjs +26 -0
  26. package/cli/mcp/export/mem0.mjs +31 -0
  27. package/cli/mcp/llm-synthesize.mjs +50 -0
  28. package/cli/mcp/mem0-scope-id.mjs +22 -0
  29. package/cli/mcp/memory-facade.mjs +455 -0
  30. package/cli/mcp/memory-reflect-consolidate.mjs +120 -0
  31. package/cli/mcp/notebooklm-banks.mjs +21 -0
  32. package/cli/mcp/notebooklm-hindsight-rest.mjs +45 -0
  33. package/cli/mcp/notebooklm-provider.mjs +225 -0
  34. package/cli/mcp/pmm-records.mjs +23 -0
  35. package/cli/mcp/portability.mjs +158 -0
  36. package/cli/mcp/stdio.mjs +65 -0
  37. package/cli/mcp/unified-mcp-install.mjs +65 -0
  38. package/cli/mem0-mcp.mjs +108 -0
  39. package/cli/notebooklm-mcp.mjs +236 -0
  40. package/cli/openmem-mcp.mjs +35 -0
  41. package/cli/openmem.mjs +205 -0
  42. package/cli/roots.mjs +85 -0
  43. package/cli/stack.mjs +436 -0
  44. package/cli/switch-memory-provider.mjs +358 -0
  45. package/cli/wiring-report.mjs +125 -0
  46. package/compose.bench.yaml +12 -0
  47. package/compose.yaml +164 -0
  48. package/config/coding-agent.json +13 -0
  49. package/config/hindsight.env.example +24 -0
  50. package/config/index.yml +54 -0
  51. package/config/litellm.lemond.yaml +40 -0
  52. package/config/litellm.ollama.yaml +33 -0
  53. package/config/notebooklm.yml +33 -0
  54. package/config/openmem.toml.example +62 -0
  55. package/docs/OPENMEM.md +23 -0
  56. package/docs/architecture.md +219 -0
  57. package/docs/assets/README.md +10 -0
  58. package/docs/assets/setup-demo.gif +0 -0
  59. package/docs/coding-agent-hooks.md +51 -0
  60. package/docs/coding-agent-scopes.md +22 -0
  61. package/docs/coding-agents.md +51 -0
  62. package/docs/cognee.md +37 -0
  63. package/docs/concepts.md +112 -0
  64. package/docs/hindsight.md +74 -0
  65. package/docs/index-sources-roadmap.md +38 -0
  66. package/docs/index-sources.md +39 -0
  67. package/docs/indexer-sinks.md +122 -0
  68. package/docs/indexing.md +57 -0
  69. package/docs/manual-stack-setup.md +74 -0
  70. package/docs/mcp-install-guide.md +4 -0
  71. package/docs/mcp-setup.md +101 -0
  72. package/docs/mem0.md +103 -0
  73. package/docs/memory-portability.md +73 -0
  74. package/docs/memory-providers.md +246 -0
  75. package/docs/model-configuration.md +84 -0
  76. package/docs/notebooklm.md +83 -0
  77. package/docs/npx-install.md +170 -0
  78. package/docs/openmem-config.md +194 -0
  79. package/docs/provider-wizard-hooks.md +222 -0
  80. package/docs/quickstart.md +101 -0
  81. package/docs/setup-wizard.md +116 -0
  82. package/docs/sources-feeds.md +52 -0
  83. package/docs/sources-readwise.md +23 -0
  84. package/docs/sources-zotero.md +22 -0
  85. package/glama.json +4 -0
  86. package/indexer/Dockerfile +38 -0
  87. package/indexer/code_outline.py +146 -0
  88. package/indexer/feed_sync.py +107 -0
  89. package/indexer/index_config.py +290 -0
  90. package/indexer/pytest.ini +5 -0
  91. package/indexer/sinks/__init__.py +148 -0
  92. package/indexer/sinks/_http.py +44 -0
  93. package/indexer/sinks/cognee.py +329 -0
  94. package/indexer/sinks/hindsight.py +107 -0
  95. package/indexer/sinks/mem0.py +247 -0
  96. package/indexer/watch.py +240 -0
  97. package/package.json +95 -4
  98. package/providers/_template/compose.yaml +52 -0
  99. package/providers/cognee/OPERATOR.md +82 -0
  100. package/providers/cognee/compose.yaml +89 -0
  101. package/providers/cognee/lib/clack.mjs +157 -0
  102. package/providers/cognee/lib/coding-agent.mjs +26 -0
  103. package/providers/cognee/lib/cognee-mcp-install.mjs +153 -0
  104. package/providers/cognee/lib/config.mjs +98 -0
  105. package/providers/cognee/lib/env-file.mjs +194 -0
  106. package/providers/cognee/lib/env-setup.mjs +83 -0
  107. package/providers/cognee/lib/llm-env.mjs +382 -0
  108. package/providers/cognee/lib/ports.mjs +25 -0
  109. package/providers/cognee/lib/smoke.mjs +246 -0
  110. package/providers/cognee/lib/stack-env.mjs +134 -0
  111. package/providers/cognee/lib/state.mjs +101 -0
  112. package/providers/cognee/lib/summary.mjs +56 -0
  113. package/providers/cognee/lib/validate.mjs +97 -0
  114. package/providers/cognee/manifest.json +56 -0
  115. package/providers/cognee/wizard.mjs +134 -0
  116. package/providers/graphiti/manifest.json +15 -0
  117. package/providers/hindsight/lib/clack.mjs +245 -0
  118. package/providers/hindsight/lib/coding-agent.mjs +204 -0
  119. package/providers/hindsight/lib/config.mjs +73 -0
  120. package/providers/hindsight/lib/env-setup.mjs +71 -0
  121. package/providers/hindsight/lib/litellm-routes.mjs +187 -0
  122. package/providers/hindsight/lib/model-backend.mjs +214 -0
  123. package/providers/hindsight/lib/notebooklm-mcp-install.mjs +127 -0
  124. package/providers/hindsight/lib/ollama-compose.mjs +51 -0
  125. package/providers/hindsight/lib/ports.mjs +30 -0
  126. package/providers/hindsight/lib/probe.mjs +33 -0
  127. package/providers/hindsight/lib/stack-env.mjs +132 -0
  128. package/providers/hindsight/lib/state.mjs +75 -0
  129. package/providers/hindsight/lib/summary.mjs +43 -0
  130. package/providers/hindsight/lib/validate.mjs +75 -0
  131. package/providers/hindsight/manifest.json +58 -0
  132. package/providers/hindsight/wizard.mjs +149 -0
  133. package/providers/letta/manifest.json +29 -0
  134. package/providers/mem0/OPERATOR.md +124 -0
  135. package/providers/mem0/compose.yaml +57 -0
  136. package/providers/mem0/lib/coding-agent.mjs +58 -0
  137. package/providers/mem0/lib/config.mjs +45 -0
  138. package/providers/mem0/lib/configure.mjs +135 -0
  139. package/providers/mem0/lib/dotenv.mjs +71 -0
  140. package/providers/mem0/lib/env-file.mjs +110 -0
  141. package/providers/mem0/lib/http.mjs +69 -0
  142. package/providers/mem0/lib/mcp-install.mjs +165 -0
  143. package/providers/mem0/lib/secret.mjs +30 -0
  144. package/providers/mem0/lib/smoke.mjs +179 -0
  145. package/providers/mem0/lib/stack-env.mjs +216 -0
  146. package/providers/mem0/lib/state.mjs +67 -0
  147. package/providers/mem0/lib/summary.mjs +60 -0
  148. package/providers/mem0/lib/url.mjs +106 -0
  149. package/providers/mem0/lib/validate.mjs +158 -0
  150. package/providers/mem0/manifest.json +47 -0
  151. package/providers/mem0/wizard.mjs +133 -0
  152. package/providers/zep/manifest.json +29 -0
  153. package/scripts/check-pack.mjs +218 -0
  154. package/scripts/gen-masks.mjs +83 -0
  155. package/scripts/gen-masks.sh +4 -0
  156. package/scripts/promotion-provider-smoke.mjs +34 -0
  157. package/scripts/run-setup.sh +30 -0
  158. package/scripts/setup.mjs +94 -0
  159. package/scripts/setup.sh +5 -0
  160. package/scripts/spin-up.sh +45 -0
  161. package/scripts/wizard.sh +5 -0
  162. package/server.json +34 -0
  163. package/skills/openmem/SKILL.md +29 -0
  164. package/sync/Dockerfile +27 -0
  165. package/sync/memory_backend.py +87 -0
  166. package/sync/notebooklm_sync.py +664 -0
  167. package/wizard/bin/pm.mjs +97 -0
  168. package/wizard/bin/setup.mjs +33 -0
  169. package/wizard/lib/compose-version.mjs +32 -0
  170. package/wizard/lib/compose.mjs +70 -0
  171. package/wizard/lib/curl.mjs +103 -0
  172. package/wizard/lib/docker-build.mjs +148 -0
  173. package/wizard/lib/exec.mjs +41 -0
  174. package/wizard/lib/indexer.mjs +6 -0
  175. package/wizard/lib/load-machine-env.mjs +4 -0
  176. package/wizard/lib/log.mjs +32 -0
  177. package/wizard/lib/notebooklm-agent-access.mjs +92 -0
  178. package/wizard/lib/notebooklm.mjs +214 -0
  179. package/wizard/lib/parse-args.mjs +87 -0
  180. package/wizard/lib/paths.mjs +39 -0
  181. package/wizard/lib/pm-config.mjs +163 -0
  182. package/wizard/lib/ports.mjs +94 -0
  183. package/wizard/lib/prompts.mjs +57 -0
  184. package/wizard/lib/provider-wizard/helpers.mjs +98 -0
  185. package/wizard/lib/provider-wizard/run-steps.mjs +129 -0
  186. package/wizard/lib/providers/registry.mjs +262 -0
  187. package/wizard/lib/run-clack.mjs +108 -0
  188. package/wizard/lib/run-wizard.mjs +755 -0
  189. package/wizard/lib/validate-setup.mjs +62 -0
  190. package/wizard/lib/wizard-action.mjs +34 -0
  191. package/wizard/lib/wizard-conf.mjs +71 -0
package/docs/mem0.md ADDED
@@ -0,0 +1,103 @@
1
+ # mem0
2
+
3
+ **mem0** is a supported OpenMem provider. You run a [self-hosted mem0 REST server](https://docs.mem0.ai/open-source/features/rest-api); OpenMem points the shared indexer and unified `memory_*` MCP at it. One active provider at a time — same agent surface as Hindsight or Cognee.
4
+
5
+ This is **not** the hosted platform at `https://api.mem0.ai` (different API shape). OpenMem talks to the open-source REST server only (no `/v1/` prefix).
6
+
7
+ Upstream project: [mem0ai/mem0](https://github.com/mem0ai/mem0). Stack details for contributors: `providers/mem0/OPERATOR.md`.
8
+
9
+ ## What you run vs what OpenMem runs
10
+
11
+ | You | OpenMem |
12
+ | --- | --- |
13
+ | mem0 REST server (JWT, Postgres/pgvector, embedder keys) | `MEMORY_PROVIDER=mem0`, `MEMORY_SINK=mem0` |
14
+ | API key in `~/.config/personal-memory/mem0.env` (mode **600**) | `MEM0_API_URL` / `MEM0_INDEXER_URL` in stack env |
15
+ | Bind so the indexer container can reach the server | Wizard smoke: docs, retain, search, delete-by-id |
16
+ | | Unified MCP + optional native mem0 MCP |
17
+
18
+ Compose profile `mem0` adds env + `extra_hosts` on the shared **indexer** only — there is no mem0 container in this repo yet.
19
+
20
+ ## First-time setup
21
+
22
+ 1. Start your mem0 REST server (default OpenMem port expectation: **18888**).
23
+ 2. Put the API key in the env file (skip if `AUTH_DISABLED=true` on the server for local dev only):
24
+
25
+ ```text
26
+ ~/.config/personal-memory/mem0.env
27
+ MEM0_API_KEY=…
28
+ ```
29
+
30
+ Never put `MEM0_API_KEY` in stack `.env`, `wizard.conf`, `config.toml`, or `mcp.json`.
31
+
32
+ 3. Select mem0 in the wizard, or switch later:
33
+
34
+ ```sh
35
+ npx @bcmyguest/openmem # choose mem0 when prompted
36
+ # or:
37
+ npx @bcmyguest/openmem switch mem0 --yes
38
+ ```
39
+
40
+ 4. Confirm:
41
+
42
+ ```sh
43
+ npx @bcmyguest/openmem doctor
44
+ curl -fsS "$MEM0_API_URL/docs" # URL from wizard / stack .env
45
+ ```
46
+
47
+ ## URLs
48
+
49
+ | Variable | Meaning |
50
+ | --- | --- |
51
+ | `MEM0_API_URL` | Host view (what you curl), e.g. `http://127.0.0.1:18888` |
52
+ | `MEM0_INDEXER_URL` | Derived for the indexer container — loopback hosts are rewritten to the Docker bridge gateway. Do not set this to `127.0.0.1` by hand inside the container. |
53
+
54
+ **Linux:** a process bound only to loopback is often unreachable from the indexer container. Bind mem0 to `0.0.0.0` (or a real hostname). Prefer `https://` when the server is not on loopback — `X-API-Key` is cleartext on plain HTTP.
55
+
56
+ Search fails if the server’s embedder is misconfigured; smoke stores with `infer: false` and looks for that fact.
57
+
58
+ ## Banks / scopes
59
+
60
+ mem0 scopes map to **`user_id`**. OpenMem’s MCP `bank` argument and indexer banks become that `user_id`. Default unified MCP scope is `openmem-mcp` unless tools pass `bank`. Project work should pass the resolved project bank so session noise does not land in the default. See [Concepts — Context and banks](concepts.md#context-and-banks).
61
+
62
+ ## Coding agents and MCP
63
+
64
+ **Preferred:** unified OpenMem MCP (`memory_*`) — same tools as Hindsight/Cognee:
65
+
66
+ ```sh
67
+ npx @bcmyguest/openmem install-coding-agent --yes
68
+ # or MCP only:
69
+ npx @bcmyguest/openmem install-mcp --yes
70
+ ```
71
+
72
+ **Optional native mem0 tools** (upstream `@yeyuan98/mem0-mcp` names, not `memory_*`):
73
+
74
+ ```sh
75
+ MEMORY_PROVIDER=mem0 npx @bcmyguest/openmem install-mcp --yes --provider-only
76
+ ```
77
+
78
+ That registers `cli/mem0-mcp.mjs` with `MEM0_API_URL` / `MEM0_BASE_URL` and the **path** to `mem0.env` — never the key value in `mcp.json`. Mem0’s cloud MCP (`https://mcp.mem0.ai`) is **not** for self-hosted REST.
79
+
80
+ Restart Cursor Agent after MCP changes. Full flag matrix: [MCP setup](mcp-setup.md).
81
+
82
+ There is no Hindsight-style coding-agent plugin for mem0; session hooks + unified MCP cover day-to-day agent memory.
83
+
84
+ ## Portability
85
+
86
+ Export/import uses **PMM** via `memory_export` / `memory_import` on the unified MCP. Switching providers does **not** migrate data by itself — export, switch, import (or re-index). See [Portable memory (PMM)](memory-portability.md).
87
+
88
+ ## Switch provider
89
+
90
+ ```sh
91
+ npx @bcmyguest/openmem switch mem0 --yes
92
+ # later:
93
+ npx @bcmyguest/openmem switch hindsight --yes
94
+ ```
95
+
96
+ Updates active provider config, restarts the stack (unless `--no-stack`), refreshes MCP (unless `--no-mcp`). Does **not** migrate memories.
97
+
98
+ ## Related
99
+
100
+ - [Concepts](concepts.md) — interface layer
101
+ - [MCP setup](mcp-setup.md) — unified vs provider-native
102
+ - [Portable memory (PMM)](memory-portability.md)
103
+ - [Architecture](architecture.md) · [Provider status](provider-status.md)
@@ -0,0 +1,73 @@
1
+ # Portable memory (PMM)
2
+
3
+ OpenMem’s **portability layer** moves memories between providers without baking in a vendor dump format. **PMM** (Personal Memory Manifest) is the first interchange format: export what a backend stores, import into another (or the same) provider, and keep a portable copy for backup or “give me my data” requests.
4
+
5
+ `npx @bcmyguest/openmem switch` rewires the stack only — it does **not** migrate content. Use export → switch → import (or re-index) when you change backends.
6
+
7
+ Status: **`memory_export` / `memory_import`** on the unified MCP are **beta**. PMM v1 is stable; adapters live under `cli/mcp/export/` (orchestrator: `cli/mcp/portability.mjs`). MCP install: [MCP setup](mcp-setup.md).
8
+
9
+ ## PMM format (version 1)
10
+
11
+ JSON object, or JSONL with one header line followed by one normalized record per line:
12
+
13
+ | Field | Type | Meaning |
14
+ | --- | --- | --- |
15
+ | `pmm_version` | `1` | Schema version |
16
+ | `exported_at` | ISO-8601 string | When the export was taken |
17
+ | `source_provider` | string | `hindsight` \| `mem0` \| `cognee` |
18
+ | `scope` | object | Provider-specific filter (bank, `user_id`, datasets, …) |
19
+ | `records` | array | Normalized memory records (see below) |
20
+
21
+ Each **record**:
22
+
23
+ | Field | Type | Meaning |
24
+ | --- | --- | --- |
25
+ | `id` | string \| null | Provider id when known |
26
+ | `content` | string | Primary text |
27
+ | `metadata` | object | Optional tags, timestamps, provider payload |
28
+ | `scope_key` | string | Bank name, mem0 `user_id`, Cognee dataset, etc. |
29
+
30
+ Import accepts PMM with `merge_strategy`:
31
+
32
+ | Strategy | Behavior |
33
+ | --- | --- |
34
+ | `skip_duplicates` (default) | For mem0, skip records whose id or content fingerprint already exists in the same bank |
35
+ | `overwrite` | Re-import all records (may duplicate on backends without idempotent upsert) |
36
+
37
+ **Cross-provider import** (e.g. PMM from mem0 into Hindsight) is best-effort: we map `content` + `scope_key` into the active provider’s add API; embeddings and graph structure are **not** preserved.
38
+
39
+ The MCP export currently collects all records in memory before returning them, including with `format: "jsonl"`. Use a bank filter for large stores; the MCP response is not a file stream. Hindsight export reads the memory-list endpoint and does not include knowledge pages, bank configuration, or source documents. Confirm migrated data before switching providers.
40
+
41
+ ## Implementation (orchestrator + adapters)
42
+
43
+ openmem stays a **meta orchestrator**: PMM shape and import live in `cli/mcp/portability.mjs`; each backend implements **list/map** in `cli/mcp/export/` (`hindsight.mjs`, `mem0.mjs`, `cognee.mjs`). New providers add an adapter and one branch in `cli/mcp/export/index.mjs` — no changes to the MCP tool names agents call.
44
+
45
+ ## Unified MCP tools
46
+
47
+ On the `openmem` MCP server ([MCP setup](mcp-setup.md), [Architecture](architecture.md)):
48
+
49
+ ```text
50
+ memory_export { format?: "json"|"jsonl", bank?: string, user_id?: string }
51
+ memory_import { data: string, merge_strategy?: "skip_duplicates"|"overwrite" }
52
+ ```
53
+
54
+ Example flow (Cursor Agent / any host with the unified server):
55
+
56
+ 1. `memory_export` with `format: "json"` and optional `bank`
57
+ 2. `npx @bcmyguest/openmem switch <other> --yes`
58
+ 3. `memory_import` with the exported JSON and `merge_strategy: "skip_duplicates"`
59
+
60
+ Restart Cursor Agent after `npx @bcmyguest/openmem install-mcp --yes`.
61
+
62
+ ## Provider behavior
63
+
64
+ | Provider | Export | Import |
65
+ | --- | --- | --- |
66
+ | **mem0** | `GET /memories` with `user_id` from `bank` arg (API key from env file) | `POST /memories` per record (`infer: false`) |
67
+ | **Hindsight** | `GET /v1/default/banks` then paginated `GET …/memories/list` per bank (`bank` arg = one bank; omit = all banks) | `POST …/banks/{bank}/memories` per record |
68
+ | **Cognee** | Resolve indexer dataset name from `bank`, `GET /api/v1/datasets`, paginate `GET …/data` (label/name as content; not full file bytes) | `POST /api/v1/add` per record when dataset in scope |
69
+
70
+ ## Related
71
+
72
+ - [Architecture — provider interface](architecture.md#how-openmem-interfaces-with-providers)
73
+ - [mem0](mem0.md) · [Cognee](cognee.md)
@@ -0,0 +1,246 @@
1
+ # Pluggable memory providers
2
+
3
+ This repo ships **one** supported backend: [Hindsight](https://github.com/vectorize-io/hindsight)
4
+ (API + retain/reflect/consolidate, LiteLLM in front of local models). **mem0** and **Cognee** are
5
+ **experimental** plugins (indexer sink, compose profile, wizard hooks, stub tests). Wave 3 hardened
6
+ operator DX (coding-agent steps, secrets, Ollama wiring); live Cognee cognify+search with a small
7
+ local model is not yet a promotion bar — see `docs/WAVE3-orchestrator.md`. Manifests under
8
+ `providers/` show `experimental` vs `supported`.
9
+
10
+ ## Meta setup wizard (what this is — and is not)
11
+
12
+ `npm run setup` (checkout), `npx @bcmyguest/openmem setup`, or `./setup` is a **meta** wizard: it
13
+ orchestrates **machine-local plumbing** that is the same idea across providers (Docker project,
14
+ ports, indexer sources, smoke “is the API alive?”, coding-agent config file, compose up/down). It does
15
+ **not** replace each provider’s **native** settings UI, CLI, or config format.
16
+
17
+ | This wizard owns (cross-cutting) | Provider still owns (native) |
18
+ | --- | --- |
19
+ | Pick provider + stack action (configure / up / down) | API keys, org/project ids, mem0 graph settings |
20
+ | Host ports, `HOST_UID`/`HOST_GID`, compose project name | Hindsight retain/reflect models beyond our LiteLLM routes |
21
+ | Shared `index.yml` (what to index) | Provider-specific memory schema, filters, user ids |
22
+ | Wiring Hindsight → LiteLLM proxy (when provider is Hindsight) | mem0 dashboard, cloud vs self-hosted choice |
23
+ | Health/smoke probes declared in manifest | Official provider docs, upgrades, migrations |
24
+
25
+ When a provider needs extra fields, the manifest should grow **provider-specific wizard steps** (or
26
+ point to “run `mem0 …` / edit `~/.mem0/…`”) — not cram mem0 into Hindsight’s LiteLLM screens.
27
+
28
+ ### Similar patterns elsewhere
29
+
30
+ These are the usual analogues people mean by “meta setup”:
31
+
32
+ - **[mise](https://mise.jdx.dev/) / [asdf](https://asdf-vm.com/)** — one CLI to install and select
33
+ runtimes; each plugin wraps the tool’s own install rules. mise does not replace `.npmrc` or
34
+ `Cargo.toml`.
35
+ - **[Chezmoi](https://www.chezmoi.io/)** — applies dotfiles from a repo; Vim, Git, and SSH keep their
36
+ normal config files on disk.
37
+ - **[Supabase CLI](https://supabase.com/docs/guides/cli)** — `supabase start` brings up Postgres,
38
+ Auth, Studio; each service still has its own env and tuning.
39
+ - **LiteLLM (in this stack)** — meta proxy in front of lemond/Ollama; model servers keep their own
40
+ configs. `./setup`’s “model backend” step is really “how LiteLLM reaches your LLM,” not a full
41
+ lemond replacement.
42
+ - **[Home Assistant](https://www.home-assistant.io/)** — core + integrations; Philips Hue still configured
43
+ in the Hue app, HA only links it.
44
+ - **`npx skills`-style installers** — discover and install artifacts; each skill or package owns its
45
+ content afterward.
46
+
47
+ openmem sits in that category: **one front door** for “memory on this machine for coding agents,”
48
+ not a reimplementation of mem0 or Hindsight settings.
49
+
50
+ Declarative config is **[mise-like](openmem-config.md)**: `~/.config/personal-memory/config.toml`
51
+ plus `./pm` tasks — same *shape* as mise (`[tasks]`, merged config files), different domain.
52
+
53
+ Provider-specific setup runs via **[wizard hooks](provider-wizard-hooks.md)** (`providers/*/wizard.mjs`)
54
+ after meta steps — like asdf plugin install scripts, not reimplemented npm/mem0 CLIs.
55
+
56
+ ## Layers (what varies per provider)
57
+
58
+ | Layer | Hindsight today | Should become |
59
+ | --- | --- | --- |
60
+ | **Compose stack** | `litellm`, `hindsight`, `indexer`, optional `notebooklm` | Provider manifest lists services / profiles; shared `indexer` where possible |
61
+ | **Model routing** | LiteLLM + `config/litellm.*.yaml` | Hindsight-specific; other providers may use their own LLM config or none |
62
+ | **Indexer sink** | `bin/hindsight-project-index` → REST `/v1/default/banks/{bank}/memories` | Python **sink** interface; one implementation per provider |
63
+ | **Setup wizard** | Node wizard: preflight, env, smoke retain/recall | Provider manifest: health URL, smoke steps, env file names |
64
+ | **Coding-agent UX** | `@vectorize-io/hindsight-coding-agents` + `coding-agent.json` | Per-provider plugin package or generic adapter |
65
+
66
+ NotebookLM sync is **orthogonal** to which provider you picked: enable the `notebooklm` profile and the sync container uses the same `MEMORY_SINK` as the indexer (Hindsight, mem0, or Cognee).
67
+
68
+ Coding-agent session memory uses the **same** in-repo hooks and unified MCP for every provider; optional `--hindsight-plugin` adds the upstream Hindsight plugin on Hindsight stacks only.
69
+
70
+ ## Provider manifest
71
+
72
+ Each provider lives under `providers/<id>/manifest.json`. The wizard loads manifests via
73
+ `wizard/lib/providers/registry.mjs`. Fields are intentionally small; expand only when a second
74
+ provider needs them.
75
+
76
+ - **`status`**: `supported` | `experimental` | `planned`
77
+ - **`compose`**: which services belong to this provider, health check, default host port env var
78
+ - **`indexer`**: env var for API base URL, `sink`, and `sinkDriver` (see the table below)
79
+ - **`codingAgent`**: optional npx package and config template path
80
+ - **`wizard`**: smoke test bank name and HTTP paths (templates may include `{bank}`)
81
+
82
+ | `indexer` field | Meaning | Required |
83
+ | --- | --- | --- |
84
+ | `apiUrlEnv` | Env var that holds the provider's API base URL for the wizard | Per provider |
85
+ | `sink` | The `MEMORY_SINK` value, which equals the `indexer/sinks/<sink>.py` module name. Must match `^[a-z][a-z0-9_]*$` (the same rule as `indexer/sinks/__init__.py`). | `supported` and `experimental`; optional but validated for `planned` |
86
+ | `sinkDriver` | Human-readable wire-dialect label (for example `hindsight-rest-v1`). It names no module and drives no dispatch. | `supported` and `experimental` |
87
+
88
+ `scripts/tests/test_provider_manifests.mjs` checks that every `supported` or `experimental` manifest
89
+ with an `indexer.sink` has a matching `indexer/sinks/<sink>.py`.
90
+
91
+ ## Selecting a sink
92
+
93
+ The indexer picks its provider with `--sink NAME`, falling back to the `MEMORY_SINK` environment
94
+ variable, then `hindsight`. Compose fragments for alternate providers set both `MEMORY_SINK` and
95
+ `MEMORY_API_URL` on the `indexer` service from stack `.env` values.
96
+
97
+ | Variable | Used by | Meaning |
98
+ | --- | --- | --- |
99
+ | `MEMORY_SINK` | indexer | Sink module name (`indexer.sink` in the manifest). Default `hindsight`. |
100
+ | `MEMORY_API_URL` | indexer, every non-Hindsight sink | Generic API base URL of the provider. |
101
+ | `HINDSIGHT_URL` | indexer, Hindsight sink only | API base URL for Hindsight (default `http://127.0.0.1:8888`). |
102
+
103
+ `--url` overrides either URL variable. A sink reads its credentials from its own environment
104
+ variables inside `create`, never from the document path.
105
+
106
+ Provider secrets (for example `MEM0_API_KEY`, `COGNEE_API_KEY`, `LLM_API_KEY`) live in
107
+ `~/.config/personal-memory/<id>.env`, outside the repo, mode 600. A provider's compose fragment loads
108
+ that file through an `env_file` entry with `required: false`, so a stack without the file still
109
+ starts. Secrets do not belong in the stack `.env` or in `wizard.conf`, and the wizard never prints
110
+ them.
111
+
112
+ ### Optional `flush()`
113
+
114
+ A sink for a provider that ingests asynchronously (`capabilities.async_ingest=True`, for example
115
+ Cognee, where `cognify` builds the graph after `add`) may define `flush(bank: str) -> None`. The
116
+ indexer calls it once per bank after that bank's batch of retains and deletes, so the provider starts
117
+ processing once per batch rather than once per document.
118
+
119
+ - The call happens only with `--apply`. The indexer calls `flush(bank)` with an explicit bank when the
120
+ batch retained or deleted at least one document for that bank, **or** when a previous flush for that
121
+ bank is still pending. A dry run never flushes, and `flush(None)` is never called.
122
+ - A sink must treat `flush(bank)` as "process this bank now", even when its own in-memory bookkeeping
123
+ says the bank is clean: the indexer may call it from a fresh process in which that bookkeeping is gone.
124
+ - Pending flushes are persisted. Per-document progress is saved to the indexer state file as it goes, so
125
+ a failed flush (or a run that died after some retains) would otherwise never be retried. For a sink
126
+ with a `flush`, the bank is recorded under the state key `::flush-pending` (a sorted list of banks)
127
+ before the first write of a batch and removed after `flush` succeeds. Every `--apply` run flushes the
128
+ banks it handles that are still pending, even when nothing changed. A bank whose source is no longer
129
+ indexed is left alone. Sinks without `flush` (Hindsight) never get the key, so their state file is
130
+ unchanged.
131
+ - `flush` is not part of the `Sink` protocol, so sinks without it (Hindsight among them) still satisfy
132
+ `isinstance(sink, Sink)` and see no change in behavior. Callers use `sinks.flush_sink(sink, bank)`,
133
+ which does nothing when the sink has no callable `flush`.
134
+ - A flush error is handled like a retain error: the source is reported as failed, the other sources
135
+ still run, and the pending marker stays so the next run flushes again.
136
+ - The watcher (`indexer/watch.py`) spawns this same CLI once per source, so flush runs there too. In
137
+ the indexer container the sink and URL come from `MEMORY_SINK` and `MEMORY_API_URL`.
138
+
139
+ Default provider id: **`hindsight`**. Change it in **interactive `./setup`** (Clack “Memory provider”,
140
+ defaults to `config.toml` and `wizard.conf`), or set `MEMORY_PROVIDER` for `--yes`. The wizard records
141
+ the choice in `wizard.conf`. Stack **up** / **down** are wizard actions (`--up`, `--down`, or Clack
142
+ first step); default action is full **configure and start**.
143
+
144
+ ### Changing provider later
145
+
146
+ Prefer **`npx @bcmyguest/openmem switch <id> --yes`** (checkout: `npx . switch <id> --yes`) over a full
147
+ interactive setup re-run when you only need to change backends:
148
+
149
+ - Updates `MEMORY_PROVIDER` in `~/.config/hindsight/wizard.conf`
150
+ - Updates `[memory].provider` in `~/.config/personal-memory/config.toml` when that file exists
151
+ - Unless `--no-stack`: compose down + up for the new provider (with mem0/Cognee readiness checks)
152
+ - Unless `--no-mcp`: runs `install-mcp --provider-only` so Cursor MCP points at the new provider
153
+
154
+ Switching does **not** migrate memories between backends. The NotebookLM compose profile and
155
+ `notebooklm` MCP entry are left alone. Flags and examples:
156
+ [README — Switch memory provider](../README.md#switch-memory-provider).
157
+
158
+ ## Suggested implementation phases (separate commits)
159
+
160
+ ### Phase A — Registry and docs (this commitset)
161
+
162
+ - Manifests for `hindsight`, `mem0`, and `cognee` (`supported`).
163
+ - Wizard reads manifest for health/smoke URLs; behavior unchanged for Hindsight.
164
+ - Document extension points (this file).
165
+
166
+ ### Phase B — Indexer sink interface (implemented)
167
+
168
+ - HTTP retain/delete/health live in `indexer/sinks/`; default sink is `hindsight`.
169
+ - CLI: `--sink <name>` or env `MEMORY_SINK`; non-Hindsight sinks use `MEMORY_API_URL` for the API base.
170
+ - Contract tests: `indexer/tests/sink_contract.py` and `test_sinks.py`. Per-provider bank mapping and compose env: [indexer-sinks.md](indexer-sinks.md).
171
+
172
+ ### Phase D — Compose profiles (implemented for Hindsight)
173
+
174
+ - `litellm` and `hindsight` use compose profile `hindsight`; the indexer always starts.
175
+ - `./setup` passes `--profile hindsight` on compose commands; `scripts/setup.mjs` writes `COMPOSE_PROFILES=hindsight` into the stack `.env`.
176
+ - Alternate providers layer `providers/<id>/compose.yaml` with their own profile (`MEMORY_SINK`, `MEMORY_API_URL`, `depends_on`).
177
+
178
+ ### Phase C — mem0 and Cognee (Wave 2 + Wave 3 DX)
179
+
180
+ - mem0 is **URL-only** in v1: the indexer talks to a mem0 server the operator already runs, and this
181
+ repo ships no mem0 container yet. A mem0 service built from a pinned upstream ref is a follow-up.
182
+ Operator runbook: `providers/mem0/OPERATOR.md`. Coding-agent: wizard `setupCodingAgent` prints
183
+ SDK/MCP steps (no fake `pluginPackage`); register Cursor MCP with
184
+ `npx @bcmyguest/openmem install-mcp --yes` / `npx @bcmyguest/openmem switch mem0 --yes`.
185
+ - Cognee runs in **docker**: a pinned `cognee/cognee` image on a loopback port with a named volume and
186
+ an optional env file (`~/.config/personal-memory/cognee.env`, mode 600).
187
+ Operator notes: `providers/cognee/OPERATOR.md`. Coding-agent: REST on the loopback port plus a
188
+ read-only stdio MCP (`cli/cognee-mcp.mjs`: `cognee_health` / `cognee_search`) registered by
189
+ `setupCodingAgent` / `npm run install-mcp` when `MEMORY_PROVIDER=cognee`.
190
+ - **Cognee + Ollama:** default endpoints use `host.docker.internal:11434` (host Ollama on the Docker
191
+ bridge). When this stack’s compose profile `ollama` publishes **loopback-only**
192
+ (`127.0.0.1:11434`), that default is refused from the Cognee container. Set
193
+ `PM_COGNEE_OLLAMA_COMPOSE=1` or `MEMORY_OLLAMA_IN_COMPOSE=1` (wizard Clack also detects
194
+ `MEMORY_OLLAMA_IN_COMPOSE=1` in `wizard.conf`) so defaults become `http://ollama:11434` and attach
195
+ Cognee to the same Docker network as the `ollama` service. Cognify still needs a model that can
196
+ emit Cognee’s structured extraction schemas; small local models (for example `gemma4:e2b`) may
197
+ pass HTTP add/cognify start but never finish the graph — treat as an operator/LLM tuning issue,
198
+ not a provider status gate.
199
+ - `hindsight`, `mem0`, and `cognee` manifests are **`supported`**; new backends still land as
200
+ `experimental` until wizard + indexer + smoke are wired.
201
+ - `indexer/sinks/mem0.py` and `indexer/sinks/cognee.py` implementing the sink protocol (Cognee also
202
+ implements the optional `flush()`).
203
+ - Wizard branch: provider select (Clack) before model backend when multiple providers are supported.
204
+ - Coding-agent story: mem0’s own SDK/plugin or a thin local proxy—document limitations.
205
+
206
+ ### Phase D — Compose profiles
207
+
208
+ - `docker compose --profile hindsight` vs `--profile mem0` generated or documented from manifests.
209
+ - Avoid duplicating indexer image; only swap `depends_on` and indexer `environment`.
210
+
211
+ ## mem0 notes (non-goals for Phase A)
212
+
213
+ mem0’s API and deployment model differ from Hindsight banks and retain/reflect aliases. Expect:
214
+
215
+ - Different **namespace** model instead of `bank` strings.
216
+ - Possibly **no** LiteLLM sidecar in this repo (mem0 cloud or separate compose).
217
+ - Coding-agent integration likely **not** the Hindsight npx package; manifest should name the real install path when known.
218
+
219
+ ## Developer deep dives (repo only)
220
+
221
+ These stay under `docs/` and are **not** synced to the Starlight site (see `site/scripts/lib/docs.mjs` —
222
+ only user-facing guides like [Architecture](architecture.md) are listed in `PAGES`).
223
+
224
+ - [Indexer sink drivers](indexer-sinks.md) — `sink` vs `sinkDriver`, env vars, bank/scope mapping for Hindsight, mem0, Cognee
225
+ - [MCP setup](mcp-setup.md) — unified MCP vs `--provider-only` vs NotebookLM MCP
226
+
227
+ ## Index sources
228
+
229
+ See [index-sources.md](index-sources.md), [sources-feeds.md](sources-feeds.md), [sources-zotero.md](sources-zotero.md), [sources-readwise.md](sources-readwise.md), and [index-sources-roadmap.md](index-sources-roadmap.md).
230
+
231
+ ## Coding-agent session hooks
232
+
233
+ See [coding-agent-hooks.md](coding-agent-hooks.md), [coding-agent-scopes.md](coding-agent-scopes.md), and `npx @bcmyguest/openmem install-coding-agent`.
234
+
235
+ ## Site and docs
236
+
237
+ Published pages sync from `docs/*.md` at build time. If you change mermaid in a synced doc (for example `docs/architecture.md`), run `cd site && pnpm render-diagrams` and commit `site/public/diagrams/*.svg`. Then run `SITE_URL=https://bcmyguest.github.io BASE_PATH=/openmem/ pnpm build` in `site/` — the same check as CI and GitHub Pages.
238
+
239
+ ## Adding a provider (checklist)
240
+
241
+ 1. Add `providers/<id>/manifest.json` with accurate `status`.
242
+ 2. Implement indexer sink (Phase B+).
243
+ 3. Add compose fragment or profile and document ports/env.
244
+ 4. Extend wizard: provider selection, provider-specific steps, smoke test.
245
+ 5. Document opt-in / agent config for that provider.
246
+ 6. Extend `scripts/tests/test_wizard.sh` or add provider-specific tests.
@@ -0,0 +1,84 @@
1
+ # Model configuration
2
+
3
+ Hindsight never names a model server. It calls the LiteLLM proxy at `http://litellm:4000/v1` with three fixed aliases, and the proxy's YAML maps each alias to a model:
4
+
5
+ | Alias | Hindsight operation |
6
+ | --- | --- |
7
+ | `memory-retain` | retain (extraction on ingest) |
8
+ | `memory-reflect` | reflect, the base `HINDSIGHT_API_LLM_MODEL`, and mental-model refresh. Needs a model that makes tool calls |
9
+ | `memory-consolidate` | consolidation |
10
+
11
+ ## Shipped routes
12
+
13
+ Edit the YAML (or a per-machine override) to change models.
14
+
15
+ | File | Backend | Default split |
16
+ | --- | --- | --- |
17
+ | `config/litellm.lemond.yaml` | lemond on the host | Reflect: Gemma 4 E4B GGUF (`unsloth/`); retain and consolidate: E2B |
18
+ | `config/litellm.ollama.yaml` | Ollama on the host | Used when `MEMORY_BACKEND=ollama`; `gemma4:e4b` needs Ollama newer than 0.20.3 |
19
+
20
+ **Why reflect uses a larger model:** E2B often returns no usable tool call on Hindsight reflect (`finish_reason=length`). The shipped lemond route uses E4B for `memory-reflect` only. Qwen3.5-4B works as an alternative if you change the route; pick any model that passes a direct tool-call check and a smoke reflect.
21
+
22
+ ## Route selection
23
+
24
+ | Priority | Path |
25
+ | --- | --- |
26
+ | 1 | `~/.config/hindsight/litellm.yaml` — full override, mounted read-only into the proxy |
27
+ | 2 | `config/litellm.$MEMORY_BACKEND.yaml` — `lemond` (default) or `ollama` |
28
+
29
+ `scripts/setup.mjs` writes `LITELLM_CONFIG` in the stack `.env`. After changing backend, override, or routes:
30
+
31
+ ```sh
32
+ node scripts/setup.mjs
33
+ docker compose up -d litellm
34
+ ```
35
+
36
+ Optional Ollama backend:
37
+
38
+ ```sh
39
+ MEMORY_BACKEND=ollama node scripts/setup.mjs
40
+ docker compose up -d litellm
41
+ ```
42
+
43
+ ## Thinking and token limits
44
+
45
+ Thinking is off on all three aliases in the route YAML (`enable_thinking: false` / `think: false`) so replies are not empty when Hindsight sends low `reasoning_effort`.
46
+
47
+ | Layer | Role |
48
+ | --- | --- |
49
+ | LiteLLM `litellm_params.max_tokens` | Default when the client omits `max_tokens` (4096 in shipped routes) |
50
+ | `HINDSIGHT_API_*_MAX_COMPLETION_TOKENS` in `hindsight.env` | Hard cap Hindsight enforces (retain 16384; reflect and consolidation 2048) |
51
+
52
+ Retain cap must exceed each retain strategy's chunk size (coding-agent strategies use 12000) or Hindsight returns `400 Invalid retain strategy`.
53
+
54
+ ## Secrets
55
+
56
+ `~/.config/hindsight/litellm.env` (mode 600): `LITELLM_MASTER_KEY` (Hindsight uses this as `HINDSIGHT_API_LLM_API_KEY`), plus provider keys referenced as `os.environ/NAME` in the YAML.
57
+
58
+ Example hosted reflect model:
59
+
60
+ ```yaml
61
+ - model_name: memory-reflect
62
+ litellm_params:
63
+ model: anthropic/claude-haiku-4-5
64
+ api_key: os.environ/ANTHROPIC_API_KEY
65
+ ```
66
+
67
+ Hindsight always sends the alias names above; you do not edit model ids in `hindsight.env` for route changes.
68
+
69
+ ## Verify and migrate
70
+
71
+ Health check from the compose network:
72
+
73
+ ```sh
74
+ docker compose exec litellm python3 -c "import urllib.request;print(urllib.request.urlopen('http://127.0.0.1:4000/health/liveliness').read())"
75
+ ```
76
+
77
+ Older `hindsight.env` files that pointed at lemond/Ollama directly:
78
+
79
+ ```sh
80
+ node scripts/setup.mjs --migrate-env
81
+ docker compose up -d
82
+ ```
83
+
84
+ Migration rewrites LLM lines to use `http://litellm:4000/v1` and the three aliases; other lines stay as they are.
@@ -0,0 +1,83 @@
1
+ # NotebookLM
2
+
3
+ Opt-in. Syncs notebooks, sources, notes, and (optionally) chats from Google NotebookLM into **`notebooklm::<notebook slug>`** banks on whichever memory provider you run (**Hindsight, mem0, or Cognee** — same `MEMORY_SINK` / indexer sinks as the project indexer). Each notebook gets one bank; duplicate titles get an ID suffix. The service runs only under the `notebooklm` compose profile, so a plain `docker compose up` never starts it unless that profile is enabled.
4
+
5
+ Risks:
6
+
7
+ - The default `client` backend uses the unofficial `notebooklm-py` library (pinned to 0.8.5 with the `markdown` extra). Google can change or block it at any time, and the sync then fails until the library is updated.
8
+ - The stored login is a Google session cookie set. Anyone who reads `~/.config/notebooklm` can act on that Google account. The directory is bind-mounted read-write into the sync container only, and masked from the indexer.
9
+ - Source text and notes are copied into your active memory backend (`notebooklm::*` scope). With Hindsight, retains may invoke the configured model server; mem0/Cognee store chunks via the indexer sink (Cognee runs cognify after each sync batch).
10
+
11
+ Login happens in **`npm run setup`** when you enable NotebookLM: the wizard installs
12
+ `notebooklm-py` (via `uv`) if needed, opens the Google sign-in browser, then writes
13
+ `NOTEBOOKLM_HOME=~/.config/notebooklm` into the process environment and `wizard.conf`.
14
+ Cookies land in `~/.config/notebooklm/profiles/default/storage_state.json` (bind-mounted
15
+ into the sync container). Re-run setup when Google expires the session.
16
+
17
+ Manual equivalent (only if you skip the wizard step):
18
+
19
+ ```sh
20
+ mkdir -p ~/.config/notebooklm
21
+ uv tool install 'notebooklm-py[browser]==0.8.5'
22
+ uv tool run --from 'notebooklm-py[browser]==0.8.5' python -m playwright install chromium
23
+ NOTEBOOKLM_HOME=~/.config/notebooklm notebooklm login # or: ... login --browser-cookies chrome
24
+ NOTEBOOKLM_HOME=~/.config/notebooklm notebooklm auth check --test --json
25
+ ```
26
+
27
+ Enable and start:
28
+
29
+ 1. Create `~/.config/hindsight/notebooklm.yml` with only the keys you change, for example:
30
+
31
+ ```yaml
32
+ enabled: true
33
+ interval_minutes: 60 # default 60
34
+ include_notebooks: ["Work*"] # fnmatch globs, case-insensitive; empty means all
35
+ ```
36
+
37
+ Compose refuses to start if this file is missing; create it first (`touch` is enough when there are no changes). Keys merge with `config/notebooklm.yml`; lists and scalars replace the shipped value.
38
+ 2. Start the service from the repository:
39
+
40
+ ```sh
41
+ docker compose --profile notebooklm up -d notebooklm
42
+ docker compose --profile notebooklm logs -f notebooklm
43
+ ```
44
+
45
+ Without a login, the service logs the login commands and retries every 15 minutes. With `enabled: false` it sleeps and checks again hourly.
46
+
47
+ ### Coding-agent access (`notebooklmAccess`)
48
+
49
+ Synced notebooks land in Hindsight banks named `notebooklm::<slug>`. The coding-agent plugin still uses per-repo `coding-agent::*` banks only. Agents can **list/search** NotebookLM banks on demand (no auto-inject) via an opt-in MCP.
50
+
51
+ **Primary paths** (pick one):
52
+
53
+ 1. **Wizard** — when you enable NotebookLM sync in setup (step 6), the wizard asks whether to allow coding agents to query those banks via MCP (`notebooklm_list_banks` / `notebooklm_search`). Default is yes after sync is enabled. On yes it writes `notebooklmAccess.enabled: true` into a **real** `~/.hindsight/coding-agent.json` (if that path was a symlink to the repo template, it is copied to a regular file first so machine settings never land in `config/coding-agent.json`) and merges a `notebooklm` entry into `~/.cursor/mcp.json`.
54
+ 2. **`npx @bcmyguest/openmem install-mcp`** — same enable + MCP merge when NotebookLM is already on (`notebooklm.yml` `enabled: true`) or with `--notebooklm` / `--notebooklm-only`. See [Coding agents and MCP](coding-agents.md).
55
+
56
+ Restart Cursor Agent after either path. Manual JSON remains a fallback if you skipped the prompt or need to change allowlists later:
57
+
58
+ ```json
59
+ "notebooklmAccess": {
60
+ "enabled": true,
61
+ "banks": ["*"]
62
+ }
63
+ ```
64
+
65
+ - `enabled: false` (shipped default) — the NotebookLM MCP exits immediately; setup does not register it.
66
+ - `banks: ["*"]` — every `notebooklm::*` bank; or list slugs / full ids (e.g. `"sitrep-analysis"` or `"notebooklm::sitrep-analysis"`).
67
+
68
+ MCP tools (stdio server `cli/notebooklm-mcp.mjs`):
69
+
70
+ | Tool | Purpose |
71
+ | --- | --- |
72
+ | `notebooklm_list_banks` | Allowlisted `notebooklm::*` banks (`bank_id`, `fact_count`) |
73
+ | `notebooklm_search` | Fast full-text list on one allowlisted bank (`bank_id` + `query`; optional `mode=recall` for slow LLM synthesis) |
74
+
75
+ When `enabled` is true, the wizard or `install-mcp` merges a `notebooklm` entry into `~/.cursor/mcp.json` (does not overwrite `hindsight` or `codegraph`). To run the server by hand:
76
+
77
+ ```sh
78
+ # after enabling notebooklmAccess (wizard, install-mcp, or hand-edit)
79
+ node cli/notebooklm-mcp.mjs
80
+ # or: openmem-notebooklm-mcp
81
+ ```
82
+
83
+ Enterprise backend (`backend: enterprise`): the documented NotebookLM Enterprise REST API lists recently viewed notebooks only. It returns no source or note text, so this backend syncs notebook metadata only. It is untested against a live Enterprise project.