prepend_to_note
Add content to the start of existing notes in Obsidian vaults, maintaining frontmatter structure with customizable separators.
Instructions
Prepend content to the beginning of an existing note (after frontmatter if present)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Path to the note relative to vault root | |
| content | Yes | Content to prepend | |
| separator | No | Separator to add after prepended content. Default: '\n\n' |
Implementation Reference
- src/index.ts:496-520 (handler)The handler function that implements the prepend_to_note tool logic: reads the note, handles frontmatter, prepends content with separator, and writes back to file.async function handlePrependToNote(args: { path: string; content: string; separator?: string; }): Promise<string> { const fullPath = resolvePath(args.path); const separator = args.separator ?? "\n\n"; if (!(await fileExists(fullPath))) { throw new Error(`Note not found at ${args.path}`); } const existingContent = await fs.readFile(fullPath, "utf-8"); const { frontmatter, body, raw } = parseFrontmatter(existingContent); let newContent: string; if (frontmatter) { newContent = `---\n${raw}\n---\n${args.content}${separator}${body}`; } else { newContent = args.content + separator + existingContent; } await fs.writeFile(fullPath, newContent, "utf-8"); return `Successfully prepended content to ${args.path}`; }
- src/index.ts:110-129 (schema)Input schema defining parameters for the prepend_to_note tool.inputSchema: { type: "object", properties: { path: { type: "string", description: "Path to the note relative to vault root", }, content: { type: "string", description: "Content to prepend", }, separator: { type: "string", description: "Separator to add after prepended content. Default: '\\n\\n'", default: "\n\n", }, }, required: ["path", "content"], },
- src/index.ts:106-130 (registration)Tool definition and registration in the tools array used for ListToolsRequest.{ name: "prepend_to_note", description: "Prepend content to the beginning of an existing note (after frontmatter if present)", inputSchema: { type: "object", properties: { path: { type: "string", description: "Path to the note relative to vault root", }, content: { type: "string", description: "Content to prepend", }, separator: { type: "string", description: "Separator to add after prepended content. Default: '\\n\\n'", default: "\n\n", }, }, required: ["path", "content"], }, },
- src/index.ts:883-886 (registration)Dispatch case in the CallToolRequest handler that routes to the prepend_to_note handler.case "prepend_to_note": result = await handlePrependToNote( args as { path: string; content: string; separator?: string } );
- src/index.ts:381-419 (helper)Helper function to parse frontmatter from note content, used in prepend_to_note to preserve it.function parseFrontmatter(content: string): { frontmatter: Record<string, unknown> | null; body: string; raw: string; } { const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/); if (match) { try { // Simple YAML parsing for common cases const yaml: Record<string, unknown> = {}; const lines = match[1].split("\n"); for (const line of lines) { const colonIndex = line.indexOf(":"); if (colonIndex > 0) { const key = line.slice(0, colonIndex).trim(); let value: unknown = line.slice(colonIndex + 1).trim(); // Handle arrays if (value === "") { value = []; } else if ( typeof value === "string" && value.startsWith("[") && value.endsWith("]") ) { value = value .slice(1, -1) .split(",") .map((v) => v.trim()); } yaml[key] = value; } } return { frontmatter: yaml, body: match[2], raw: match[1] }; } catch { return { frontmatter: null, body: content, raw: "" }; } } return { frontmatter: null, body: content, raw: "" }; }