read_notebook
Extract and retrieve contents of a specific notebook by providing its unique ID, enabling efficient data access and management in Joplin MCP Server.
Instructions
Read the contents of a specific notebook
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| notebook_id | Yes | ID of the notebook to read |
Implementation Reference
- src/lib/tools/read-notebook.ts:7-84 (handler)The ReadNotebook class extending BaseTool implements the core execution logic for the read_notebook tool. The `call` method fetches notebook details, retrieves its notes, sorts them by update time, and formats a response listing all notes with instructions.class ReadNotebook extends BaseTool { async call(notebookId: string): Promise<string> { const validationError = this.validateId(notebookId, "notebook") if (validationError) { return validationError } try { // First, get the notebook details const notebook = await this.apiClient.get<JoplinFolder>(`/folders/${notebookId}`, { query: { fields: "id,title,parent_id" }, }) // Validate notebook response if (!notebook || typeof notebook !== "object" || !notebook.id) { return `Error: Unexpected response format from Joplin API when fetching notebook` } // Get all notes in this notebook const notes = await this.apiClient.get<NotebookNotesResponse>(`/folders/${notebookId}/notes`, { query: { fields: "id,title,updated_time,is_todo,todo_completed" }, }) // Validate notes response if (!notes || typeof notes !== "object") { return `Error: Unexpected response format from Joplin API when fetching notes` } if (!notes.items || !Array.isArray(notes.items) || notes.items.length === 0) { return `Notebook "${notebook.title}" (notebook_id: "${notebook.id}") is empty.\n\nTry another notebook ID or use list_notebooks to see all available notebooks.` } // Format the notebook contents const resultLines: string[] = [] resultLines.push(`# Notebook: "${notebook.title}" (notebook_id: "${notebook.id}")`) resultLines.push(`Contains ${notes.items.length} notes:\n`) resultLines.push(`NOTE: This is showing the contents of notebook "${notebook.title}", not a specific note.\n`) // If multiple notes were found, add a hint about read_multinote if (notes.items.length > 1) { const noteIds = notes.items.map((note) => note.id) resultLines.push(`TIP: To read all ${notes.items.length} notes at once, use:\n`) resultLines.push(`read_multinote note_ids=${JSON.stringify(noteIds)}\n`) } // Sort notes by updated_time (newest first) const sortedNotes = [...notes.items].sort((a, b) => b.updated_time - a.updated_time) sortedNotes.forEach((note) => { const updatedDate = this.formatDate(note.updated_time) // Add checkbox for todos if (note.is_todo) { const checkboxStatus = note.todo_completed ? "✅" : "☐" resultLines.push(`- ${checkboxStatus} Note: "${note.title}" (note_id: "${note.id}")`) } else { resultLines.push(`- Note: "${note.title}" (note_id: "${note.id}")`) } resultLines.push(` Updated: ${updatedDate}`) resultLines.push(` To read this note: read_note note_id="${note.id}"`) resultLines.push("") // Empty line between notes }) return resultLines.join("\n") } catch (error: any) { if (error.response && error.response.status === 404) { return `Notebook with ID "${notebookId}" not found.\n\nThis might happen if:\n1. The ID is incorrect\n2. You're using a note title instead of a notebook ID\n3. The notebook has been deleted\n\nUse list_notebooks to see all available notebooks with their IDs.` } return ( this.formatError(error, "reading notebook") + `\n\nMake sure you're using a valid notebook ID, not a note title.\nUse list_notebooks to see all available notebooks with their IDs.` ) } } } export default ReadNotebook
- src/index.ts:98-107 (schema)Input schema definition for the read_notebook tool in the stdio MCP server list tools response.{ name: "read_notebook", description: "Read the contents of a specific notebook", inputSchema: { type: "object", properties: { notebook_id: { type: "string", description: "ID of the notebook to read" }, }, required: ["notebook_id"], },
- src/index.ts:235-238 (registration)Tool dispatch handler in stdio MCP server that calls manager.readNotebook for read_notebook.case "read_notebook": { const notebookResult = await manager.readNotebook(args.notebook_id as string) return { content: [{ type: "text", text: notebookResult }], isError: false } }
- src/server-fastmcp.ts:68-77 (registration)Registration of read_notebook tool in FastMCP server including schema (Zod) and execute handler calling manager.readNotebook.server.addTool({ name: "read_notebook", description: "Read the contents of a specific notebook", parameters: z.object({ notebook_id: z.string().describe("ID of the notebook to read"), }), execute: async (args) => { return await manager.readNotebook(args.notebook_id) }, })
- src/server-core.ts:46-58 (helper)Instantiation of ReadNotebook tool instance in JoplinServerManager for use by manager.readNotebook method.this.tools = { listNotebooks: new ListNotebooks(this.apiClient), searchNotes: new SearchNotes(this.apiClient), readNotebook: new ReadNotebook(this.apiClient), readNote: new ReadNote(this.apiClient), readMultiNote: new ReadMultiNote(this.apiClient), createNote: new CreateNote(this.apiClient), createFolder: new CreateFolder(this.apiClient), editNote: new EditNote(this.apiClient), editFolder: new EditFolder(this.apiClient), deleteNote: new DeleteNote(this.apiClient), deleteFolder: new DeleteFolder(this.apiClient), }