FGU-bookfusion/README.md
Claude 53292df67d
Add BookFusion MCP server for Calibre / Calibre-Web-Automated
Introduces a stdio MCP server that lets Claude sync books from a Calibre
library (including the one managed by Calibre-Web-Automated) to a BookFusion
account. Reuses the same HTTP API, request shape and digest algorithms as the
official BookFusion Calibre plugin so existing accounts and metadata stay in
sync.

- bookfusion_api: async httpx client mirroring /uploads/init, /uploads/finalize,
  /uploads/{id}, /uploads?isbn=..., /limits with HTTP Basic auth.
- calibre_library: read-only reader for metadata.db plus the file/metadata
  digest helpers from the upstream plugin.
- sync: high-level flow (lookup by id/ISBN/digest -> upload or update).
- server: 8 MCP tools (library_status, list_books, get_book,
  get_bookfusion_limits, check_book_in_bookfusion, sync_book_to_bookfusion,
  sync_books_to_bookfusion, sync_all_books).
- config: env-var based settings (BOOKFUSION_API_KEY, CALIBRE_LIBRARY_PATH...).
- 14 pytest tests covering API client, settings loader and library reader.
2026-04-14 12:19:55 +00:00

4.8 KiB

BookFusion MCP

An MCP server that lets Claude (or any other MCP client) sync books from a Calibre library — including the one managed by Calibre-Web-Automated — to your BookFusion account.

It reuses the exact same HTTP API that the official BookFusion Calibre plugin talks to, so anything you already have configured on the BookFusion side (account, quota, integrations, API key) just works.

What it does

The server reads metadata directly from the Calibre metadata.db SQLite database and the on-disk book / cover files. It never writes to the database. It exposes the following MCP tools:

Tool Purpose
library_status Show the configured library path, book count and BookFusion endpoint.
list_books Paginated list of local books, optionally filtered by title/author.
get_book Full details for one book (formats, identifiers, digests).
get_bookfusion_limits Fetch upload limits (max filesize, etc.).
check_book_in_bookfusion Look up a local book on BookFusion (by id, ISBN or digest).
sync_book_to_bookfusion Upload or update a single book.
sync_books_to_bookfusion Same, in parallel for a list of book ids.
sync_all_books Sync every book matching a list_books filter.

Configuration

Copy .env.example to .env and fill it in:

cp .env.example .env
Env var Required Default Notes
BOOKFUSION_API_KEY yes — Get it from BookFusion → Settings → Integrations → Calibre.
CALIBRE_LIBRARY_PATH yes — Host path to the directory containing metadata.db. For Calibre-Web-Automated this is the host folder you mapped to /calibre-library.
BOOKFUSION_API_BASE no https://www.bookfusion.com/calibre-api/v1 Override only if you self-host or test against a staging instance.
BOOKFUSION_UPLOAD_THREADS no 2 Parallel uploads when running sync_books_to_bookfusion / sync_all_books.
BOOKFUSION_TIMEOUT no 120 Request timeout in seconds.

Never commit your API key. .env is already in .gitignore.

Install

The server requires Python 3.10+.

python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Run the test suite to make sure everything is wired up:

pytest -q

Running the server

bookfusion-mcp

This starts a stdio MCP server. Connect any MCP client to it.

Claude Desktop / Claude Code

Add the server to your client config (Claude Desktop's claude_desktop_config.json or Claude Code's ~/.claude.json):

{
  "mcpServers": {
    "bookfusion": {
      "command": "bookfusion-mcp",
      "env": {
        "BOOKFUSION_API_KEY": "your-bookfusion-api-key",
        "CALIBRE_LIBRARY_PATH": "/path/to/your/calibre-library"
      }
    }
  }
}

If you installed inside a virtualenv, point command at the venv's bookfusion-mcp binary, e.g. /home/you/FGU-bookfusion/.venv/bin/bookfusion-mcp.

Calibre-Web-Automated specifics

The server only needs read access to:

  • the metadata.db file produced by Calibre / CWA, and
  • the book / cover files inside the same library directory.

If you run CWA in Docker and want the MCP server on the same host, point CALIBRE_LIBRARY_PATH at whatever you mounted into the container at /calibre-library. Example:

docker run -d \
  -v /opt/cwa/library:/calibre-library \
  ... \
  crocodilestick/calibre-web-automated

→ on the host, set CALIBRE_LIBRARY_PATH=/opt/cwa/library.

How the sync works

For each book the server:

  1. Picks the first format the BookFusion plugin supports (EPUB, PDF, CBZ, CBR, CBT, MOBI).
  2. Computes the file digest the way the plugin does (sha256(filesize_bytes || 0x00 || file_contents)) and a metadata digest over the same fields the plugin hashes — so digests match what BookFusion already has.
  3. Looks up the book on BookFusion using the most specific identifier available, in this order: existing bookfusion identifier → isbn → file digest.
  4. If the upstream digest matches and reupload=false, skips the book.
  5. Otherwise either PUT /uploads/{id} to update an existing book, or runs the three-step init → upload to presigned URL → finalize flow for a new one.

Notes & limits

  • Uploads are one-way (Calibre → BookFusion), exactly like the official plugin.
  • metadata.db is opened read-only via file:...?mode=ro so Calibre / CWA can keep the file open at the same time.
  • The bookshelves field is wired through the API but not yet populated from Calibre custom columns; PRs welcome.

License

GPL-3.0-or-later, matching the upstream BookFusion Calibre plugin.