search_content
Find notes containing specific text in your Obsidian vault using content-based search with customizable parameters.
Instructions
Search for notes containing specific text in their content
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Text to search for in note contents | |
| caseSensitive | No | Whether search is case-sensitive. Default: false | |
| limit | No | Maximum number of results to return. Default: 20 |
Implementation Reference
- src/index.ts:571-604 (handler)The handler function that implements the core logic for the 'search_content' tool. It searches all notes in the Obsidian vault for the given query string, finds matching lines, and returns up to the specified limit of results as JSON.async function handleSearchContent(args: { query: string; caseSensitive?: boolean; limit?: number; }): Promise<string> { const limit = args.limit ?? 20; const caseSensitive = args.caseSensitive ?? false; const allNotes = await getAllNotes(); const results: { path: string; matches: string[] }[] = []; const regex = new RegExp( args.query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), caseSensitive ? "g" : "gi" ); for (const notePath of allNotes) { if (results.length >= limit) break; const fullPath = path.join(VAULT_PATH, notePath); const content = await fs.readFile(fullPath, "utf-8"); if (regex.test(content)) { // Find matching lines const lines = content.split("\n"); const matchingLines = lines .filter((line) => regex.test(line)) .slice(0, 3); results.push({ path: notePath, matches: matchingLines }); } } return JSON.stringify(results, null, 2); }
- src/index.ts:183-206 (schema)The tool definition including name, description, and input schema (JSON Schema) for validating parameters of the 'search_content' tool.{ name: "search_content", description: "Search for notes containing specific text in their content", inputSchema: { type: "object", properties: { query: { type: "string", description: "Text to search for in note contents", }, caseSensitive: { type: "boolean", description: "Whether search is case-sensitive. Default: false", default: false, }, limit: { type: "number", description: "Maximum number of results to return. Default: 20", default: 20, }, }, required: ["query"], }, },
- src/index.ts:901-905 (registration)Registration in the main tool call request handler switch statement, dispatching calls to the 'search_content' handler function.case "search_content": result = await handleSearchContent( args as { query: string; caseSensitive?: boolean; limit?: number } ); break;
- src/index.ts:853-855 (registration)The tools array (including 'search_content') is registered for the ListToolsRequestHandler, making the tool discoverable.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools, }));
- src/index.ts:365-379 (helper)Helper function 'getAllNotes' recursively lists all .md note paths in the vault, used by the search_content handler to iterate over notes.async function getAllNotes(dir: string = VAULT_PATH): Promise<string[]> { const notes: string[] = []; const entries = await fs.readdir(dir, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(dir, entry.name); if (entry.isDirectory() && !entry.name.startsWith(".")) { notes.push(...(await getAllNotes(fullPath))); } else if (entry.isFile() && entry.name.endsWith(".md")) { notes.push(path.relative(VAULT_PATH, fullPath)); } } return notes; }