obsidian-mcp-server 3.1.11 → 3.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.
Files changed (40) hide show
  1. package/CLAUDE.md +2 -2
  2. package/README.md +14 -13
  3. package/changelog/3.2.x/3.2.0.md +49 -0
  4. package/dist/config/server-config.d.ts +1 -0
  5. package/dist/config/server-config.d.ts.map +1 -1
  6. package/dist/config/server-config.js +6 -0
  7. package/dist/config/server-config.js.map +1 -1
  8. package/dist/index.d.ts +4 -2
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +26 -9
  11. package/dist/index.js.map +1 -1
  12. package/dist/mcp-server/tools/definitions/_shared/regex-safety.d.ts +18 -0
  13. package/dist/mcp-server/tools/definitions/_shared/regex-safety.d.ts.map +1 -0
  14. package/dist/mcp-server/tools/definitions/_shared/regex-safety.js +34 -0
  15. package/dist/mcp-server/tools/definitions/_shared/regex-safety.js.map +1 -0
  16. package/dist/mcp-server/tools/definitions/_shared/schemas.js +1 -1
  17. package/dist/mcp-server/tools/definitions/_shared/schemas.js.map +1 -1
  18. package/dist/mcp-server/tools/definitions/index.d.ts +30 -844
  19. package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
  20. package/dist/mcp-server/tools/definitions/index.js +10 -6
  21. package/dist/mcp-server/tools/definitions/index.js.map +1 -1
  22. package/dist/mcp-server/tools/definitions/obsidian-list-commands.tool.d.ts +21 -2
  23. package/dist/mcp-server/tools/definitions/obsidian-list-commands.tool.d.ts.map +1 -1
  24. package/dist/mcp-server/tools/definitions/obsidian-list-commands.tool.js +59 -6
  25. package/dist/mcp-server/tools/definitions/obsidian-list-commands.tool.js.map +1 -1
  26. package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.d.ts.map +1 -1
  27. package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.js +2 -22
  28. package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.js.map +1 -1
  29. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts +175 -19
  30. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts.map +1 -1
  31. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js +249 -134
  32. package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js.map +1 -1
  33. package/dist/services/obsidian/obsidian-service.d.ts +22 -2
  34. package/dist/services/obsidian/obsidian-service.d.ts.map +1 -1
  35. package/dist/services/obsidian/obsidian-service.js +143 -12
  36. package/dist/services/obsidian/obsidian-service.js.map +1 -1
  37. package/dist/services/obsidian/types.d.ts +25 -1
  38. package/dist/services/obsidian/types.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/server.json +3 -3
@@ -1,17 +1,25 @@
1
1
  /**
2
- * @fileoverview obsidian_search_notes — text/dataview/jsonlogic search.
3
- * Caps results at 100 hits and surfaces an `excluded` indicator when more
4
- * were returned upstream. Text-mode hits are additionally capped per file
5
- * via `maxMatchesPerHit` so a single match-heavy note can't blow the
6
- * response budget — clipped hits carry `truncated: true` and `totalMatches`.
2
+ * @fileoverview obsidian_search_notes — text/jsonlogic/omnisearch search with
3
+ * MCP-spec cursor pagination. The `omnisearch` mode is added conditionally by
4
+ * the entry point only when the Omnisearch plugin's HTTP server is reachable
5
+ * at startup. Text-mode hits additionally clip per file via `maxMatchesPerHit`
6
+ * so a single match-heavy note can't blow the response budget — clipped hits
7
+ * carry `truncated: true` and `totalMatches`.
7
8
  * @module mcp-server/tools/definitions/obsidian-search-notes.tool
8
9
  */
9
10
  import { tool, z } from '@cyanheads/mcp-ts-core';
10
11
  import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
12
+ import { paginateArray } from '@cyanheads/mcp-ts-core/utils';
11
13
  import { getObsidianService } from '../../../services/obsidian/obsidian-service.js';
