patchNote
Modify existing notes by inserting content relative to headings, block references, or frontmatter fields using append, prepend, or replace operations.
Instructions
Inserts content into an existing note relative to a heading, block reference, or frontmatter field.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| operation | Yes | Operation to perform (append, prepend, or replace) | |
| targetType | Yes | Type of target to patch (heading, block, or frontmatter) | |
| target | Yes | Target identifier - For heading: Use a heading path string. For nested headings, use '::' as a delimiter (e.g., '## Heading 1 ### Subheading 1' must be 'Heading 1::Subheading 1'). The path should match the exact heading text. For headings with special characters, use URL encoding. - For block: Use the block ID (e.g., '2d9b4a'). - For frontmatter: Use the frontmatter field name (e.g., 'tags', 'date', 'title'). | |
| content | Yes | Content to be inserted or used for replacement | |
| targetDelimiter | No | ||
| trimTargetWhitespace | No | ||
| contentType | No |
Implementation Reference
- src/tools/patch-note.ts:45-64 (handler)Factory function createPatchNoteTool that returns the ToolHandler for executing the patchNote tool logic. It destructures params, calls ObsidianAPI.patchNote, and formats success/error responses.export function createPatchNoteTool(api: ObsidianAPI): ToolHandler { return async (params: { path: string; operation: "append" | "prepend" | "replace"; targetType: "heading" | "block" | "frontmatter"; target: string; content: string; targetDelimiter?: string; trimTargetWhitespace?: boolean; contentType?: string; }): Promise<ToolResponse> => { try { const { path, content, ...patchOptions } = params; await api.patchNote(path, content, patchOptions as PatchNoteOptions); return formatSuccessResponse({ success: true, message: "Note patched successfully" }); } catch (error) { return formatErrorResponse(`Error patching note: ${(error as Error).message}`); } }; }
- src/tools/patch-note.ts:34-38 (schema)ToolDefinition for patchNote tool, including name, description, and reference to input schema.export const patchNoteDefinition: ToolDefinition = { name: "patchNote", description: "Inserts content into an existing note relative to a heading, block reference, or frontmatter field.", schema: PatchNoteSchema };
- src/tools/patch-note.ts:7-29 (schema)Zod schema (PatchNoteSchema) defining input parameters and validation for the patchNote tool.export const PatchNoteSchema = { path: z.string().min(1, "Note path is required"), operation: z.enum(["append", "prepend", "replace"], { description: "Operation to perform (append, prepend, or replace)", }), targetType: z.enum(["heading", "block", "frontmatter"], { description: "Type of target to patch (heading, block, or frontmatter)", }), target: z .string() .min(1, "Target is required") .describe(`Target identifier - For heading: Use a heading path string. For nested headings, use '::' as a delimiter (e.g., '## Heading 1 ### Subheading 1' must be 'Heading 1::Subheading 1'). The path should match the exact heading text. For headings with special characters, use URL encoding. - For block: Use the block ID (e.g., '2d9b4a'). - For frontmatter: Use the frontmatter field name (e.g., 'tags', 'date', 'title').`), content: z .string() .min(1, "Content is required") .describe("Content to be inserted or used for replacement"), targetDelimiter: z.string().optional(), trimTargetWhitespace: z.boolean().optional(), contentType: z.string().optional(), };
- src/server.ts:71-76 (registration)Registration of the patchNote tool on the MCP server using server.tool() with definition and created handler.this.server.tool( patchNoteDefinition.name, patchNoteDefinition.description, patchNoteDefinition.schema, createPatchNoteTool(this.api) );
- src/api/obsidian-api.ts:54-95 (helper)ObsidianAPI.patchNote method implementing the core patching logic via HTTP PATCH request to the Obsidian Local REST API.async patchNote( path: string, content: string, patchOptions: PatchNoteOptions ): Promise<void> { const normalizedPath = path.startsWith("/") ? path.substring(1) : path; const processedContent = content; const { operation, targetType, target, targetDelimiter = "::", trimTargetWhitespace = false, contentType = "text/markdown", } = patchOptions; // ターゲットを日本語で指定するとエラーになるため const encodedTarget = containsNonASCII(target) ? encodeURIComponent(target) : target; try { const response = await this.client.patch( `/vault/${encodeURIComponent(normalizedPath)}`, processedContent, { headers: { ...this.defaultHeaders, Operation: operation, "Target-Type": targetType, Target: encodedTarget, "Target-Delimiter": targetDelimiter, "Trim-Target-Whitespace": trimTargetWhitespace, "Content-Type": contentType, }, } ); return response.data; } catch (error: any) { throw error; } }