diff --git a/manifest.json b/manifest.json index 0f6ae64..41a192a 100644 --- a/manifest.json +++ b/manifest.json @@ -72,11 +72,7 @@ }, { "name": "obsidian_search", - "description": "Search for notes in the vault by content. Returns matching files with optional context snippets. Supports case-sensitive search and folder filtering." - }, - { - "name": "obsidian_search_with_context", - "description": "Search for notes with surrounding context. Returns matching lines with context before and after the match for better understanding." + "description": "Search vault for text. Returns matching files and optionally match counts. Supports path filtering, result limits, case sensitivity, and multiple output formats (text/json)." }, { "name": "obsidian_get_backlinks", diff --git a/specs/001-obsidian-mcp-bundle/tasks.md b/specs/001-obsidian-mcp-bundle/tasks.md index 2624da3..7c6b8fb 100644 --- a/specs/001-obsidian-mcp-bundle/tasks.md +++ b/specs/001-obsidian-mcp-bundle/tasks.md @@ -108,8 +108,8 @@ ### Implementation for User Story 2 - [X] T046 [P] [US2] Create obsidian_search tool in src/tools/search.ts -- [X] T047 [P] [US2] Define Zod schema for search parameters (query, folder, limit, caseSensitive) -- [X] T048 [P] [US2] Create obsidian_search_with_context tool in src/tools/search.ts +- [X] T047 [P] [US2] Define Zod schema for search parameters (query, path, limit, case, total) +- [X] T048 [P] [US2] REMOVED - Search with context (not in Obsidian CLI spec) - [X] T049 [P] [US2] Create obsidian_get_backlinks tool in src/tools/links.ts - [X] T050 [P] [US2] Define Zod schema for backlinks parameters (file/path, counts) - [X] T051 [P] [US2] Create obsidian_get_outgoing_links tool in src/tools/links.ts diff --git a/src/cli/executor.ts b/src/cli/executor.ts index f54cfe8..a79b0b1 100644 --- a/src/cli/executor.ts +++ b/src/cli/executor.ts @@ -110,7 +110,7 @@ export async function executeObsidianCommand( const fullArgs = [subcommand, '--vault', vaultName, ...args]; return executeCommand({ - command: 'obsidian', + command: '/Applications/Obsidian.app/Contents/MacOS/obsidian', args: fullArgs, timeout: options?.timeout, }); diff --git a/src/tools/search.ts b/src/tools/search.ts index 4182250..408ce66 100644 --- a/src/tools/search.ts +++ b/src/tools/search.ts @@ -20,20 +20,26 @@ export async function registerSearchTools(server: ObsidianMCPServer): Promise { const validated = searchSchema.parse(args) as any; const sanitized = sanitizeParameters(validated) as any; - const cmdArgs: string[] = ['search', sanitized.query as string]; - if (sanitized.folder) cmdArgs.push('--folder', sanitized.folder as string); - if (sanitized.limit) cmdArgs.push('--limit', String(sanitized.limit)); - if (sanitized.caseSensitive) cmdArgs.push('--case-sensitive'); - if (sanitized.format) cmdArgs.push('--format', sanitized.format as string); + const cmdArgs: string[] = ['search']; + + // Add query parameter + cmdArgs.push(`query=${sanitized.query as string}`); + + // Add optional parameters + if (sanitized.path) cmdArgs.push(`path=${sanitized.path as string}`); + if (sanitized.limit) cmdArgs.push(`limit=${sanitized.limit}`); + if (sanitized.total) cmdArgs.push('total'); + if (sanitized.case) cmdArgs.push('case'); + if (sanitized.format) cmdArgs.push(`format=${sanitized.format as string}`); const result = await executeObsidianCommand('search', cmdArgs); handleCLIResult(result, { operation: 'search', query: sanitized.query }); @@ -53,37 +59,5 @@ export async function registerSearchTools(server: ObsidianMCPServer): Promise { - const validated = searchSchema.parse(args) as any; - const sanitized = sanitizeParameters(validated) as any; - - const cmdArgs: string[] = ['search', sanitized.query as string, '--context']; - if (sanitized.folder) cmdArgs.push('--folder', sanitized.folder as string); - if (sanitized.limit) cmdArgs.push('--limit', String(sanitized.limit)); - if (sanitized.contextLines) cmdArgs.push('--context-lines', String(sanitized.contextLines)); - - const result = await executeObsidianCommand('search', cmdArgs); - handleCLIResult(result, { operation: 'search_with_context', query: sanitized.query }); - - return { - content: [ - { - type: 'text', - text: formatForMCP(result.stdout, 'text'), - }, - ], - }; - } - ) - ); - - logger.info('Search tools registered', { count: 2 }); + logger.info('Search tools registered', { count: 1 }); } diff --git a/src/validation/schemas.ts b/src/validation/schemas.ts index a048008..2b11c9d 100644 --- a/src/validation/schemas.ts +++ b/src/validation/schemas.ts @@ -144,11 +144,11 @@ export const moveRenameSchema = z.intersection( // Search parameters export const searchSchema = z.object({ query: z.string().min(1, 'Search query cannot be empty'), - folder: optionalStringSchema, + path: optionalStringSchema, // Folder path to limit search limit: z.number().int().positive().max(1000).optional(), - caseSensitive: booleanFlagSchema.optional(), - contextLines: z.number().int().positive().max(10).optional(), - ...formatSchema.shape, + total: booleanFlagSchema.optional(), // Return match count instead of files + case: booleanFlagSchema.optional(), // Case sensitive search + format: z.enum(['text', 'json']).optional().default('text'), }); // Tag search parameters