12
- const HIT_CAP = 100;
14
+ const DEFAULT_PAGE_SIZE = 50;
15
+ const MAX_PAGE_SIZE = 200;
13
16
  const DEFAULT_MATCHES_PER_HIT = 10;
14
- const EXCLUSION_HINT = 'Narrow your query (add filters or more specific terms) to surface the rest.';
17
+ /** Omnisearch's hardwired upstream cap — pagination/limit params are ignored. */
18
+ const OMNISEARCH_UPSTREAM_CAP = 50;
19
+ const CursorSchema = z
20
+ .string()
21
+ .optional()
22
+ .describe('Opaque cursor from a prior response. Omit for the first page. Page size is server-determined; do not assume a fixed value.');
15
23
  const TextHitSchema = z
16
24
  .object({
17
25
  filename: z.string().describe('Vault-relative path of the matching note.'),
@@ -45,23 +53,50 @@ const StructuredHitSchema = z
45
53
  result: z.unknown().describe('The query result for this file — shape determined by the query.'),
46
54
  })
47
55
  .describe('A file with a structured (Dataview/JSONLogic) result value.');
48
- const ExcludedSchema = z
56
+ const OmnisearchHitSchema = z
49
57
  .object({
50
- count: z.number().describe('Number of additional hits the upstream returned beyond the cap.'),
51
- hint: z.string().describe('Suggestion for narrowing the query.'),
58
+ filename: z.string().describe('Vault-relative path of the matching note.'),
59
+ basename: z.string().describe('Note basename without extension.'),
60
+ score: z.number().describe('BM25 relevance score. Higher is more relevant.'),
61
+ foundWords: z
62
+ .array(z.string())
63
+ .describe('Query words found in the note. Populated even when no body match exists (e.g. basename-only match), so empty `matches` paired with non-empty `foundWords` is valid.'),
64
+ matches: z
65
+ .array(z
66
+ .object({
67
+ match: z.string().describe('The matched substring.'),
68
+ offset: z.number().describe('Offset of the match within the note body.'),
69
+ })
70
+ .describe('A single match span in the note body.'))
71
+ .describe('Match positions within the note body. May be empty for basename-only matches.'),
72
+ excerpt: z
73
+ .string()
74
+ .describe('Surrounding-context excerpt with `<mark>` around matches; HTML entities are decoded and `<br>` becomes `\\n`.'),
52
75
  })
