update_obsidian_note
Update an existing Obsidian note by replacing, appending, or prepending content with optional backup to preserve previous version.
Instructions
Update an existing Obsidian note
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Path to the note (relative to vault root) | |
| content | Yes | New content for the note | |
| mode | No | Update mode: replace, append, or prepend content | replace |
| createBackup | No | Whether to create a backup before updating |
Implementation Reference
- src/tools/notes.ts:201-260 (handler)Core handler method `updateNote()` that executes the update logic for an Obsidian note. It checks file existence, optionally creates a backup, reads existing content, applies the update mode (replace/append/prepend), updates frontmatter with a new modified timestamp, and writes back to disk.
async updateNote( path: string, newContent: string, mode: 'replace' | 'append' | 'prepend' = 'replace', createBackup: boolean = true ): Promise<NoteMetadata> { try { // ファイルの存在確認 if (!(await this.fileSystem.exists(path))) { throw new Error(`${ErrorCode.FILE_NOT_FOUND}: File '${path}' not found`); } // バックアップを作成 if (createBackup) { await this.fileSystem.createBackup(path); } // 既存のコンテンツを読み取り const { content: existingContent, frontmatter } = await this.readNote(path); // 更新モードに応じてコンテンツを結合 let finalContent: string; switch (mode) { case 'replace': finalContent = newContent; break; case 'append': finalContent = existingContent + '\\n\\n' + newContent; break; case 'prepend': finalContent = newContent + '\\n\\n' + existingContent; break; default: throw new Error(`${ErrorCode.TRANSLATION_FAILED}: Invalid mode '${mode}'`); } // Frontmatterを更新 const updatedFrontmatter = { ...frontmatter, modified: new Date().toISOString() }; // ファイルを更新 const noteContent = matter.stringify(finalContent, updatedFrontmatter); await this.fileSystem.writeFile(path, noteContent); return { title: frontmatter.title || path.split('/').pop()?.replace('.md', '') || 'Untitled', path, tags: frontmatter.tags || [], lastModified: new Date(), created: new Date(frontmatter.created || new Date()) }; } catch (error) { if (error instanceof Error) { throw error; } throw new Error(`${ErrorCode.PERMISSION_DENIED}: Failed to update note '${path}'`); } } - src/index.ts:230-251 (handler)MCP request handler `handleUpdateNote()` that extracts path, content, mode, and createBackup from `args` and delegates to `notesTool.updateNote()`. It validates required parameters and formats the success response.
private async handleUpdateNote(args: any) { const { path, content, mode, createBackup } = args; if (!path || !content) { throw new McpError(ErrorCode.InvalidParams, 'Path and content are required'); } const result = await this.notesTool.updateNote(path, content, mode, createBackup); return { content: [ { type: 'text', text: `✅ ノートが更新されました\\n\\n` + `📁 パス: ${result.path}\\n` + `📝 タイトル: ${result.title}\\n` + `🔄 更新モード: ${mode || 'replace'}\\n` + `⏰ 更新日時: ${result.lastModified.toISOString()}` } ] }; } - src/tools/notes.ts:74-103 (schema)Tool definition `getUpdateNoteToolDefinition()` returning the schema for 'update_obsidian_note': defines input properties (path, content, mode with enum replace/append/prepend, createBackup) with required fields path and content.
static getUpdateNoteToolDefinition(): Tool { return { name: 'update_obsidian_note', description: 'Update an existing Obsidian note', inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Path to the note (relative to vault root)' }, content: { type: 'string', description: 'New content for the note' }, mode: { type: 'string', enum: ['replace', 'append', 'prepend'], description: 'Update mode: replace, append, or prepend content', default: 'replace' }, createBackup: { type: 'boolean', description: 'Whether to create a backup before updating', default: true } }, required: ['path', 'content'] } }; - src/index.ts:89-98 (registration)Tool registration in `ListToolsRequestSchema` handler: the 'update_obsidian_note' tool is listed via `NotesTool.getUpdateNoteToolDefinition()` on line 95, making it available to clients.
this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ TranslateTool.getToolDefinition(), NotesTool.getCreateNoteToolDefinition(), NotesTool.getReadNoteToolDefinition(), NotesTool.getUpdateNoteToolDefinition(), SearchTool.getSearchToolDefinition(), SearchTool.getSearchByTagsToolDefinition(), ], - src/index.ts:117-118 (registration)Tool dispatch in `CallToolRequestSchema` handler: the switch-case on line 117 routes the name 'update_obsidian_note' to `handleUpdateNote()`.
case 'update_obsidian_note': return await this.handleUpdateNote(args);