@owrede/vault-memory 0.10.0 → 2.0.0-rc.1
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.
- package/README.md +192 -338
- package/dist/cli.js +14971 -5260
- package/dist/cli.js.map +1 -1
- package/package.json +19 -4
package/README.md
CHANGED
|
@@ -1,284 +1,23 @@
|
|
|
1
1
|
# vault-memory
|
|
2
2
|
|
|
3
|
-
**Local-first
|
|
3
|
+
**Local-first, source-agnostic-ready agentic knowledge layer over your Obsidian notes,
|
|
4
|
+
exposed to any MCP-aware agent.**
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
(via Ollama), keeps the index live as you edit, and exposes the result to Claude Code
|
|
8
|
-
(and any other [Model Context Protocol](https://modelcontextprotocol.io)–aware agent)
|
|
9
|
-
as a set of well-defined tools for search, graph navigation, frontmatter queries, and
|
|
10
|
-
atomic writes.
|
|
6
|
+
> See [CHANGELOG.md](./CHANGELOG.md) for release history. Latest: **v2.0.0** — additive
|
|
7
|
+
> over v1.x; the 23 v1 tool names + input schemas are preserved byte-identical.
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
> See [CHANGELOG.md](./CHANGELOG.md) for release history. Latest: **v0.10.0**.
|
|
15
|
-
|
|
16
|
-
## What is vault-memory?
|
|
17
|
-
|
|
18
|
-
It's an [MCP server](https://modelcontextprotocol.io) that sits between your Obsidian
|
|
19
|
-
vaults and an AI agent. The agent — whether that's Claude Code in your editor, the
|
|
20
|
-
Claude desktop app via a Custom Connector, ChatGPT in Deep-Research mode, or anything
|
|
21
|
-
else that speaks MCP — gets a set of tools to read, search, and (optionally) write
|
|
22
|
-
notes. vault-memory handles the hard parts:
|
|
23
|
-
|
|
24
|
-
- **Hybrid retrieval** — semantic search over local embeddings, BM25 full-text search,
|
|
25
|
-
and Reciprocal Rank Fusion to merge them. Optional cross-encoder reranking for the
|
|
26
|
-
hardest queries.
|
|
27
|
-
- **Live indexing** — a file-watcher picks up changes the moment you save a note in
|
|
28
|
-
Obsidian. No manual re-index.
|
|
29
|
-
- **Multi-vault** — multiple vaults can be registered; search fans out by default and
|
|
30
|
-
merges results, or you can scope to one.
|
|
31
|
-
- **Graph awareness** — wikilinks, backlinks, broken-link detection, Obsidian-style
|
|
32
|
-
aliases.
|
|
33
|
-
- **Atomic, hash-protected writes** — the agent can edit notes, but only with explicit
|
|
34
|
-
opt-in and with concurrency control so it can't clobber your edits.
|
|
35
|
-
|
|
36
|
-
## What it provides
|
|
37
|
-
|
|
38
|
-
### MCP tools (23)
|
|
39
|
-
|
|
40
|
-
**Discovery & read**
|
|
41
|
-
- `list_vaults`, `read_note`
|
|
42
|
-
|
|
43
|
-
**Search**
|
|
44
|
-
- `search_semantic`, `search_text`, `search_hybrid` — all support optional
|
|
45
|
-
`exclude_paths` (glob) and an explicit `vaults` filter. Responses include a `note`
|
|
46
|
-
field when vaults were skipped (e.g. mid-indexing).
|
|
47
|
-
|
|
48
|
-
**Graph**
|
|
49
|
-
- `list_backlinks`, `list_forward_links`, `find_broken_links`
|
|
50
|
-
|
|
51
|
-
**Frontmatter**
|
|
52
|
-
- `query_frontmatter` — safe JSON-path DSL
|
|
53
|
-
|
|
54
|
-
**Write (hash-protected, atomic)**
|
|
55
|
-
- `write_note`, `update_frontmatter`, `delete_note`
|
|
56
|
-
|
|
57
|
-
**Audit**
|
|
58
|
-
- `audit_log`, `index_runs`
|
|
59
|
-
|
|
60
|
-
**Model management**
|
|
61
|
-
- `list_models`, `start_shadow_index`, `switch_active_model`
|
|
62
|
-
|
|
63
|
-
**Maintenance**
|
|
64
|
-
- `vacuum_embeddings` — drop orphaned embedding rows whose `chunk_id` no longer exists
|
|
65
|
-
|
|
66
|
-
**Agent compatibility (OB1 / Custom Connectors)**
|
|
67
|
-
- `search`, `fetch` — flat-shape adapters for ChatGPT Custom Connectors, Claude.ai,
|
|
68
|
-
and Deep-Research modes. Backed by the same hybrid pipeline, so connector users get
|
|
69
|
-
full search quality through the standardized shape.
|
|
70
|
-
|
|
71
|
-
**Agent self-orientation**
|
|
72
|
-
- `vault_stats` — note count, top tags, top frontmatter keys, last index run
|
|
73
|
-
- `recent_notes` — most-recently-modified notes (mtime DESC). Use on first connect to
|
|
74
|
-
brief an agent on what's in the vault and what the user has been working on.
|
|
75
|
-
|
|
76
|
-
**Schema inference (v0.10.0)**
|
|
77
|
-
- `suggest_frontmatter` — for an existing note (by `path`) or a draft (by `content +
|
|
78
|
-
folder_hint`), returns `{existing, suggestions, conflicts}` with calibrated confidence
|
|
79
|
-
per source. Three independent layers contribute:
|
|
80
|
-
- **folder-conventions** — frequency of frontmatter keys in sibling notes (same folder
|
|
81
|
-
prefix). Walks up one level when sibling count <3. Confidence = prevalence.
|
|
82
|
-
- **neighbor-inference** — frontmatter aggregate across wikilink-linked neighbors
|
|
83
|
-
(forward + backlink, deduped). Confidence = prevalence × 0.6 (dampened, since
|
|
84
|
-
indirect).
|
|
85
|
-
- **content-heuristics** — vault-agnostic title/body regex matchers for Email, Meeting,
|
|
86
|
-
Person, Clipping, Fact, and date-prefix patterns. Confidence fixed per rule.
|
|
87
|
-
Conflicts surface when sources disagree on a value. Existing-vs-suggested mismatches
|
|
88
|
-
are also flagged. No LLM, no embeddings.
|
|
89
|
-
|
|
90
|
-
### Claude Code skills
|
|
91
|
-
|
|
92
|
-
Five skills bundled in `skills/`, installable into any vault with one curl-pipe:
|
|
93
|
-
|
|
94
|
-
| Skill | What it does | When to invoke |
|
|
95
|
-
|---|---|---|
|
|
96
|
-
| **`install-vault-memory/`** | The complete installer — 8 idempotent checkpoints from Homebrew through MCP smoketest. Defaults to autonomous mode with a `why:` line on every install prompt. Re-running on a working setup verifies state in under 5 seconds and exits. | First-time setup of a vault, or repairing a broken state. `/install-vault-memory` |
|
|
97
|
-
| **`add-vault/`** | Wraps `vault-memory add-vault` CLI with a confirmation flow — appends to `config.toml`, writes `.mcp.json`, builds the initial index. Atomic and idempotent. | Adding a *second or third* vault after vault-memory is already installed. `/add-vault` |
|
|
98
|
-
| **`audit-vault-health/`** | Read-only vault health audit — overview stats, broken wikilinks, tag drift (case/separator variants), frontmatter schema drift, indexing freshness. Pure read, never modifies notes. | Quarterly check, before relying on search after bulk import. `/audit-vault-health` |
|
|
99
|
-
| **`find-stale-notes/`** | Discovers notes >6 mo old with 0 backlinks. Presents candidates as a sortable table, walks through each one with per-note actions (Archive / Update / Delete / Skip / Keep). Hash-protected deletes; never bulk-acts. | Vault cleanup, after import-bursts. `/find-stale-notes` |
|
|
100
|
-
| **`triage-inbox/`** | Walks through recent inbox-stage notes (sparse frontmatter, few tags, recent mtime). Per note: suggests target folder, tags, frontmatter, related wikilinks — based on semantic search against the rest of the vault. User accepts / edits / skips per note. | After a capture-burst (voice memos, web clippings, meeting transcripts). `/triage-inbox` |
|
|
101
|
-
|
|
102
|
-
## Requirements
|
|
103
|
-
|
|
104
|
-
Tested on macOS. Linux should work; Windows untested.
|
|
105
|
-
|
|
106
|
-
| What | Why | How |
|
|
107
|
-
|---|---|---|
|
|
108
|
-
| **Node.js ≥ 22** | Runtime for the MCP server. | `brew install node@22` |
|
|
109
|
-
| **[Ollama](https://ollama.com)** running on `localhost:11434` | Local embedding model host. No cloud API. | `brew install ollama && brew services start ollama` |
|
|
110
|
-
| **An embedding model** — default `bge-m3` (≈1.1 GB) | Generates the vectors that power semantic search. | `ollama pull bge-m3` |
|
|
111
|
-
| **Disk space** — ~1.2 GB for the embedding model, ~1× your vault size for the SQLite index | Models and the per-vault DB under `~/.vault-memory/`. | — |
|
|
112
|
-
| **(Optional) ONNX reranker** — `bge-reranker-v2-m3` (≈570 MB) | Cross-encoder reranking for `search_hybrid` when `rerank: true`. Lazy-loaded — zero cost if you never use it. | `bash scripts/download-reranker.sh` |
|
|
113
|
-
| **An MCP-aware client** — Claude Code, Claude desktop, ChatGPT Custom Connector, etc. | The agent that consumes the MCP tools. | — |
|
|
114
|
-
| **One or more Obsidian vaults** | What you're actually indexing. | — |
|
|
115
|
-
|
|
116
|
-
### Embedding-model recommendation
|
|
117
|
-
|
|
118
|
-
Eval-v2 (May 2026) compared two multilingual Ollama-hosted embedding models on a
|
|
119
|
-
187-note real-world German+English vault:
|
|
120
|
-
|
|
121
|
-
| Model | Size | Dim | Verdict |
|
|
122
|
-
|---|---|---|---|
|
|
123
|
-
| **`bge-m3`** ⭐ | 1.1 GB | 1024 | **Recommended default.** Materially better at concept-paraphrase queries; finds the right note where qwen3 returns generic tool pages. MIT-licensed. |
|
|
124
|
-
| `qwen3-embedding:0.6b` | 600 MB | 1024 | Low-RAM fallback. OK for direct keyword matches, weak on conceptual queries. Apache 2.0. |
|
|
125
|
-
| `embeddinggemma:300m` | 600 MB | 768 | Not benchmarked yet — promising for laptops with <8 GB free RAM. Gemma 3 license. |
|
|
126
|
-
|
|
127
|
-
See `vault-memory-eval-v2-results.md` for the full per-query benchmark table.
|
|
9
|
+
## 30-second example
|
|
128
10
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
### Recommended — npm
|
|
11
|
+
Install the CLI from npm, register a vault, and start the MCP server:
|
|
132
12
|
|
|
133
13
|
```bash
|
|
134
|
-
# 1) Homebrew (system-level)
|
|
135
|
-
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
136
|
-
|
|
137
|
-
# 2) Node 22+
|
|
138
|
-
brew install node@22
|
|
139
|
-
|
|
140
|
-
# 3) Ollama + service
|
|
141
|
-
brew install ollama && brew services start ollama
|
|
142
|
-
|
|
143
|
-
# 4) Embedding model (~1.1 GB)
|
|
144
|
-
ollama pull bge-m3
|
|
145
|
-
|
|
146
|
-
# 5) Install vault-memory from npm (public registry, no auth)
|
|
147
14
|
npm install -g @owrede/vault-memory
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
vault-memory add-vault "/Users/you/Documents/Obsidian Vaults/My Vault"
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
The MCP-host config (`.mcp.json` in the consuming vault) calls the `vault-memory`
|
|
154
|
-
binary, so any shell with it on `$PATH` works. Future upgrades:
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
npm install -g @owrede/vault-memory@latest
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Guided install from inside Claude Code
|
|
161
|
-
|
|
162
|
-
If you'd rather not run the steps by hand, install the skills first and let
|
|
163
|
-
`/install-vault-memory` walk you through it:
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
curl -fsSL https://raw.githubusercontent.com/owrede/vault-memory/main/scripts/install-skills.sh \
|
|
167
|
-
| bash -s -- "/path/to/your/obsidian/vault"
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
Open the vault in Claude Code, then run `/install-vault-memory` — it executes the
|
|
171
|
-
same 6 steps above as 8 idempotent checkpoints, with a `why:` line on every prompt.
|
|
172
|
-
|
|
173
|
-
### Install from source (developer mode)
|
|
174
|
-
|
|
175
|
-
Only needed if you want to modify vault-memory itself.
|
|
176
|
-
|
|
177
|
-
```bash
|
|
178
|
-
cd ~/Documents/GitHub
|
|
179
|
-
gh repo clone owrede/vault-memory
|
|
180
|
-
cd vault-memory
|
|
181
|
-
npm install && npm run build && npm link # creates the global `vault-memory` binary
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
## Adding a second (or third…) vault
|
|
185
|
-
|
|
186
|
-
One command:
|
|
187
|
-
|
|
188
|
-
```bash
|
|
189
|
-
vault-memory add-vault "/path/to/another/obsidian/vault"
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
This appends a `[[vaults]]` block to `~/.vault-memory/config.toml`, writes a `.mcp.json`
|
|
193
|
-
into the vault root (so Claude Code auto-spawns the MCP server when you open it), and
|
|
194
|
-
runs the initial index. Idempotent — re-running on a known path only fills in whatever
|
|
195
|
-
is missing.
|
|
196
|
-
|
|
197
|
-
Flags: `--name <slug>` to override the auto-slugified basename, `--write` to enable
|
|
198
|
-
MCP writes (default read-only), `--no-index` to skip the initial index. Inside Claude
|
|
199
|
-
Code, the `/add-vault` skill wraps the same CLI with confirmation prompts.
|
|
200
|
-
|
|
201
|
-
### Installing the skills in a vault
|
|
202
|
-
|
|
203
|
-
One-liner — works from anywhere, installs into the specified vault:
|
|
204
|
-
|
|
205
|
-
```bash
|
|
206
|
-
curl -fsSL https://raw.githubusercontent.com/owrede/vault-memory/main/scripts/install-skills.sh \
|
|
207
|
-
| bash -s -- "/path/to/your/obsidian/vault"
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
Or, from inside the vault's root directory:
|
|
211
|
-
|
|
212
|
-
```bash
|
|
213
|
-
curl -fsSL https://raw.githubusercontent.com/owrede/vault-memory/main/scripts/install-skills.sh | bash
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
The script is idempotent — re-running it fetches the latest skill versions from
|
|
217
|
-
`main` and overwrites the local copies. Use it to update your skills whenever
|
|
218
|
-
vault-memory ships a new release.
|
|
219
|
-
|
|
220
|
-
If you cloned the source repo, you can also copy directly:
|
|
221
|
-
|
|
222
|
-
```bash
|
|
223
|
-
cp -R ~/Documents/GitHub/vault-memory/skills/{install-vault-memory,add-vault,audit-vault-health,find-stale-notes,triage-inbox} .claude/skills/
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### Autonomous mode
|
|
227
|
-
|
|
228
|
-
`VAULT_MEMORY_AUTO=1` switches `install-vault-memory/setup.sh` to non-interactive
|
|
229
|
-
mode: every non-destructive `confirm()` prompt auto-answers yes, with a `why:` line
|
|
230
|
-
explaining what is being installed and why vault-memory needs it. Destructive
|
|
231
|
-
operations (overwriting an existing multi-vault `config.toml`, rebuilding a clone with
|
|
232
|
-
uncommitted changes) still prompt. This is the default when the skill is invoked via
|
|
233
|
-
`/install-vault-memory`; direct invocation of `setup.sh` defaults to fully-interactive
|
|
234
|
-
mode.
|
|
235
|
-
|
|
236
|
-
## Architecture in one paragraph
|
|
237
|
-
|
|
238
|
-
One SQLite database per vault under `~/.vault-memory/vaults/<name>.db`. Three storage
|
|
239
|
-
layers: **raw** (notes, chunks — permanent, model-agnostic), **derived** (embeddings
|
|
240
|
-
via sqlite-vec, FTS5, wikilinks — regenerable from raw), **audit** (index runs, write
|
|
241
|
-
history). Embeddings via Ollama HTTP. Cross-vault search via Reciprocal Rank Fusion in
|
|
242
|
-
the query layer. Per-model `embeddings_m<id>_d<dim>` vec0 tables let multiple embedding
|
|
243
|
-
models coexist for shadow-indexing and seamless model upgrades.
|
|
244
|
-
|
|
245
|
-
## Reranker — real ONNX cross-encoder
|
|
246
|
-
|
|
247
|
-
A real cross-encoder forward pass over **BAAI/bge-reranker-v2-m3** (ONNX INT8,
|
|
248
|
-
≈570 MB) via `onnxruntime-node` + `@huggingface/tokenizers`. Sigmoid-of-logit gives a
|
|
249
|
-
true `[0, 1]` relevance score per `(query, chunk)` pair, matching the `Reranker`
|
|
250
|
-
contract directly.
|
|
251
|
-
|
|
252
|
-
Setup (one-time):
|
|
253
|
-
|
|
254
|
-
```bash
|
|
255
|
-
bash scripts/download-reranker.sh # ≈590 MB into ~/.vault-memory/models/bge-reranker-v2-m3/
|
|
15
|
+
vault-memory add-vault "/path/to/your/obsidian/vault" --name notes
|
|
16
|
+
vault-memory serve
|
|
256
17
|
```
|
|
257
18
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
```toml
|
|
261
|
-
[server]
|
|
262
|
-
reranker_model = "bge-reranker-v2-m3"
|
|
263
|
-
reranker_backend = "onnx" # default when reranker_model is set
|
|
264
|
-
# reranker_model_dir = "..." # optional override; defaults to ~/.vault-memory/models/bge-reranker-v2-m3
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
Reranking remains **opt-in per query** via `rerank: true` in `search_hybrid`. The ONNX
|
|
268
|
-
session loads lazily on the first reranked query, so users who never set
|
|
269
|
-
`rerank: true` pay zero startup cost.
|
|
270
|
-
|
|
271
|
-
The legacy `OllamaReranker` (L2-norm proxy) stays available via
|
|
272
|
-
`reranker_backend = "ollama"` for back-compat, but is no longer recommended.
|
|
273
|
-
|
|
274
|
-
## Search scope
|
|
275
|
-
|
|
276
|
-
By default — with multiple vaults configured — `search_*` tools fan out across all of
|
|
277
|
-
them and merge via RRF. Two mechanisms scope this:
|
|
278
|
-
|
|
279
|
-
**`VAULT_MEMORY_ACTIVE_VAULT` env var** — set per consumer (in `.mcp.json`'s `env`
|
|
280
|
-
block) to default search to one vault. Explicit `vaults: [...]` in the request still
|
|
281
|
-
overrides; cross-vault stays opt-in.
|
|
19
|
+
Point an MCP-aware client at the `vault-memory` binary. For Claude Desktop, drop this
|
|
20
|
+
into `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
282
21
|
|
|
283
22
|
```json
|
|
284
23
|
{
|
|
@@ -286,86 +25,201 @@ overrides; cross-vault stays opt-in.
|
|
|
286
25
|
"vault-memory": {
|
|
287
26
|
"type": "stdio",
|
|
288
27
|
"command": "vault-memory",
|
|
289
|
-
"args": ["serve"]
|
|
290
|
-
"env": { "VAULT_MEMORY_ACTIVE_VAULT": "myvault" }
|
|
28
|
+
"args": ["serve"]
|
|
291
29
|
}
|
|
292
30
|
}
|
|
293
31
|
}
|
|
294
32
|
```
|
|
295
33
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
## Connector compatibility
|
|
34
|
+
Restart the client. Ask the agent something like: *"Pull me a brief for tomorrow's
|
|
35
|
+
1:1 with Alice."* The agent discovers the bundled `meeting-prep` task contract via
|
|
36
|
+
`describe_contract`, instantiates it with `instantiate_contract`, and the result —
|
|
37
|
+
attendees, recent shared notes, last decisions, open action items — is written into
|
|
38
|
+
your vault's `_memory/_briefs/` folder with full provenance. The brief is a regular
|
|
39
|
+
note; you can read it, edit it, link to it, or delete it.
|
|
40
|
+
|
|
41
|
+
That is the full agentic-knowledge-layer loop: discover a contract, instantiate it,
|
|
42
|
+
get a cited document back. Memory writes are labeled and provenance-tracked; user
|
|
43
|
+
notes are never modified silently.
|
|
44
|
+
|
|
45
|
+
## What this is
|
|
46
|
+
|
|
47
|
+
vault-memory turns one or more Obsidian vaults into a queryable, agent-native
|
|
48
|
+
knowledge layer running entirely on your machine. It indexes your notes with local
|
|
49
|
+
embeddings (via Ollama), keeps the index live as you edit, and exposes the result to
|
|
50
|
+
**any MCP-aware agent** — Claude Code, Claude Desktop, ChatGPT Custom Connectors,
|
|
51
|
+
the MCP Inspector, or any other client speaking the
|
|
52
|
+
[Model Context Protocol](https://modelcontextprotocol.io).
|
|
53
|
+
|
|
54
|
+
v1.0.0 was a strong **retrieval substrate**: hybrid search (semantic + BM25 + RRF,
|
|
55
|
+
optional cross-encoder rerank), live indexing, multi-vault, hash-protected writes.
|
|
56
|
+
v2.0.0 evolves it into a full **agentic knowledge layer** — memory namespace with
|
|
57
|
+
provenance, document-tree assembly (bundles, outlines, dossiers), graph-as-retrieval
|
|
58
|
+
(typed edges, expand, cluster), a compiled-brief layer with a staleness daemon, and
|
|
59
|
+
a task-contract DSL that any MCP-aware agent can discover and instantiate.
|
|
60
|
+
|
|
61
|
+
Obsidian is the v2 source connector; the same MCP tool surface backs any future
|
|
62
|
+
adapter (Notion, Logseq, ...) via the `SourceConnector` / `DeliveryAdapter` /
|
|
63
|
+
`ChangeFeed` seams introduced in Phase 1. The memory namespace is a non-negotiable
|
|
64
|
+
safety invariant: agents never write silently into user notes; every agent-authored
|
|
65
|
+
document carries provenance properties and lives in a labeled `MemorySink`.
|
|
330
66
|
|
|
331
|
-
|
|
332
|
-
Custom Connectors / Claude.ai / Deep-Research:
|
|
67
|
+
Nothing leaves your machine. No cloud sync, no API keys, no telemetry.
|
|
333
68
|
|
|
69
|
+
## Architecture
|
|
70
|
+
|
|
71
|
+
One SQLite database per vault under `~/.vault-memory/vaults/<name>.db`. Layers L0
|
|
72
|
+
through L4 sit on top of an Adapter tier that abstracts the source-of-truth. v2.0.0
|
|
73
|
+
ships exactly one adapter implementation (`obsidian-fs`); v3.0.0 adds `notion-api`
|
|
74
|
+
without touching the layers above the seam.
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
+-----------------------------------------------------------------------------+
|
|
78
|
+
| L4 Compiled briefs + Task contracts (Phases 5, 6) |
|
|
79
|
+
| compile_brief . get_brief . instantiate_contract . staleness daemon |
|
|
80
|
+
+-----------------------------------------------------------------------------+
|
|
81
|
+
| L3 Assembly (bundles, outlines, dossiers, authority + staleness) |
|
|
82
|
+
| get_document_bundle . get_outline . search_sections . |
|
|
83
|
+
| assemble_dossier . authority + staleness signals (Phases 3, 4) |
|
|
84
|
+
+-----------------------------------------------------------------------------+
|
|
85
|
+
| L2 Memory namespace + provenance (Phase 2) |
|
|
86
|
+
| record_observation . recall . supersede . MemoryContract |
|
|
87
|
+
+-----------------------------------------------------------------------------+
|
|
88
|
+
| L1 Graph as retrieval (Phase 4) |
|
|
89
|
+
| typed edges . expand . cluster . backlink walks |
|
|
90
|
+
+-----------------------------------------------------------------------------+
|
|
91
|
+
| L0 Retrieval substrate (v1, behavior unchanged) |
|
|
92
|
+
| hybrid search (semantic + BM25 + RRF + rerank) . chunker |
|
|
93
|
+
+-----------------------------------------------------------------------------+
|
|
94
|
+
| Adapter tier (Phase 1) |
|
|
95
|
+
| SourceConnector . DeliveryAdapter . ChangeFeed . Registry |
|
|
96
|
+
+-----------------------------------------------------------------------------+
|
|
97
|
+
| Implementations |
|
|
98
|
+
| obsidian-fs (v2.0.0) | notion-api (v3, Phase 10) |
|
|
99
|
+
+-----------------------------------------------------------------------------+
|
|
334
100
|
```
|
|
335
|
-
search({query, limit}) → { results: [{ id, title, url, snippet }] }
|
|
336
|
-
fetch({id}) → { id, title, text, url, metadata }
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
`id` is the opaque format `<vault>:<vault-relative-path>`. `url` is an
|
|
340
|
-
`obsidian://open?…` URL — connectors render it as a clickable link that opens the
|
|
341
|
-
note locally. Use the richer `search_hybrid` / `read_note` tools when working with a
|
|
342
|
-
vault-memory-aware client (Claude Code's MCP integration); use `search` / `fetch`
|
|
343
|
-
when integrating with a connector ecosystem that expects the standard shape.
|
|
344
101
|
|
|
345
|
-
|
|
102
|
+
The Adapter tier is the only horizontal seam in the stack. Every layer above it
|
|
103
|
+
consumes canonical `Document` objects resolved through the registry; no upper layer
|
|
104
|
+
holds a reference to a concrete adapter module. L0 keeps direct database access
|
|
105
|
+
because it is substrate, not a consumer of `Document`s. See
|
|
106
|
+
[docs/v2/ARCHITECTURE.md](docs/v2/ARCHITECTURE.md) for the full layer model, the
|
|
107
|
+
adapter conformance suite, and the read/write data-flow diagrams.
|
|
108
|
+
|
|
109
|
+
## What's new in v2
|
|
110
|
+
|
|
111
|
+
- **Phase 2 — Memory namespace + provenance.** Three new tools
|
|
112
|
+
(`record_observation`, `recall`, `supersede`); labeled `MemorySink` write guard;
|
|
113
|
+
default folder sink at `_memory/`; superseded-doc handling. See
|
|
114
|
+
[docs/v2/MEMORY_CONTRACT.md](docs/v2/MEMORY_CONTRACT.md).
|
|
115
|
+
- **Phase 3 — Assembly + authority/staleness.** Four new tools (`get_outline`,
|
|
116
|
+
`search_sections`, `get_document_bundle`, `assemble_dossier`); citation packets
|
|
117
|
+
on every result; recency/authority rescore params on `search_hybrid`;
|
|
118
|
+
superseded-doc filtering at SQL level. See
|
|
119
|
+
[docs/v2/PHASE-3-SIGN-OFF.md](docs/v2/PHASE-3-SIGN-OFF.md).
|
|
120
|
+
- **Phase 4 — Graph-as-retrieval.** Two new tools (`expand`, `cluster`); typed edges
|
|
121
|
+
table (`wikilink`, `mention`, `frontmatter-ref`, `hyperlink`); `search_hybrid`
|
|
122
|
+
gains an additive `expand` param attaching the typed-edge neighborhood to each
|
|
123
|
+
hit. See [docs/v2/PHASE-4-SIGN-OFF.md](docs/v2/PHASE-4-SIGN-OFF.md).
|
|
124
|
+
- **Phase 5 — Compiled brief layer + staleness daemon.** `compile_brief`,
|
|
125
|
+
`get_brief`, and `list_briefs`; per-brief `source_hashes` map; daemon marks
|
|
126
|
+
briefs stale when any source's hash drifts. See
|
|
127
|
+
[docs/v2/PHASE-5-SIGN-OFF.md](docs/v2/PHASE-5-SIGN-OFF.md).
|
|
128
|
+
- **Phase 6 — Task contract DSL + reference contracts.** Declarative YAML contracts
|
|
129
|
+
under `_contracts/<name>.yaml`; three new tools (`describe_contract`,
|
|
130
|
+
`instantiate_contract`, `register_contracts_as_tools`); three reference contracts
|
|
131
|
+
(`meeting-prep`, `project-status`, `code-review-brief`). See
|
|
132
|
+
[docs/v2/PHASE-6-SIGN-OFF.md](docs/v2/PHASE-6-SIGN-OFF.md).
|
|
133
|
+
- **Phase 7 — Obsidian plugin (default OFF).** Variant-C visual contract editor,
|
|
134
|
+
settings tab, secrets via OS keyring, manual reindex + stats panel, peer-MCP
|
|
135
|
+
connectors. Adds 6 gated tools when enabled. See
|
|
136
|
+
[docs/v2/plugin/README.md](docs/v2/plugin/README.md).
|
|
137
|
+
- **Tool surface delta.** 23 v1 tools become 32 canonical tools + 5 DEPRECATED
|
|
138
|
+
entries in `tools/list` (the 5 promoted list-style tools remain callable through
|
|
139
|
+
v2.x with a `DEPRECATED` notice in their `description`; removal scheduled for
|
|
140
|
+
v3.0.0). The raw `tools/list` therefore returns 37 entries; canonical
|
|
141
|
+
(non-deprecated) count = 32. Plugin OFF is the baseline; +6 gated tools when
|
|
142
|
+
enabled.
|
|
143
|
+
- **Resources delta.** 5 MCP Resources become 10 MCP Resources in v2.0.0
|
|
144
|
+
(`vaults`, `models`, `recent`, `stats`, `backlinks` added alongside the
|
|
145
|
+
pre-existing memory/brief/contract resources).
|
|
146
|
+
|
|
147
|
+
## Roadmap
|
|
148
|
+
|
|
149
|
+
**Phase 9 — Pre-Phase-10 premise check (hard gate).** Before any v3 code is
|
|
150
|
+
written, a dedicated phase verifies that the architectural premise for the v3
|
|
151
|
+
multi-source line still holds: all Phase 1 CI greps (no `chokidar`, no
|
|
152
|
+
`gray-matter`, no raw paths, no `Claude` leak, no `obsidian://` literal outside
|
|
153
|
+
adapters) return zero hits on `main`; an adversarial-review sub-agent confirms
|
|
154
|
+
ADRs 001-004 remain unviolated by code shipped in Phases 2-8; the stub-adapter
|
|
155
|
+
conformance suite is green; capability-descriptor test coverage meets the
|
|
156
|
+
plugin-architecture threshold; the maintainer signs off explicitly. Without that
|
|
157
|
+
sign-off, no v3 code is written.
|
|
158
|
+
|
|
159
|
+
**v3.0.0 — Notion connector + multi-source proof.** Ship the first non-Obsidian
|
|
160
|
+
source/delivery/change-feed adapter (Notion), promoting the adapter seams from
|
|
161
|
+
"interfaces with one implementation" to a real plugin architecture. Resolve the
|
|
162
|
+
14 open ADRs (005-01x) covering identity stability, link resolution, property
|
|
163
|
+
equivalence, granularity, write semantics, auth, watch, rate limits, embedding
|
|
164
|
+
strategy, cross-source memory, caching, sync, Notion sinks, and capability
|
|
165
|
+
discovery. Tracked requirements: NOT-01 through NOT-07; DMN-01 through DMN-03
|
|
166
|
+
(MCP daemon mode, v2.1.x or v3); TPC-01 through TPC-03 (third-party connectors,
|
|
167
|
+
post-v3). Status: deferred — gated by Phase 9 sign-off.
|
|
168
|
+
|
|
169
|
+
**Beyond v3 (ideas, not commitments).** A v3.x `postgres-fs` storage adapter is
|
|
170
|
+
sketched in the roadmap for users whose vaults outgrow local SQLite, with explicit
|
|
171
|
+
non-goals: still single-user-runtime, not a managed service, not pgvector
|
|
172
|
+
evangelism. A v4.0.0 multi-user direction is anticipated in the roadmap so v2's
|
|
173
|
+
opaque DocIds, adapter seams, content-stable ChunkIds, and provenance-on-every-
|
|
174
|
+
agent-write read as deliberate choices in service of that path. Neither is
|
|
175
|
+
committed work. See [.planning/ROADMAP.md](.planning/ROADMAP.md) for the full
|
|
176
|
+
phase plan and the v3/v4 deferred sections.
|
|
177
|
+
|
|
178
|
+
## Install and docs
|
|
179
|
+
|
|
180
|
+
### Prerequisites
|
|
181
|
+
|
|
182
|
+
- **Node.js >= 22** — runtime for the MCP server (`brew install node@22`).
|
|
183
|
+
- **[Ollama](https://ollama.com)** on `localhost:11434` — local embedding host
|
|
184
|
+
(`brew install ollama && brew services start ollama`).
|
|
185
|
+
- **`bge-m3`** embedding model (~1.1 GB) — vectors for semantic search
|
|
186
|
+
(`ollama pull bge-m3`).
|
|
187
|
+
- One or more Obsidian vaults — what you index.
|
|
188
|
+
- An MCP-aware client — the agent that consumes the tools.
|
|
189
|
+
|
|
190
|
+
Tested on macOS. Linux should work; Windows untested. Optional ONNX reranker
|
|
191
|
+
(`bge-reranker-v2-m3`, ~570 MB) via `bash scripts/download-reranker.sh`.
|
|
192
|
+
|
|
193
|
+
### Install
|
|
346
194
|
|
|
347
195
|
```bash
|
|
348
|
-
npm install
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
npm run build
|
|
196
|
+
npm install -g @owrede/vault-memory
|
|
197
|
+
vault-memory add-vault "/path/to/your/obsidian/vault"
|
|
198
|
+
vault-memory serve
|
|
352
199
|
```
|
|
353
200
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
[
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
201
|
+
The `add-vault` command appends a `[[vaults]]` block to
|
|
202
|
+
`~/.vault-memory/config.toml`, writes a `.mcp.json` into the vault root, and runs
|
|
203
|
+
the initial index. Idempotent — re-running on a known path fills in whatever is
|
|
204
|
+
missing. Flags: `--name <slug>`, `--write` (enable MCP writes; default read-only),
|
|
205
|
+
`--no-index` (skip the initial index).
|
|
206
|
+
|
|
207
|
+
### Documentation
|
|
208
|
+
|
|
209
|
+
- **Plugin install** — [docs/v2/plugin/INSTALL.md](docs/v2/plugin/INSTALL.md)
|
|
210
|
+
- **Plugin README** — [docs/v2/plugin/README.md](docs/v2/plugin/README.md)
|
|
211
|
+
- **Migration v1 to v2** — [docs/v2/MIGRATION-V1-TO-V2.md](docs/v2/MIGRATION-V1-TO-V2.md)
|
|
212
|
+
- **Architecture deep-dive** — [docs/v2/ARCHITECTURE.md](docs/v2/ARCHITECTURE.md)
|
|
213
|
+
- **Memory contract** — [docs/v2/MEMORY_CONTRACT.md](docs/v2/MEMORY_CONTRACT.md)
|
|
214
|
+
- **Agent-agnostic statement** — [docs/v2/AGENT_AGNOSTIC.md](docs/v2/AGENT_AGNOSTIC.md)
|
|
215
|
+
- **ADR index** — [docs/v2/adr/README.md](docs/v2/adr/README.md)
|
|
216
|
+
- **Changelog** — [CHANGELOG.md](./CHANGELOG.md)
|
|
217
|
+
|
|
218
|
+
SemVer-locked tool API per the v1.0.0 declaration. v2.0.0 is additive: the 23 v1
|
|
219
|
+
tool names + input schemas are preserved byte-identical, and the 5 list-style
|
|
220
|
+
tools promoted to MCP Resources remain callable through v2.x with a `DEPRECATED`
|
|
221
|
+
notice in their tool description (removal scheduled for v3.0.0). See
|
|
222
|
+
[CHANGELOG.md](./CHANGELOG.md) for full history.
|
|
369
223
|
|
|
370
224
|
## License
|
|
371
225
|
|