neuro-vault-mcp 1.3.1 → 1.4.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 CHANGED
@@ -1,133 +1,277 @@
1
1
  # Neuro Vault MCP
2
2
 
3
- Neuro Vault MCP is a Model Context Protocol server for semantic search over an Obsidian vault that already has Smart Connections embeddings and note data on disk. It reads Smart Connections `.smart-env/multi/*.ajson` files, loads the corpus into memory, and exposes MCP tools over stdio so compatible clients can search the vault without extra infrastructure.
3
+ **Semantic vault search and expansion for your Obsidian vault — right inside your AI assistant.**
4
4
 
5
- ## Overview
5
+ [![npm version](https://img.shields.io/npm/v/neuro-vault-mcp)](https://www.npmjs.com/package/neuro-vault-mcp)
6
+ [![Node.js](https://img.shields.io/node/v/neuro-vault-mcp)](https://nodejs.org)
7
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](LICENSE)
6
8
 
7
- The server is started by an MCP host or from the command line with an explicit vault path:
9
+ > "What did I write about that idea last month?"
8
10
 
9
- ```bash
10
- neuro-vault-mcp --vault /absolute/path/to/vault
11
- ```
11
+ Neuro Vault MCP provides semantic search over your Obsidian vault and semantic expansion for related notes. Agents can combine it with structural tools for exact note, path, date, tag, property, and link lookups when those tools are available. It reuses the embeddings already computed by [Smart Connections](https://github.com/brianpetro/obsidian-smart-connections) — no re-indexing, no extra infrastructure, no API keys.
12
+
13
+ ---
12
14
 
13
- The vault path must be absolute. Neuro Vault MCP expects Smart Connections data in:
15
+ ## How It Works
14
16
 
15
- ```text
16
- <vault>/.smart-env/multi/*.ajson
17
17
  ```
18
+ Your question
19
+ │
20
+ ▼
21
+ AI assistant
22
+ │ routes by intent
23
+ ▼
24
+ ├──────────────► Structural tools
25
+ │ (exact file, title, path, daily note, tag, property, wikilink, backlink, link traversal)
26
+ │
27
+ └──────────────► search_notes
28
+ (semantic retrieval)
29
+ │
30
+ ▼
31
+ get_similar_notes
32
+ (semantic expansion)
33
+ ```
34
+
35
+ The server loads `.smart-env/multi/*.ajson` into memory at startup and keeps it there. No background processes, no watchers, no database.
18
36
 
19
- On first run, the query embedding model is downloaded automatically. That initial model download may add noticeable startup latency.
37
+ ## Search Routing
38
+
39
+ Tool routing and retrieval policy are related, but not the same thing.
40
+
41
+ - Use structural tools first for exact file, title, path, daily note, tag, property, wikilink, backlink, and link traversal requests.
42
+ - Use `search_notes` for fuzzy topic, concept, and semantic retrieval.
43
+ - Use `get_similar_notes` after you already have a relevant note and want semantic expansion.
44
+ - Treat the routing guidance as behavior, not enforcement; the server does not hard-block other tool choices.
45
+ - Use semantic retrieval to find likely notes, then switch to structural tools when you need exact anchors.
46
+
47
+ ---
20
48
 
21
49
  ## Requirements
22
50
 
23
- - Node.js 20 or newer
24
- - An Obsidian vault on the local machine
25
- - Smart Connections data present in `<vault>/.smart-env/multi/*.ajson`
51
+ - Node.js 20+
52
+ - Obsidian vault with [Smart Connections](https://github.com/brianpetro/obsidian-smart-connections) plugin (embeddings must be generated)
53
+ - Smart Connections data at `<vault>/.smart-env/multi/*.ajson`
54
+
55
+ ---
26
56
 
27
- ## Installation
57
+ ## Quick Start
28
58
 
29
- Install globally:
59
+ **1. Install**
30
60
 
31
61
  ```bash
32
62
  npm install -g neuro-vault-mcp
33
63
  ```
34
64
 
35
- Or run it on demand with `npx`:
65
+ **2. Configure your MCP client**
36
66
 
37
- ```bash
38
- npx -y neuro-vault-mcp --vault /absolute/path/to/vault
39
- ```
67
+ For Claude Code (`~/.claude/settings.json` or `.claude/settings.json` in your project):
40
68
 
41
- ## MCP Configuration Example
69
+ ```json
70
+ {
71
+ "mcpServers": {
72
+ "neuro-vault": {
73
+ "command": "neuro-vault-mcp",
74
+ "args": ["--vault", "/absolute/path/to/your/vault"]
75
+ }
76
+ }
77
+ }
78
+ ```
42
79
 
43
- Most MCP hosts just need the binary and vault argument:
80
+ For Cursor or Windsurf (`.cursor/mcp.json` / `.windsurf/mcp.json`):
44
81
 
45
82
  ```json
46
83
  {
47
- "command": "neuro-vault-mcp",
48
- "args": ["--vault", "/absolute/path/to/vault"]
84
+ "mcpServers": {
85
+ "neuro-vault": {
86
+ "command": "neuro-vault-mcp",
87
+ "args": ["--vault", "/absolute/path/to/your/vault"]
88
+ }
89
+ }
49
90
  }
50
91
  ```
51
92
 
52
- If your host uses a more explicit JSON configuration, the same launch command applies:
93
+ Or run without installing using `npx`:
53
94
 
54
95
  ```json
55
96
  {
56
97
  "mcpServers": {
57
98
  "neuro-vault": {
58
- "command": "neuro-vault-mcp",
59
- "args": ["--vault", "/absolute/path/to/vault"]
99
+ "command": "npx",
100
+ "args": ["-y", "neuro-vault-mcp", "--vault", "/absolute/path/to/your/vault"]
60
101
  }
61
102
  }
62
103
  }
63
104
  ```
64
105
 
65
- ## CLI Usage
106
+ **3. Try it**
66
107
 
67
- After installing globally, launch the server directly from your shell:
108
+ Ask your assistant:
68
109
 
69
- ```bash
70
- neuro-vault-mcp --vault /absolute/path/to/vault
71
- ```
110
+ > "What did I write about building AI agents?"
111
+
112
+ > "Find my notes on productivity systems"
113
+
114
+ > "What are all my ideas related to embeddings?"
115
+
116
+ On first run the embedding model downloads automatically (~40 MB). Subsequent starts are fast.
117
+
118
+ ---
119
+
120
+ ## Features
121
+
122
+ ### Mode-Based Search
123
+
124
+ Every search picks a mode that controls retrieval depth:
72
125
 
73
- The process speaks MCP over stdio, so it is intended to be started by a compatible client or wrapper process rather than visited in a browser.
126
+ | Mode | Use when | Limit | Threshold | Expansion |
127
+ | ------- | --------------------------------- | ----- | --------- | --------- |
128
+ | `quick` | Specific question, need 1-2 notes | 3 | 0.50 | off |
129
+ | `deep` | Broad topic, need an overview | 8 | 0.35 | on |
74
130
 
75
- ## Available Tools
131
+ The AI assistant picks the mode automatically based on your question. You can also pass it explicitly.
132
+
133
+ ### Block-Level Results (Deep Mode)
134
+
135
+ In `deep` mode the server also searches by individual note sections (blocks), not just whole notes. This surfaces the exact paragraphs that are most relevant, not just the note they live in.
136
+
137
+ ### Expansion (Deep Mode)
138
+
139
+ After finding top results, the server uses their embeddings to discover neighboring notes. This catches related notes that don't directly match your query but are semantically close to what you found.
140
+
141
+ ### Automatic Fallback
142
+
143
+ When vector search returns nothing, the server retries with a lower similarity threshold (0.3). If still nothing — the AI assistant can search vault files using its own tools.
144
+
145
+ ---
146
+
147
+ ## Tools Reference
76
148
 
77
149
  ### `search_notes`
78
150
 
79
- Search the loaded corpus by semantic similarity.
151
+ Search the vault by semantic similarity.
152
+
153
+ ```typescript
154
+ search_notes({
155
+ query: string, // short keyword query (1-4 words)
156
+ mode?: "quick" | "deep", // default: "quick"
157
+ threshold?: number, // override mode default (0–1)
158
+ expansion?: boolean, // override mode default
159
+ expansion_limit?: number, // how many top results to expand (default: 3)
160
+ })
161
+ ```
162
+
163
+ Returns `results` (ranked notes) and `blockResults` (ranked sections — scoped to matched notes in quick mode, all sources in deep mode).
164
+
165
+ **Tips for better results:**
80
166
 
81
- Parameters:
167
+ - Use short keyword queries (1–4 words), not full sentences
168
+ - Call multiple times for synonyms and translations: `"embeddings"`, then `"векторний пошук"`, then `"vector search"`
169
+ - Lower the threshold to `0.3` if nothing comes back
170
+ - Use `deep` mode for exploratory questions
82
171
 
83
- - `query` `string` required
84
- - `limit` `number` optional, default `10`, must be a positive integer
85
- - `threshold` `number` optional, default `0.5`, must be between `0` and `1`
172
+ ---
86
173
 
87
174
  ### `get_similar_notes`
88
175
 
89
- Find notes similar to a vault-relative note path.
176
+ Find notes similar to a given note path.
177
+
178
+ ```typescript
179
+ get_similar_notes({
180
+ note_path: string, // vault-relative POSIX path, e.g. "Projects/neuro-vault.md"
181
+ limit?: number, // default: 10
182
+ threshold?: number, // default: 0.5
183
+ })
184
+ ```
90
185
 
91
- Parameters:
186
+ Use this after `search_notes` finds a relevant note — it discovers related content without needing a text query.
92
187
 
93
- - `note_path` `string` required, vault-relative and POSIX-style
94
- - `limit` `number` optional, default `10`, must be a positive integer
95
- - `threshold` `number` optional, default `0.5`, must be between `0` and `1`
188
+ ---
96
189
 
97
190
  ### `find_duplicates`
98
191
 
99
192
  Find note pairs with high embedding similarity.
100
193
 
101
- Parameters:
194
+ ```typescript
195
+ find_duplicates({
196
+ threshold?: number, // default: 0.9
197
+ })
198
+ ```
199
+
200
+ Useful for vault maintenance: identifies notes that cover the same topic and could be merged.
102
201
 
103
- - `threshold` `number` optional, default `0.9`, must be between `0` and `1`
202
+ ---
104
203
 
105
204
  ### `get_stats`
106
205
 
107
- Report corpus and embedding statistics.
206
+ Report loaded corpus statistics.
108
207
 
109
- Parameters:
208
+ Returns: `{ totalNotes, totalBlocks, embeddingDimension, modelKey }`
110
209
 
111
- - none
210
+ ---
112
211
 
113
- ## Tool Output
212
+ ## AGENTS.md / CLAUDE.md Snippet
114
213
 
115
- All search-style tools return note paths relative to the vault, similarity scores, and the note blocks preserved from Smart Connections data. `get_stats` returns the loaded corpus size, block count, embedding dimension, and model key.
214
+ Add this to your `AGENTS.md` or `CLAUDE.md` to help the AI assistant use the vault effectively:
116
215
 
117
- ## Development Commands
216
+ ```markdown
217
+ ## Vault search
218
+
219
+ Use vault-aware tools when vault context matters.
220
+ Do not guess about note contents when the vault can be searched.
221
+ Follow the Neuro Vault MCP server instructions for routing and retrieval.
222
+ ```
223
+
224
+ ---
225
+
226
+ ## Configuration
227
+
228
+ ### CLI Arguments
229
+
230
+ | Argument | Required | Description |
231
+ | --------- | -------- | --------------------------------------------- |
232
+ | `--vault` | yes | Absolute path to the Obsidian vault directory |
233
+ | `--help` | no | Show help |
234
+
235
+ ### Startup Behavior
236
+
237
+ - Smart Connections `.ajson` files are loaded into memory once at startup
238
+ - The embedding model (`TaylorAI/bge-micro-v2`) is downloaded on first run and cached by `@xenova/transformers`
239
+ - If the vault path is missing or Smart Connections data is absent, the server exits immediately with an error
240
+
241
+ ### Troubleshooting
242
+
243
+ **"Smart Connections directory does not exist"** — make sure the Smart Connections plugin has run and generated embeddings. Open Obsidian, let Smart Connections finish indexing, then restart the MCP server.
244
+
245
+ **First startup is slow** — the embedding model (~40 MB) is downloading. Subsequent starts use the cached model.
246
+
247
+ **Search returns nothing** — try lowering the threshold: `threshold: 0.3`. Also check that `get_stats` shows a non-zero `totalNotes`.
248
+
249
+ ---
250
+
251
+ ## Development
118
252
 
119
253
  ```bash
120
- npm run build
121
- npm run lint
122
- npm run format
123
- npm run format:write
124
- npm run test
254
+ npm run build # compile TypeScript to dist/
255
+ npm run test # run tests with vitest
256
+ npm run lint # ESLint
257
+ npm run format # check formatting with Prettier
258
+ npm run format:write # fix formatting
125
259
  ```
126
260
 
127
- ## Limitations for v1
261
+ ---
262
+
263
+ ## Limitations
128
264
 
129
265
  - Requires Smart Connections `.ajson` files already present in the vault
130
- - Uses in-memory search only, with no persistent index
131
- - Starts over stdio only, not HTTP or SSE
132
- - Loads the embedding model at startup, so the first run can be slow
133
- - Expects a local vault path and does not support remote vaults
266
+ - In-memory search only — no persistent index, no background re-indexing
267
+ - stdio transport only — not HTTP or SSE
268
+ - Local vault path only — no remote vaults
269
+ - Embedding model loaded at startup; first run can be slow
270
+
271
+ ---
272
+
273
+ ## License
274
+
275
+ ISC — see [LICENSE](LICENSE).
276
+
277
+ Changelog: [Releases](https://github.com/AlexMost/neuro-vault/releases)
package/dist/cli.d.ts CHANGED
@@ -2,6 +2,11 @@
2
2
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
4
 
5
+ interface RetrievalOutput {
6
+ results: SearchResult[];
7
+ blockResults?: BlockSearchResult[];
8
+ }
9
+
5
10
  interface SmartBlock {
6
11
  key: string;
7
12
  heading: string;
@@ -13,14 +18,15 @@ interface SmartSource {
13
18
  embedding: number[];
14
19
  blocks: SmartBlock[];
15
20
  }
16
- interface SearchResultBlock {
21
+ interface BlockSearchResult {
22
+ path: string;
17
23
  heading: string;
18
24
  lines: [number, number];
25
+ similarity: number;
19
26
  }
20
27
  interface SearchResult {
21
28
  path: string;
22
29
  similarity: number;
23
- blocks: SearchResultBlock[];
24
30
  }
25
31
  interface DuplicatePair {
26
32
  note_a: string;
@@ -39,15 +45,25 @@ interface SearchEngine {
39
45
  limit?: number;
40
46
  excludePath?: string;
41
47
  }): SearchResult[];
48
+ findBlockNeighbors(args: {
49
+ queryVector: number[];
50
+ sources: Iterable<SmartSource>;
51
+ threshold: number;
52
+ limit?: number;
53
+ }): BlockSearchResult[];
42
54
  findDuplicates(args: {
43
55
  sources: Iterable<SmartSource>;
44
56
  threshold: number;
45
57
  }): DuplicatePair[];
46
58
  }
59
+ type SearchMode = 'quick' | 'deep';
47
60
  interface SearchNotesInput {
48
61
  query: string;
62
+ mode?: SearchMode;
49
63
  limit?: number;
50
64
  threshold?: number;
65
+ expansion?: boolean;
66
+ expansion_limit?: number;
51
67
  }
52
68
  interface GetSimilarNotesInput {
53
69
  note_path: string;
@@ -72,7 +88,7 @@ interface ToolHandlerDependencies {
72
88
  modelKey: string;
73
89
  }
74
90
  interface ToolHandlers {
75
- searchNotes(input: SearchNotesInput): Promise<SearchResult[]>;
91
+ searchNotes(input: SearchNotesInput): Promise<RetrievalOutput>;
76
92
  getSimilarNotes(input: GetSimilarNotesInput): Promise<SearchResult[]>;
77
93
  findDuplicates(input?: FindDuplicatesInput): Promise<DuplicatePair[]>;
78
94
  getStats(): Promise<ToolStats>;