neuro-vault-mcp 4.0.1 → 4.2.0

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
@@ -18,7 +18,7 @@ Your second brain stops being a folder you open between contexts and becomes a f
18
18
 
19
19
  - 🧠 **Semantic search that already knows your vault** — reuses [Smart Connections](https://github.com/brianpetro/obsidian-smart-connections) embeddings. No re-indexing, no API keys, no extra infrastructure.
20
20
  - 🎯 **Quick or deep, your call** — fast direct lookups for "find that note", or exploratory mode with related-note expansion when the question is fuzzy.
21
- - 🧭 **A real navigation toolkit for your agent** — instead of grepping files and opening notes one by one, your assistant walks the vault like a database: filter by tags and properties, batch-read metadata, discover the structure, jump to semantic neighbours.
21
+ - 🧭 **A real navigation toolkit for your agent** — instead of grepping files and opening notes one by one, your assistant walks the vault like a database: filter by tags and properties, batch-read metadata, traverse the wikilink graph, discover the structure, jump to semantic neighbours.
22
22
  - 🔎 **Ask structured questions in plain language** — _"active projects tagged #ai"_, _"todo tasks with a deadline this week"_, _"meeting notes from `Work/` newest first"_ — one call, ranked answer, no chains of reads.
23
23
  - ✍️ **Read and write through Obsidian itself** — create, append, edit notes, manage frontmatter and daily notes via the [Obsidian CLI](https://github.com/AlexMost/obsidian-cli), so Smart Connections, sync, and other plugins stay in the loop.
24
24
  - ⚡ **Zero infrastructure** — local stdio MCP server, in-memory index, no database, no background processes, no watchers.
package/dist/cli.d.ts CHANGED
@@ -18,6 +18,63 @@ interface SmartConnectionsCorpus {
18
18
  sources: Map<string, SmartSource>;
19
19
  }
20
20
 
21
+ type ReadNotesField = 'frontmatter' | 'content';
22
+ interface ReadNotesItemSuccess {
23
+ path: string;
24
+ frontmatter: Record<string, unknown> | null;
25
+ content: string;
26
+ }
27
+ interface ReadNotesItemError {
28
+ path: string;
29
+ error: {
30
+ code: 'NOT_FOUND' | 'INVALID_ARGUMENT' | 'READ_FAILED';
31
+ message: string;
32
+ };
33
+ }
34
+ type ReadNotesItem = ReadNotesItemSuccess | ReadNotesItemError;
35
+ interface ReadNotesInput {
36
+ paths: string[];
37
+ fields: ReadNotesField[];
38
+ }
39
+ interface ScanOptions {
40
+ pathPrefix?: string;
41
+ }
42
+ interface VaultReader {
43
+ readNotes(input: ReadNotesInput): Promise<ReadNotesItem[]>;
44
+ scan(opts?: ScanOptions): Promise<string[]>;
45
+ }
46
+
47
+ interface OutgoingLink {
48
+ target: string;
49
+ resolved: boolean;
50
+ path?: string;
51
+ }
52
+ interface IncomingLink {
53
+ source: string;
54
+ }
55
+ interface NoteLinks {
56
+ incoming: IncomingLink[];
57
+ outgoing: OutgoingLink[];
58
+ }
59
+ interface WikilinkGraphIndexOptions {
60
+ reader: VaultReader;
61
+ ttlMs?: number;
62
+ now?: () => number;
63
+ }
64
+ declare class WikilinkGraphIndex {
65
+ private readonly reader;
66
+ private readonly ttlMs;
67
+ private readonly now;
68
+ private byPath;
69
+ private lastBuildAt;
70
+ private buildPromise;
71
+ constructor(opts: WikilinkGraphIndexOptions);
72
+ ensureFresh(): Promise<void>;
73
+ getNoteLinks(notePath: string): NoteLinks;
74
+ getBacklinkCount(notePath: string): number;
75
+ private rebuild;
76
+ }
77
+
21
78
  interface BlockSearchResult {
22
79
  path: string;
23
80
  heading: string;
@@ -65,6 +122,10 @@ interface SemanticModuleDeps {
65
122
  searchEngine?: SearchEngine;
66
123
  pathExists?: PathExistsCheck;
67
124
  readNoteContent?: (vaultRelativePath: string) => Promise<string>;
125
+ graph?: WikilinkGraphIndex;
126
+ vaultReaderFactory?: (opts: {
127
+ vaultRoot: string;
128
+ }) => VaultReader;
68
129
  }
69
130
 
70
131
  type NoteIdentifier = {
@@ -150,37 +211,12 @@ interface ObsidianCLIProviderOptions {
150
211
  exec?: ExecFn;
151
212
  }
152
213
 
153
- type ReadNotesField = 'frontmatter' | 'content';
154
- interface ReadNotesItemSuccess {
155
- path: string;
156
- frontmatter: Record<string, unknown> | null;
157
- content: string;
158
- }
159
- interface ReadNotesItemError {
160
- path: string;
161
- error: {
162
- code: 'NOT_FOUND' | 'INVALID_ARGUMENT' | 'READ_FAILED';
163
- message: string;
164
- };
165
- }
166
- type ReadNotesItem = ReadNotesItemSuccess | ReadNotesItemError;
167
- interface ReadNotesInput {
168
- paths: string[];
169
- fields: ReadNotesField[];
170
- }
171
- interface ScanOptions {
172
- pathPrefix?: string;
173
- }
174
- interface VaultReader {
175
- readNotes(input: ReadNotesInput): Promise<ReadNotesItem[]>;
176
- scan(opts?: ScanOptions): Promise<string[]>;
177
- }
178
-
179
214
  interface OperationsModuleDeps {
180
215
  vaultProviderFactory?: (opts: ObsidianCLIProviderOptions) => VaultProvider;
181
216
  vaultReaderFactory?: (opts: {
182
217
  vaultRoot: string;
183
218
  }) => VaultReader;
219
+ graph?: WikilinkGraphIndex;
184
220
  }
185
221
 
186
222
  type ToolServer = Pick<McpServer, 'registerTool' | 'connect'>;