create_note
Generate and organize notes in Joplin by adding titles, markdown or HTML content, todos, and images, while optionally nesting them within specific notebooks.
Instructions
Create a new note in Joplin
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | Note content in Markdown | |
| body_html | No | Note content in HTML | |
| image_data_url | No | Base64 encoded image data URL | |
| is_todo | No | Whether this is a todo note | |
| parent_id | No | ID of parent notebook | |
| title | No | Note title |
Implementation Reference
- src/lib/tools/create-note.ts:14-103 (handler)Core implementation of the create_note tool: CreateNote class extending BaseTool with the async call(options) method that handles note creation via Joplin API, validation, error handling, and formatted response.class CreateNote extends BaseTool { async call(options: CreateNoteOptions): Promise<string> { if (!options || typeof options !== "object") { return 'Please provide note creation options. Example: create_note {"title": "My Note", "body": "Note content"}' } // Validate that we have at least a title or body if (!options.title && !options.body && !options.body_html) { return "Please provide at least a title, body, or body_html for the note." } // Validate parent_id if provided if (options.parent_id && (options.parent_id.length < 10 || !options.parent_id.match(/[a-f0-9]/i))) { return `Error: "${options.parent_id}" does not appear to be a valid notebook ID.\n\nNotebook IDs are long alphanumeric strings like "58a0a29f68bc4141b49c99f5d367638a".\n\nUse list_notebooks to see available notebooks and their IDs.` } try { // Prepare the request body const requestBody: CreateNoteOptions = {} if (options.title) requestBody.title = options.title if (options.body) requestBody.body = options.body if (options.body_html) requestBody.body_html = options.body_html if (options.parent_id) requestBody.parent_id = options.parent_id if (options.is_todo !== undefined) requestBody.is_todo = options.is_todo if (options.image_data_url) requestBody.image_data_url = options.image_data_url // Create the note const createdNote = await this.apiClient.post<CreateNoteResponse>("/notes", requestBody) // Validate response if (!createdNote || typeof createdNote !== "object" || !createdNote.id) { return "Error: Unexpected response format from Joplin API when creating note" } // Get notebook info if available let notebookInfo = "Root level" if (createdNote.parent_id) { try { const notebook = await this.apiClient.get(`/folders/${createdNote.parent_id}`, { query: { fields: "id,title" }, }) if (notebook && notebook.title) { notebookInfo = `"${notebook.title}" (notebook_id: "${createdNote.parent_id}")` } } catch { // Continue even if we can't get notebook info notebookInfo = `Notebook ID: ${createdNote.parent_id}` } } // Format success response const resultLines: string[] = [] resultLines.push(`✅ Successfully created note!`) resultLines.push("") resultLines.push(`📝 Note Details:`) resultLines.push(` Title: "${createdNote.title || "Untitled"}"`) resultLines.push(` Note ID: ${createdNote.id}`) resultLines.push(` Location: ${notebookInfo}`) if (createdNote.is_todo) { resultLines.push(` Type: Todo item`) } const createdDate = this.formatDate(createdNote.created_time) resultLines.push(` Created: ${createdDate}`) resultLines.push("") resultLines.push(`🔗 Next steps:`) resultLines.push(` - Read the note: read_note note_id="${createdNote.id}"`) if (createdNote.parent_id) { resultLines.push(` - View notebook: read_notebook notebook_id="${createdNote.parent_id}"`) } resultLines.push(` - Search for it: search_notes query="${createdNote.title}"`) return resultLines.join("\n") } catch (error: any) { if (error.response) { // Handle specific API errors if (error.response.status === 400) { return `Error creating note: Invalid request data.\n\nPlease check your input parameters. ${error.response.data?.error || ""}` } if (error.response.status === 404 && options.parent_id) { return `Error: Notebook with ID "${options.parent_id}" not found.\n\nUse list_notebooks to see available notebooks and their IDs.` } } return this.formatError(error, "creating note") } } }
- src/lib/tools/create-note.ts:3-10 (schema)TypeScript interface defining the input parameters for the create_note tool.interface CreateNoteOptions { title?: string | undefined body?: string | undefined body_html?: string | undefined parent_id?: string | undefined is_todo?: boolean | undefined image_data_url?: string | undefined }
- src/server-fastmcp.ts:104-118 (registration)Registration of create_note tool in FastMCP server, including Zod input schema and execution delegating to JoplinServerManager.createNote.server.addTool({ name: "create_note", description: "Create a new note in Joplin", parameters: z.object({ title: z.string().optional().describe("Note title"), body: z.string().optional().describe("Note content in Markdown"), body_html: z.string().optional().describe("Note content in HTML"), parent_id: z.string().optional().describe("ID of parent notebook"), is_todo: z.boolean().optional().describe("Whether this is a todo note"), image_data_url: z.string().optional().describe("Base64 encoded image data URL"), }), execute: async (args) => { return await manager.createNote(args) }, })
- src/index.ts:132-145 (registration)Tool schema registration for create_note in the stdio MCP server's ListTools response.name: "create_note", description: "Create a new note in Joplin", inputSchema: { type: "object", properties: { title: { type: "string", description: "Note title" }, body: { type: "string", description: "Note content in Markdown" }, body_html: { type: "string", description: "Note content in HTML" }, parent_id: { type: "string", description: "ID of parent notebook" }, is_todo: { type: "boolean", description: "Whether this is a todo note" }, image_data_url: { type: "string", description: "Base64 encoded image data URL" }, }, }, },
- src/server-core.ts:86-95 (helper)JoplinServerManager wrapper method for createNote that delegates to the instantiated CreateNote tool instance.async createNote(params: { title?: string | undefined body?: string | undefined body_html?: string | undefined parent_id?: string | undefined is_todo?: boolean | undefined image_data_url?: string | undefined }): Promise<string> { return await this.tools.createNote.call(params) }