add_book
Add a new book to a Micro.blog bookshelf by providing title, author, and bookshelf ID, with optional ISBN and cover image URL.
Instructions
Add a new book.
Args: title: The title of the book author: The author of the book bookshelf_id: The ID of the bookshelf to add the book to isbn: The ISBN of the book (optional) cover_url: URL to the book cover image (optional)
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| author | Yes | ||
| bookshelf_id | Yes | ||
| isbn | No | ||
| cover_url | No |
Implementation Reference
- micro_mcp_server/server.py:223-245 (handler)FastMCP @mcp.tool() handler for the 'add_book' tool. Calls the client helper and returns JSON-formatted result.@mcp.tool() async def add_book( title: str, author: str, bookshelf_id: int, isbn: Optional[str] = None, cover_url: Optional[str] = None, ) -> str: """Add a new book. Args: title: The title of the book author: The author of the book bookshelf_id: The ID of the bookshelf to add the book to isbn: The ISBN of the book (optional) cover_url: URL to the book cover image (optional) """ try: result = await client.add_book(title, author, bookshelf_id, isbn, cover_url) return json.dumps(result, indent=2) except Exception: logger.exception("Failed to add book") raise
- dxt-extension/server/index.js:518-529 (handler)MCP Server CallToolRequest handler switch case for 'add_book'. Destructures arguments, calls client.addBook, and returns MCP-formatted text content.case "add_book": { const { title, author, bookshelf_id, isbn, cover_url } = args; const result = await client.addBook(title, author, bookshelf_id, isbn, cover_url); return { content: [ { type: "text", text: JSON.stringify(result, null, 2), }, ], }; }
- Explicit JSON schema definition for 'add_book' tool inputs, used in ListTools response and validation.{ name: "add_book", description: "Add a new book to a bookshelf", inputSchema: { type: "object", properties: { title: { type: "string", description: "The title of the book", minLength: 1, }, author: { type: "string", description: "The author of the book", minLength: 1, }, bookshelf_id: { type: "integer", description: "The ID of the bookshelf to add the book to", minimum: 1, }, isbn: { type: "string", description: "The ISBN of the book (optional)", }, cover_url: { type: "string", description: "URL to the book cover image (optional)", }, }, required: ["title", "author", "bookshelf_id"], }, },
- micro_mcp_server/server.py:69-96 (helper)MicroBooksClient helper method implementing HTTP POST to Micro.blog /books endpoint to add book with optional ISBN and cover.async def add_book( self, title: str, author: str, bookshelf_id: int, isbn: Optional[str] = None, cover_url: Optional[str] = None, ) -> dict: """Add a new book.""" data = { "title": title, "author": author, "bookshelf_id": str(bookshelf_id), } if isbn: data["isbn"] = isbn if cover_url: data["cover_url"] = cover_url async with httpx.AsyncClient() as client: response = await client.post( urljoin(BASE_URL, "/books"), headers=self.headers, data=data, ) response.raise_for_status() return {"success": True, "message": f"Book '{title}' by {author} added successfully"}
- dxt-extension/server/index.js:96-126 (helper)MicroBooksClient.addBook helper with input validation, constructs POST data, calls makeRequest to Micro.blog API.async addBook(title, author, bookshelfId, isbn = null, coverUrl = null) { if (!title || typeof title !== 'string' || title.trim().length === 0) { throw new Error("Book title is required and must be a non-empty string"); } if (!author || typeof author !== 'string' || author.trim().length === 0) { throw new Error("Book author is required and must be a non-empty string"); } if (!Number.isInteger(bookshelfId) || bookshelfId <= 0) { throw new Error("Bookshelf ID must be a positive integer"); } const data = { title: title.trim(), author: author.trim(), bookshelf_id: bookshelfId.toString(), }; if (isbn && typeof isbn === 'string' && isbn.trim().length > 0) { data.isbn = isbn.trim(); } if (coverUrl && typeof coverUrl === 'string' && coverUrl.trim().length > 0) { data.cover_url = coverUrl.trim(); } await this.makeRequest("/books", { method: "POST", body: new URLSearchParams(data), }); return { success: true, message: `Book '${title.trim()}' by ${author.trim()} added successfully` }; }