Find a file
Frederic Guariento c9c104f04e fix(build): remove redundant wheel force-include (hatchling duplicate-path error)
packages=["src/bookfusion_mcp"] already bundles web/*.user.js. Recent hatchling
rejects the duplicate add from force-include (ValueError: second file at same
path) - non-deterministic build surfacing only on a host with newer hatchling.
Web asset still shipped via packages (verified in image).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 18:04:20 +02:00
deploy fix(api): force dict for form data, drop Authorization on presigned upload 2026-04-25 13:43:46 +02:00
src/bookfusion_mcp feat: plan-aware storage budget + 422 dedup + transient retries 2026-04-28 08:45:09 +02:00
tests Add HTTP companion, CWA button userscript and Docker deploy 2026-04-14 12:43:21 +00:00
.dockerignore Add HTTP companion, CWA button userscript and Docker deploy 2026-04-14 12:43:21 +00:00
.env.example Add BookFusion MCP server for Calibre / Calibre-Web-Automated 2026-04-14 12:19:55 +00:00
.gitignore Add BookFusion MCP server for Calibre / Calibre-Web-Automated 2026-04-14 12:19:55 +00:00
.pre-commit-config.yaml chore: ggshield pre-commit hook to refuse hardcoded secrets 2026-04-25 20:40:20 +02:00
LICENSE chore: add GPL-3.0 LICENSE (matches pyproject license declaration) 2026-04-25 15:01:07 +02:00
pyproject.toml fix(build): remove redundant wheel force-include (hatchling duplicate-path error) 2026-07-10 18:04:20 +02:00
README.md Add HTTP companion, CWA button userscript and Docker deploy 2026-04-14 12:43:21 +00:00

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.

Running as a Docker service next to Calibre-Web-Automated

A ready-to-use Docker setup lives in deploy/. It runs the same Python package as an HTTP companion (bookfusion-http) that:

  • exposes a small REST API (/api/books, /api/books/{id}/sync, …) with CORS,
  • serves a Tampermonkey userscript at /bookfusion-sync.user.js that adds a Sync to BookFusion button on every CWA book detail page.

See deploy/README.md for the full step-by-step, but in short:

cd /Volumes/docker/calibre-web-automated
git clone --branch claude/add-bookfusion-mcp-ocUTD \
    https://github.com/Fguarien/FGU-bookfusion.git bookfusion-mcp
cd bookfusion-mcp/deploy
cp .env.example .env      # set BOOKFUSION_API_KEY + CALIBRE_LIBRARY_HOST_PATH
docker compose up -d --build
open http://localhost:8765/     # click "Install userscript" in Tampermonkey

Then open any book in CWA — the button is injected by the userscript, so CWA itself is never modified.

Download as a ZIP

If you don't want to git clone, GitHub serves a ready-to-use tarball / ZIP of the branch:

License

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