53
- .optional();
54
- export const obsidianSearchNotes = tool('obsidian_search_notes', {
55
- description: `Search the vault by text substring, Dataview DQL query, or JSONLogic predicate. Pick the mode that matches the query shape. Results cap at ${HIT_CAP} hits with an \`excluded\` indicator when more were available; text-mode hits also clip per file at \`maxMatchesPerHit\`. On large vaults, narrow with \`pathPrefix\` or lower \`maxMatchesPerHit\` to keep responses compact.`,
56
- annotations: { readOnlyHint: true, idempotentHint: true },
57
- input: z.object({
76
+ .describe('An Omnisearch BM25-ranked hit.');
77
+ /**
78
+ * Build the `obsidian_search_notes` tool. The `omnisearch` mode is included
79
+ * in the input/output schemas only when `omnisearchReachable` is true so the
80
+ * LLM never sees it as an option on a deployment where it can't run. Re-probe
81
+ * requires a server restart.
82
+ */
83
+ export function buildSearchNotesTool({ omnisearchReachable }) {
84
+ const modeEnum = omnisearchReachable
85
+ ? ['text', 'jsonlogic', 'omnisearch']
86
+ : ['text', 'jsonlogic'];
87
+ const description = omnisearchReachable
88
+ ? 'Search the vault by text substring, JSONLogic predicate, or BM25-ranked Omnisearch query. Pick the mode that matches the query shape — `omnisearch` is best for ranked relevance, typo tolerance, and PDF/OCR coverage (via the Text Extractor plugin). Results paginate via opaque cursors: omit `cursor` for the first page, then pass `nextCursor` from the prior response. Text-mode hits additionally clip per file at `maxMatchesPerHit`.'
89
+ : 'Search the vault by text substring or JSONLogic predicate. Pick the mode that matches the query shape. Results paginate via opaque cursors: omit `cursor` for the first page, then pass `nextCursor` from the prior response. Text-mode hits additionally clip per file at `maxMatchesPerHit`.';
90
+ const inputSchema = z.object({
58
91
  mode: z
59
- .enum(['text', 'dataview', 'jsonlogic'])
60
- .describe('Which search algorithm to run. `text` matches a substring case-insensitively across filenames and note bodies, returning surrounding context windows. `dataview` runs a DQL query (e.g. `TABLE WHERE file.mtime > date(today)`) for path/date/metadata filters. `jsonlogic` evaluates a JSONLogic tree against each note, with `var` paths into `path`, `content`, `frontmatter.<key>`, `tags`, and `stat.{ctime,mtime,size}`, plus `glob` and `regexp` operators.'),
92
+ .enum(modeEnum)
93
+ .describe(omnisearchReachable
94
+ ? 'Which search algorithm to run. `text` matches a substring case-insensitively across filenames and note bodies, returning surrounding context windows. `jsonlogic` evaluates a JSONLogic tree against each note, with `var` paths into `path`, `content`, `frontmatter.<key>`, `tags`, and `stat.{ctime,mtime,size}`, plus `glob` and `regexp` operators. `omnisearch` runs a BM25-ranked query via the Omnisearch plugin — supports quoted phrases, `-exclusion`, `path:` / `ext:` filters, typo tolerance, and PDF/OCR (with Text Extractor); upstream caps results at 50.'
95
+ : 'Which search algorithm to run. `text` matches a substring case-insensitively across filenames and note bodies, returning surrounding context windows. `jsonlogic` evaluates a JSONLogic tree against each note, with `var` paths into `path`, `content`, `frontmatter.<key>`, `tags`, and `stat.{ctime,mtime,size}`, plus `glob` and `regexp` operators.'),
61
96
  query: z
62
97
  .string()
63
98
  .optional()
64
- .describe('For `text` mode: substring to match. For `dataview` mode: the DQL query string. Required for those modes.'),
99
+ .describe('For `text` and `omnisearch` modes: the query string. Required for both.'),
65
100
  logic: z
66
101
  .record(z.string(), z.unknown())
67
102
  .optional()
@@ -82,40 +117,70 @@ export const obsidianSearchNotes = tool('obsidian_search_notes', {
82
117
  .positive()
83
118
  .default(DEFAULT_MATCHES_PER_HIT)
84
119
  .describe('Cap on match contexts returned per file in text mode. When clipped, the hit carries `truncated: true` and `totalMatches`.'),
85
- }),
86
- output: z.object({
120
+ cursor: CursorSchema,
121
+ });
122
+ const textBranch = z
123
+ .object({
124
+ mode: z.literal('text').describe('Echoed mode.'),
125
+ hits: z.array(TextHitSchema).describe('Matching files with per-match context.'),
126
+ totalCount: z
127
+ .number()
128
+ .describe('Total post-path-policy hit count across all pages, before pagination.'),
129
+ nextCursor: z
130
+ .string()
131
+ .optional()
132
+ .describe('Opaque cursor for the next page. Omitted on the last page (do not treat absent as null).'),
133
+ })
134
+ .describe('Text-search results.');
135
+ const jsonlogicBranch = z
136
+ .object({
137
+ mode: z.literal('jsonlogic').describe('Echoed mode.'),
138
+ hits: z
139
+ .array(StructuredHitSchema)
140
+ .describe('Matching files with the JSONLogic result per file.'),
141
+ totalCount: z
142
+ .number()
143
+ .describe('Total post-path-policy hit count across all pages, before pagination.'),
144
+ nextCursor: z
145
+ .string()
146
+ .optional()
147
+ .describe('Opaque cursor for the next page. Omitted on the last page (do not treat absent as null).'),
148
+ })
149
+ .describe('JSONLogic results.');
150
+ const omnisearchBranch = z
151
+ .object({
152
+ mode: z.literal('omnisearch').describe('Echoed mode.'),
153
+ hits: z.array(OmnisearchHitSchema).describe('BM25-ranked matching files.'),
154
+ totalCount: z
155
+ .number()
156
+ .describe('Total post-path-policy hit count across all pages, before pagination.'),
157
+ nextCursor: z
158
+ .string()
159
+ .optional()
160
+ .describe('Opaque cursor for the next page. Omitted on the last page (do not treat absent as null).'),
161
+ truncated: z
162
+ .boolean()
163
+ .describe("True when the upstream returned exactly 50 raw hits (Omnisearch's hardwired cap); more matches may exist that are not retrievable. Narrow the query to surface additional results."),
164
+ })
165
+ .describe('Omnisearch BM25 results.');
166
+ const branches = omnisearchReachable
167
+ ? [textBranch, jsonlogicBranch, omnisearchBranch]
168
+ : [textBranch, jsonlogicBranch];
169
+ const outputSchema = z.object({
87
170
  result: z
88
- .discriminatedUnion('mode', [
89
- z
90
- .object({
91
- mode: z.literal('text').describe('Echoed mode.'),
92
- hits: z.array(TextHitSchema).describe('Matching files with per-match context.'),
93
- excluded: ExcludedSchema.describe('Present when results were truncated to the cap.'),
94
- })
95
- .describe('Text-search results.'),
96
- z
97
- .object({
98
- mode: z.literal('dataview').describe('Echoed mode.'),
99
- hits: z
100
- .array(StructuredHitSchema)
101
- .describe('Matching files with the query result per file.'),
102
- excluded: ExcludedSchema.describe('Present when results were truncated to the cap.'),
103
- })
104
- .describe('Dataview DQL results.'),
105
- z
106
- .object({
107
- mode: z.literal('jsonlogic').describe('Echoed mode.'),
108
- hits: z
109
- .array(StructuredHitSchema)
110
- .describe('Matching files with the JSONLogic result per file.'),
111
- excluded: ExcludedSchema.describe('Present when results were truncated to the cap.'),
112
- })
113
- .describe('JSONLogic results.'),
114
- ])
171
+ .discriminatedUnion('mode', [...branches])
115
172
  .describe('Mode-discriminated search payload.'),
116
- }),
117
- auth: ['tool:obsidian_search_notes:read'],
118
- errors: [
173
+ });
174
+ /**
175
+ * Declared inline as a `const` tuple so `tool()`'s `const TErrors` generic
176
+ * captures the literal reason strings — that's what gives the handler its
177
+ * typed `ctx.fail<'reason'>(...)`. The `omnisearch_unreachable` entry is
178
+ * declared unconditionally even when `omnisearchReachable` is false; the
179
+ * branch that throws it only runs in the omnisearch handler path (which
180
+ * only runs when reachable), so the entry is harmless when unused and
181
+ * keeps the contract shape stable across deployments.
182
+ */
183
+ const errors = [
119
184
  {
120
185
  reason: 'path_prefix_invalid_mode',
121
186
  code: JsonRpcErrorCode.ValidationError,
@@ -125,8 +190,8 @@ export const obsidianSearchNotes = tool('obsidian_search_notes', {
125
190
  {
126
191
  reason: 'query_required',
127
192
  code: JsonRpcErrorCode.ValidationError,
128
- when: '`query` is missing for `text` or `dataview` mode (required for both).',
129
- recovery: 'Pass `query` — search terms for text mode (e.g. "TODO"), or DQL like "TABLE WHERE file.mtime > date(today)" for dataview mode.',
193
+ when: '`query` is missing for `text` or `omnisearch` mode (required for both).',
194
+ recovery: 'Pass `query` — substring for text mode, or BM25 query syntax (quoted phrases, `-exclusion`, `path:` / `ext:` filters) for omnisearch.',
130
195
  },
131
196
  {
132
197
  reason: 'logic_required',
@@ -134,100 +199,150 @@ export const obsidianSearchNotes = tool('obsidian_search_notes', {
134
199
  when: '`logic` is missing for `jsonlogic` mode.',
135
200
  recovery: 'Pass a JSONLogic tree as `logic`, e.g. `{"glob": [{"var": "path"}, "Projects/*.md"]}`.',
136
201
  },
137
- ],
138
- async handler(input, ctx) {
139
- const svc = getObsidianService();
140
- if (input.pathPrefix && input.mode !== 'text') {
141
- throw ctx.fail('path_prefix_invalid_mode', '`pathPrefix` is only valid in text mode.', {
142
- mode: input.mode,
143
- ...ctx.recoveryFor('path_prefix_invalid_mode'),
144
- });
145
- }
146
- /**
147
- * Path-policy post-filter: reads outside OBSIDIAN_READ_PATHS are dropped
148
- * silently, before the per-mode cap. The `excluded` overflow indicator
149
- * counts hits trimmed by the cap, not hits dropped by the policy — leaking
150
- * the dropped count would defeat the gate.
151
- */
152
- const policy = svc.policy;
153
- if (input.mode === 'text') {
154
- if (!input.query) {
155
- throw ctx.fail('query_required', '`query` is required for text mode.', {
202
+ {
203
+ reason: 'omnisearch_unreachable',
204
+ code: JsonRpcErrorCode.ServiceUnavailable,
205
+ when: 'Omnisearch was reachable at startup but is now unreachable (Obsidian quit, plugin disabled, or mobile session).',
206
+ retryable: true,
207
+ recovery: 'Restart Obsidian with the Omnisearch plugin enabled, then restart this MCP server so it re-probes the plugin URL.',
208
+ },
209
+ ];
210
+ return tool('obsidian_search_notes', {
211
+ description,
212
+ annotations: { readOnlyHint: true, idempotentHint: true },
213
+ input: inputSchema,
214
+ output: outputSchema,
215
+ auth: ['tool:obsidian_search_notes:read'],
216
+ errors,
217
+ async handler(input, ctx) {
218
+ const svc = getObsidianService();
219
+ if (input.pathPrefix && input.mode !== 'text') {
220
+ throw ctx.fail('path_prefix_invalid_mode', '`pathPrefix` is only valid in text mode.', {
156
221
  mode: input.mode,
157
- ...ctx.recoveryFor('query_required'),
222
+ ...ctx.recoveryFor('path_prefix_invalid_mode'),
158
223
  });
159
224
  }
160
- const all = await svc.searchText(ctx, input.query, input.contextLength);
161
- const prefix = input.pathPrefix;
162
- const prefixed = prefix ? all.filter((h) => h.filename.startsWith(prefix)) : all;
163
- const allowed = policy.filterReadable(prefixed);
164
- const matchCap = input.maxMatchesPerHit;
165
- const clipped = allowed.map((h) => clipMatches(h, matchCap));
166
- const capped = applyCap(clipped);
167
- return { result: { mode: 'text', ...capped } };
168
- }
169
- if (input.mode === 'dataview') {
225
+ const policy = svc.policy;
226
+ if (input.mode === 'text') {
227
+ if (!input.query) {
228
+ throw ctx.fail('query_required', '`query` is required for text mode.', {
229
+ mode: input.mode,
230
+ ...ctx.recoveryFor('query_required'),
231
+ });
232
+ }
233
+ const raw = await svc.searchText(ctx, input.query, input.contextLength);
234
+ const prefix = input.pathPrefix;
235
+ const prefixed = prefix ? raw.filter((h) => h.filename.startsWith(prefix)) : raw;
236
+ const allowed = policy.filterReadable(prefixed);
237
+ const clipped = allowed.map((h) => clipMatches(h, input.maxMatchesPerHit));
238
+ return { result: { mode: 'text', ...paginate(clipped, input.cursor, ctx) } };
239
+ }
240
+ if (input.mode === 'jsonlogic') {
241
+ if (!input.logic) {
242
+ throw ctx.fail('logic_required', '`logic` (JSONLogic tree) is required for jsonlogic mode.', { mode: input.mode, ...ctx.recoveryFor('logic_required') });
243
+ }
244
+ const raw = await svc.searchJsonLogic(ctx, input.logic);
245
+ const allowed = policy.filterReadable(raw);
246
+ return { result: { mode: 'jsonlogic', ...paginate(allowed, input.cursor, ctx) } };
247
+ }
248
+ // omnisearch — only reachable when omnisearchReachable is true at build time.
170
249
  if (!input.query) {
171
- throw ctx.fail('query_required', '`query` (DQL string) is required for dataview mode.', {
250
+ throw ctx.fail('query_required', '`query` is required for omnisearch mode.', {
172
251
  mode: input.mode,
173
252
  ...ctx.recoveryFor('query_required'),
174
253
  });
175
254
  }
176
- const all = await svc.searchDataview(ctx, input.query);
177
- const allowed = policy.filterReadable(all);
178
- const capped = applyCap(allowed);
179
- return { result: { mode: 'dataview', ...capped } };
180
- }
181
- if (!input.logic) {
182
- throw ctx.fail('logic_required', '`logic` (JSONLogic tree) is required for jsonlogic mode.', {
183
- mode: input.mode,
184
- ...ctx.recoveryFor('logic_required'),
185
- });
186
- }
187
- const all = await svc.searchJsonLogic(ctx, input.logic);
188
- const allowed = policy.filterReadable(all);
189
- const capped = applyCap(allowed);
190
- return { result: { mode: 'jsonlogic', ...capped } };
191
- },
192
- format: ({ result }) => {
193
- const lines = [`**Search (${result.mode}) — ${result.hits.length} hits**`];
194
- if (result.excluded) {
195
- lines.push(`_Excluded ${result.excluded.count} additional hits — ${result.excluded.hint}_`);
196
- }
197
- if (result.hits.length === 0) {
198
- lines.push('', '_No matches. Try broader terms, a different mode, or check that the path/filter is correct._');
199
- return [{ type: 'text', text: lines.join('\n') }];
200
- }
201
- lines.push('');
202
- if (result.mode === 'text') {
203
- for (const h of result.hits) {
204
- const score = h.score !== undefined ? ` (score: ${h.score})` : '';
205
- const trunc = h.truncated
206
- ? ` — truncated, showing first ${h.matches.length} of ${h.totalMatches} matches`
207
- : '';
208
- lines.push(`### ${h.filename}${score}${trunc}`);
209
- for (const m of h.matches) {
210
- lines.push(`- match[${m.match.start}–${m.match.end}]: ${truncate(m.context, 240)}`);
255
+ const raw = await svc.searchOmnisearch(ctx, input.query);
256
+ /**
257
+ * Compute `truncated` against the raw upstream array, before path-policy
258
+ * filtering — a filtered-down set legitimately under 50 should not be
259
+ * reported as truncated.
260
+ */
261
+ const truncated = raw.length >= OMNISEARCH_UPSTREAM_CAP;
262
+ const allowed = policy.filterReadable(raw);
263
+ return {
264
+ result: {
265
+ mode: 'omnisearch',
266
+ ...paginate(allowed, input.cursor, ctx),
267
+ truncated,
268
+ },
269
+ };
270
+ },
271
+ format: ({ result }) => {
272
+ const lines = [];
273
+ const pageInfo = `${result.hits.length} on this page · ${result.totalCount} total`;
274
+ const cursorInfo = result.nextCursor ? ' · more available' : '';
275
+ lines.push(`**Search (${result.mode}) — ${pageInfo}${cursorInfo}**`);
276
+ if (result.mode === 'omnisearch' && result.truncated) {
277
+ lines.push(`_Upstream returned the full ${OMNISEARCH_UPSTREAM_CAP}-hit cap; more matches may exist. Narrow the query to surface them._`);
278
+ }
279
+ if (result.nextCursor) {
280
+ lines.push(`_Next page cursor: \`${result.nextCursor}\`_`);
281
+ }
282
+ if (result.hits.length === 0) {
283
+ lines.push('', '_No matches. Try broader terms, a different mode, or check that the path/filter is correct._');
284
+ return [{ type: 'text', text: lines.join('\n') }];
285
+ }
286
+ lines.push('');
287
+ if (result.mode === 'text') {
288
+ for (const h of result.hits) {
289
+ const score = h.score !== undefined ? ` (score: ${h.score})` : '';
290
+ const trunc = h.truncated
291
+ ? ` — truncated, showing first ${h.matches.length} of ${h.totalMatches} matches`
292
+ : '';
293
+ lines.push(`### ${h.filename}${score}${trunc}`);
294
+ for (const m of h.matches) {
295
+ lines.push(`- match[${m.match.start}–${m.match.end}]: ${truncate(m.context, 240)}`);
296
+ }
297
+ }
298
+ }
299
+ else if (result.mode === 'omnisearch') {
300
+ for (const h of result.hits) {
301
+ lines.push(`### ${h.filename} (score: ${h.score.toFixed(2)})`);
302
+ if (h.foundWords.length > 0) {
303
+ lines.push(`**Matched:** ${h.foundWords.map((w) => `\`${w}\``).join(', ')}`);
304
+ }
305
+ if (h.excerpt)
306
+ lines.push(`> ${h.excerpt.replace(/\n/g, '\n> ')}`);
211
307
  }
212
308
  }
213
- }
214
- else {
215
- for (const h of result.hits) {
216
- lines.push(`### ${h.filename}`);
217
- lines.push('```json');
218
- lines.push(safeJsonStringify(h.result));
219
- lines.push('```');
309
+ else {
310
+ for (const h of result.hits) {
311
+ lines.push(`### ${h.filename}`);
312
+ lines.push('```json');
313
+ lines.push(safeJsonStringify(h.result));
314
+ lines.push('```');
315
+ }
220
316
  }
221
- }
222
- return [{ type: 'text', text: lines.join('\n') }];
223
- },
224
- });
225
- function applyCap(all) {
226
- if (all.length <= HIT_CAP)
227
- return { hits: all, excluded: undefined };
317
+ return [{ type: 'text', text: lines.join('\n') }];
318
+ },
319
+ });
320
+ }
321
+ /**
322
+ * Static specimen for the MCP definition linter (which duck-types tool
323
+ * exports out of each `.tool.ts` file) and for existing tests that import
324
+ * the tool directly. Defaults to `omnisearchReachable: false` — the safe
325
+ * baseline that doesn't assume the optional plugin is installed. The entry
326
+ * point (`src/index.ts`) builds the live tool via `buildSearchNotesTool`
327
+ * with the actual probe result; this export is not the registered tool.
328
+ * The omnisearch-enabled variant is exercised by tests rather than the
329
+ * linter (two exports under the same tool name would collide on
330
+ * `name-unique`).
331
+ */
332
+ export const obsidianSearchNotes = buildSearchNotesTool({ omnisearchReachable: false });
333
+ /**
334
+ * Apply MCP-spec cursor pagination to a fully assembled, post-filter result
335
+ * array. Returns the page's hits, the total pre-pagination count, and
336
+ * `nextCursor` (omitted on the last page). Localizes the `Context` →
337
+ * `RequestContext` cast — `paginateArray`'s signature requires the index-
338
+ * signature shape that handler-facing `Context` doesn't carry.
339
+ */
340
+ function paginate(items, cursor, ctx) {
341
+ const page = paginateArray(items, cursor, DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE, ctx);
228
342
  return {
229
- hits: all.slice(0, HIT_CAP),
230
- excluded: { count: all.length - HIT_CAP, hint: EXCLUSION_HINT },
343
+ hits: page.items,
344
+ totalCount: page.totalCount ?? items.length,
345
+ ...(page.nextCursor !== undefined ? { nextCursor: page.nextCursor } : {}),
231
346
  };
232
347
  }
233
348
  function clipMatches(hit, cap) {
@@ -1 +1 @@
1
- {"version":3,"file":"obsidian-search-notes.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-search-notes.tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"obsidian-search-notes.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-search-notes.tool.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ import type { Context } from '@cyanheads/mcp-ts-core';
8
8
  import { type Dispatcher, type RequestInit, fetch as undiciFetch } from 'undici';
9
9
  import { type ServerConfig } from '../../config/server-config.js';
10
10
  import { PathPolicy } from './path-policy.js';
11
- import type { DocumentMap, FileListing, NoteJson, NoteTarget, ObsidianCommand, ObsidianTag, PatchHeaders, StructuredSearchHit, TextSearchHit, VaultStatus } from './types.js';
11
+ import type { DocumentMap, FileListing, NoteJson, NoteTarget, ObsidianCommand, ObsidianTag, OmnisearchHit, PatchHeaders, StructuredSearchHit, TextSearchHit, VaultStatus } from './types.js';
12
12
  type UndiciResponse = Awaited<ReturnType<typeof undiciFetch>>;
13
13
  /**
14
14
  * The HTTP fetch contract this service depends on. Defaults to undici's
@@ -30,6 +30,8 @@ export declare class ObsidianService {
30
30
  constructor(config: ServerConfig, fetchImpl?: ObsidianFetch);
31
31
  /** Path-policy accessor — used by `obsidian_search_notes` to filter hits. */
32
32
  get policy(): PathPolicy;
33
+ /** Resolved Omnisearch URL (derived from baseUrl or OBSIDIAN_OMNISEARCH_URL override). */
34
+ get omnisearchUrl(): string;
33
35
  getStatus(ctx: Context): Promise<VaultStatus>;
34
36
  /**
35
37
  * Probe whether the configured `OBSIDIAN_API_KEY` is accepted. Hits the
@@ -78,8 +80,26 @@ export declare class ObsidianService {
78
80
  listTags(ctx: Context): Promise<ObsidianTag[]>;
79
81
  listCommands(ctx: Context): Promise<ObsidianCommand[]>;
80
82
  searchText(ctx: Context, query: string, contextLength?: number): Promise<TextSearchHit[]>;
81
- searchDataview(ctx: Context, dql: string): Promise<StructuredSearchHit[]>;
82
83
  searchJsonLogic(ctx: Context, logic: Record<string, unknown>): Promise<StructuredSearchHit[]>;
84
+ /**
85
+ * One-shot startup probe for the Omnisearch plugin's HTTP endpoint. Returns
86
+ * `true` only when the response is `HTTP 200`, declares `application/json`,
87
+ * and the body parses as a JSON array — unrouted paths on the Omnisearch
88
+ * server also return `200` with an empty body, so status alone is
89
+ * insufficient. The entry point passes the return value into the
90
+ * `obsidian_search_notes` factory to decide whether to expose the
91
+ * `omnisearch` mode.
92
+ */
93
+ probeOmnisearch(signal?: AbortSignal): Promise<boolean>;
94
+ /**
95
+ * Query the Omnisearch HTTP endpoint. Normalizes the response on the way
96
+ * out: decodes HTML entities + `<br>` → `\n` in `excerpt`, renames `path`
97
+ * to `filename`, and drops `vault`. Throws `omnisearch_unreachable`
98
+ * (ServiceUnavailable) on network failures or non-2xx responses — the
99
+ * plugin can shut down mid-session (Obsidian quits, plugin disabled), and
100
+ * the tool needs a distinct signal from the upstream's success cases.
101
+ */
102
+ searchOmnisearch(ctx: Context, query: string): Promise<OmnisearchHit[]>;
83
103
  executeCommand(ctx: Context, commandId: string): Promise<void>;
84
104
  openInUi(ctx: Context, path: string, opts?: {
85
105
  newLeaf?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"obsidian-service.d.ts","sourceRoot":"","sources":["../../../src/services/obsidian/obsidian-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"obsidian-service.d.ts","sourceRoot":"","sources":["../../../src/services/obsidian/obsidian-service.ts"],"names":[],"mappings":"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"}