write_note
Save or update notes in your personal knowledge management system by specifying a path and content, and optionally adding tags for better organization.
Instructions
Create a new note or overwrite an existing note with content. Path should be relative to your notes directory. Optionally include tags that will be merged with any existing tags in the note.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | Content to write to the note | |
| path | Yes | Path where the note should be saved, relative to notes directory | |
| tags | No | Tags must follow these rules: - Can contain letters, numbers, underscore (_), hyphen (-), and forward slash (/) - Must contain at least one non-numerical character - Cannot contain spaces (use camelCase, PascalCase, snake_case, or kebab-case) - Are case-insensitive (stored as lowercase) Tags to add to the note's frontmatter. Will be merged with existing tags if present. |
Input Schema (JSON Schema)
{
"properties": {
"content": {
"description": "Content to write to the note",
"type": "string"
},
"path": {
"description": "Path where the note should be saved, relative to notes directory",
"type": "string"
},
"tags": {
"description": "Tags must follow these rules:\n- Can contain letters, numbers, underscore (_), hyphen (-), and forward slash (/)\n- Must contain at least one non-numerical character\n- Cannot contain spaces (use camelCase, PascalCase, snake_case, or kebab-case)\n- Are case-insensitive (stored as lowercase)\n \n Tags to add to the note's frontmatter. Will be merged with existing tags if present.",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"path",
"content"
],
"type": "object"
}
Implementation Reference
- src/tools/index.ts:363-451 (handler)Main handler logic for the 'write_note' tool. Validates input, creates and saves a Note object with content and tags, and optionally appends a link to the daily log.case "write_note": { try { const writeNoteArgs = args as WriteNoteArgs; // Validate parameters if (!writeNoteArgs.path) { throw new Error("'path' parameter is required"); } if (writeNoteArgs.content === undefined) { throw new Error("'content' parameter is required"); } try { // Create a Note instance with content only const note = new Note(notesPath, writeNoteArgs.path, { content: writeNoteArgs.content }); // Add tags separately to handle validation errors if (writeNoteArgs.tags && writeNoteArgs.tags.length > 0) { note.addTags(writeNoteArgs.tags); } // Save the note const result = await note.save(); if (!result.success) { return { content: [{ type: "text", text: `Error writing note: ${result.error}` }], isError: true }; } // After successfully saving the note, append an entry to the daily log try { // Create a LogNote instance for today const logNote = new LogNote(notesPath); // Load existing content if available await logNote.load(); // Format the note path for wikilink // Remove file extension if present and get the base name const notePath = writeNoteArgs.path; const noteBaseName = path.basename(notePath, path.extname(notePath)); // Create wikilink using Obsidian convention const wikilink = `[[${noteBaseName}]]`; // Create log entry with the wikilink const logEntry = `Created note: ${wikilink}`; // Append the entry to the log await logNote.appendEntry(logEntry); return { content: [{ type: "text", text: `Successfully wrote note to: ${writeNoteArgs.path} and updated daily log with link` }] }; } catch (logError) { const errorMessage = logError instanceof Error ? logError.message : String(logError); console.error("Error updating log with note link:", logError); // Still return success for the note creation even if log update fails return { content: [{ type: "text", text: `Successfully wrote note to: ${writeNoteArgs.path} (but failed to update daily log: ${errorMessage})` }] }; } } catch (tagError) { const errorMessage = tagError instanceof Error ? tagError.message : String(tagError); return { content: [{ type: "text", text: `Error writing note: ${errorMessage}` }], isError: true }; } } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [{ type: "text", text: `Error writing note: ${errorMessage}` }], isError: true }; } }
- src/tools/index.ts:67-71 (schema)TypeScript interface defining the expected input arguments for the write_note tool.interface WriteNoteArgs { path: string; content: string; tags?: string[]; }
- src/tools/index.ts:177-203 (registration)Tool registration in getToolDefinitions(), including name, description, and JSON input schema.{ name: "write_note", description: "Create a new note or overwrite an existing note with content. " + "Path should be relative to your notes directory. " + "Optionally include tags that will be merged with any existing tags in the note.", inputSchema: { type: "object", properties: { path: { type: "string", description: "Path where the note should be saved, relative to notes directory" }, content: { type: "string", description: "Content to write to the note" }, tags: { type: "array", items: { type: "string" }, description: `${TAG_VALIDATION_DESCRIPTION} Tags to add to the note's frontmatter. Will be merged with existing tags if present.` } }, required: ["path", "content"] }, },
- src/notes/Note.ts:150-174 (helper)The Note.save() method called by the handler, which generates frontmatter (with created date and tags), ensures the directory exists, and writes the file.async save(): Promise<SaveResult> { try { // Ensure directory exists await this._ensureDirectoryExists(); // Create content with frontmatter const frontmatter = this._createFrontmatter(); const finalContent = frontmatter + this.content; // Write to file await fs.writeFile(this.fullPath, finalContent, 'utf8'); return { success: true, path: this.relativePath, content: finalContent }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { success: false, error: errorMessage }; } }