search_by_frontmatter
Find notes in Obsidian vaults by searching specific frontmatter property values, optionally within designated folders.
Instructions
Search notes by frontmatter property values
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| property | Yes | Frontmatter property key to search for | |
| value | Yes | Value to match against the property | |
| folder | No | Limit search to a specific folder |
Implementation Reference
- src/tools/read.ts:232-317 (handler)The 'search_by_frontmatter' tool is registered and implemented within the 'registerReadTools' function. The handler function iterates through notes, reads their frontmatter, and compares specified property values with the target search string.
server.registerTool( "search_by_frontmatter", { description: "Search notes by frontmatter property values", inputSchema: { property: z .string() .min(1) .describe("Frontmatter property key to search for"), value: z.string().min(1).describe("Value to match against the property"), folder: z .string() .optional() .describe("Limit search to a specific folder"), }, }, async ({ property, value, folder }) => { try { const notes = await listNotes(vaultPath, folder); const matches: Array<{ path: string; frontmatter: Record<string, unknown>; }> = []; for (const notePath of notes) { let content: string; try { content = await readNote(vaultPath, notePath); } catch { console.error( `Failed to read note during frontmatter search: ${notePath}`, ); continue; } const { data: frontmatterData } = parseFrontmatter(content); const propValue = frontmatterData[property]; if (propValue === undefined) continue; const stringified = Array.isArray(propValue) ? propValue.map(String) : [String(propValue)]; const isMatch = stringified.some( (v) => v.toLowerCase() === value.toLowerCase(), ); if (isMatch) { matches.push({ path: notePath, frontmatter: frontmatterData }); } } if (matches.length === 0) { return { content: [ { type: "text" as const, text: `No notes found with frontmatter "${property}" matching "${value}"`, }, ], }; } const lines: string[] = [ `Found ${matches.length} note(s) where "${property}" matches "${value}":`, "", ]; for (const match of matches) { lines.push(`## ${match.path}`); for (const [key, val] of Object.entries(match.frontmatter)) { lines.push(` ${key}: ${JSON.stringify(val)}`); } lines.push(""); } return { content: [{ type: "text" as const, text: lines.join("\n") }], }; } catch (err) { console.error("search_by_frontmatter error:", err); return errorResult(`Error searching by frontmatter: ${err instanceof Error ? err.message : String(err)}`); } }, );