io.github.caelum29/calibre-mcp
Calibre ebook library server: search, read content, curate metadata, semantic search, gated writes.
Open source Open in the app JSON README (API)
About
Calibre ebook library server: search, read content, curate metadata, semantic search, gated writes.
Details
- Kind
- MCP servers
- Topic
- AI, RAG & memory
- Publisher
- caelum29
- Origin
- official
- Category
- ferramentas
- Transport
- local
- Version
- 0.7.4
- Stars
- 12
- Forks
- 3
- Last push
- 2026-08-21T08:11:48Z
- Repository state
- ativo
- Language
- TypeScript
- License
- MIT
- Added
- 2026-08-29 03:02:33
- Updated
- 2026-08-29 03:02:33
- Origin id
io.github.caelum29/calibre-mcp
README
# 📚 calibre-mcp
[](https://www.npmjs.com/package/calibre-mcp)
[](https://www.npmjs.com/package/calibre-mcp)
[](https://registry.modelcontextprotocol.io)
[](https://github.com/caelum29/calibre-mcp/actions/workflows/ci.yml)
[](https://nodejs.org)
[](./LICENSE)
[](https://skills.sh/caelum29/calibre-mcp)
> **The most capable Calibre MCP server in existence** — connect Claude (or any MCP client)
> to your [Calibre](https://calibre-ebook.com) ebook library and search it by *meaning*, not
> just keywords.
Ask your AI assistant *“which of my books explain consumer-group rebalancing?”* and get the
exact chapter — across 800+ books or inside one. Curate metadata, dedupe, and safely edit
your library, all through natural language.
<p align="center">
<img src="https://raw.githubusercontent.com/caelum29/calibre-mcp/main/demo.gif" width="720" alt="Claude Desktop: a plain-language question becomes a semantic search across the library, results render as a 3D cover flow, a click opens the book card, search-inside returns the exact passage with its location, and the figure viewer shows the book's diagrams" />
<br/>
<em>One question → semantic search → 3D cover flow → book card → exact passage → figure viewer, all inside Claude Desktop (MCP Apps)</em>
</p>
## ✨ Highlights
- **19 tools** covering the full surface: search, read content, browse categories, curate,
and (opt-in) write — update metadata, bulk-edit, merge duplicates, import, delete, and
manage bundles (named topical filters).
- **Semantic search** — meaning-based, hybrid vector + keyword retrieval over your whole
library *or inside a single book*. Multilingual (English + Russian verified,
cross-lingual queries work). No other Calibre MCP server has this.
- **In-chat UI (MCP Apps)** — in hosts that support MCP Apps (Claude Desktop), library
searches render an interactive cover carousel, `calibre_get_book` a book detail card
with cover, rating, and read/similar actions, and `calibre_get_figures` a figure viewer
that shows you the same diagrams the assistant fetched. Text-only hosts are unaffected.
- **Curation tools** — find duplicates with merge-safety scoring, audit metadata quality,
and recover real metadata for books with raw filenames (`795731065.pdf` →
*Fundamentals of Software Engineering*) via Open Library / Google Books.
- **Safe by default** — read-only unless you explicitly enable writes; destructive
operations preview first and require confirmation; all writes route through the
Content Server so they never race the Calibre GUI.
## 📋 Requirements
- **Calibre** with the **Content Server running** (in Calibre: *Connect/share → Start
Content server*). Tested against Calibre 9.x; any recent version should work.
- **Node.js ≥ 22.5** for the npm/npx install (not needed for the Claude Desktop
one-click bundle — Desktop ships its own runtime).
- Optional, for best PDF text extraction: poppler's `pdftotext`
(`brew install poppler`) or Python 3 with PyMuPDF (`pip install pymupdf`). Without
them the server falls back to Calibre's `ebook-convert`.
## 🚀 Quick start
### Easiest — let your agent install it for you
Grab the guided-installer skill and hand the whole job to your agent:
```sh
npx skills@latest add caelum29/calibre-mcp # pick calibre-mcp-setup
```
Then tell your agent: **"set up calibre-mcp"**. The `calibre-mcp-setup` skill drives
everything below — preflight (Node, calibredb, Content Server), the Calibre-side
config, the right install for your client (macOS/Windows/Linux), and a `calibre_ping`
verification — asking you only the questions that are yours to answer (which client,
writes on/off). Works in any Agent-Skills-compatible harness (Claude Code, Copilot,
Amp, …). Prefer doing it by hand? Pick your client below.
### Claude Code
MCP server only:
```sh
claude mcp add calibre -- npx -y calibre-mcp
```
Or install the plugin — server **and** the companion skills in one step, with a settings
dialog (server URL, library, write gate) at install time:
```
/plugin marketplace add caelum29/calibre-mcp
/plugin install calibre-mcp@caelum29
```
### Claude Desktop (one-click)
Download the `.mcpb` bundle from the
[latest release](https://github.com/caelum29/calibre-mcp/releases/latest) and open it —
Claude Desktop installs it and prompts for settings (server URL, library, writes on/off).
No terminal needed.
> **About the install warning.** Claude Desktop shows *“Installing will grant this
> extension access to everything on your computer… developer information has not been
> verified by Anthropic”* for **every** extension installed from a file rather than the
> built-in directory — it’s not specific to this one. The server runs as a local Node
> process under your user account, exactly like the `npx` install below; the bundle is
> built and published by CI from this repository, so you can audit what you’re running.
> Click **Install** to proceed.
> The bundle ships without the optional embeddings dependency to stay small, so the two
> semantic-search tools report themselves unavailable. Metadata and full-text search work
> fully. For semantic search, use the npx install below instead.
### Claude Desktop (JSON config)
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"calibre": {
"command": "npx",
"args": ["-y", "calibre-mcp"]
}
}
}
```
### Cowork
Configure the server in Claude Desktop (either method above) — Desktop bridges local MCP
servers into Cowork automatically. No extra setup.
### Skills only — any agent (Claude Code, Codex, Cursor, …)
The repo's Agent Skills — a guided installer (`calibre-mcp-setup`), the calibre-mcp usage
guide, and the two distill skills — install into any Agent-Skills-compatible harness with
the [skills.sh](https://skills.sh) installer:
```sh
npx skills@latest add caelum29/calibre-mcp
```
Pick the skills and target agents interactively. Two philosophies, same as
[mattpocock/skills](https://github.com/mattpocock/skills): **skills.sh copies** the files
into your setup so you can hack on them; the **Claude Code plugin** (above) keeps them as a
managed, auto-updating bundle. Either way the skills drive this MCP server's tools, so
install the server too — or let the `calibre-mcp-setup` skill do it: it walks any agent
through preflight, per-client install (macOS/Windows/Linux), and verification.
### First contact — a five-prompt tour
The server auto-detects your default library; if the Content Server isn’t reachable it
logs an actionable hint to stderr. Then try, in order:
1. *“list my calibre libraries”* — connectivity sanity check.
2. *“find books about Rust”* — metadata search; in Claude Desktop the results render as
the cover carousel above.
3. *“show me The Rust Programming Language”* — full metadata; renders as a book card with
cover, rating, and per-format read buttons.
4. *“show me figure 2.3 from the JWT Handbook”* — the figure arrives as an image for the
assistant and, in Claude Desktop, in a figure viewer you can zoom and pan. If the
first description doesn’t match what you see, ask *“look at the image — what does it
actually show?”*: models sometimes answer figure questions from memory before reading
the pixels (the tool result nudges them to look; see Troubleshooting).
5. *“build the semantic index for my Kafka books”* — one-time prep for meaning-based search
(see below).
6. *“which of my books explain consumer-group rebalancing?”* — semantic search; answers
with ranked books, or exact passages when scoped to one book.
Bonus: *“what’s wrong with my library?”* runs the quality audit (missing metadata,
raw-filename titles, invalid ISBNs).
## ✍️ Enabling writes
Write tools (`calibre_update_book`, `calibre_bulk_update`, `calibre_add_book`,
`calibre_remove_book`, `calibre_merge_books`, `calibre_manage_bundles`) are **hidden by
default** — including `calibre_manage_bundles`' read-only `list` action, since the gate works
per tool, not per action. Two independent switches must be on:
1. **The MCP-side gate** — set `CALIBRE_MCP_ENABLE_WRITE=1` (or tick *Enable writes* in
the Desktop bundle settings). Without it the write tools aren’t even registered.
2. **The Calibre-side gate** — the Content Server must allow local writes. **By
default the server embedded in the Calibre GUI is read-only**, so either enable
the GUI option below or run a standalone server with `--enable-local-write`:
```sh
# quit the Calibre GUI first (it holds the library lock), then:
calibre-server --enable-local-write --port 8080 "/path/to/Calibre Library"
```
Or enable it on the **GUI-embedded** server without quitting the app: open
Calibre → **Preferences → Sharing over the net → Advanced** and tick
**“Allow un-authenticated local connections to make changes to the library”**
(i.e. permit local write access), then restart the Content Server from the GUI.
This is the `--enable-local-write` equivalent for the embedded server.
With only the first switch on, write tools appear but Calibre refuses the write — the
error message tells you exactly that. Reads work fine against the GUI-embedded server.
Safety behavior: `calibre_bulk_update` requires an explicit book selection (`ids` or
`query` — there is no “all books” default) and previews changes until you pass
`preview: false`. `calibre_remove_book` is a dry-run until you pass `confirm: true`;
deletion removes records *and* files, permanently. `calibre_merge_books` shows its full
merge plan until you pass `confirm: true`, and trashed sources stay recoverable from
Calibre's trash (mode `safe` keeps them entirely). `calibre_add_book` only imports files
from whitelisted folders (`CALIBRE_MCP_ADD_ROOTS`).
## 🔎 Semantic search
> Deep dive: [`docs/SEMANTIC-SEARCH.md`](./docs/SEMANTIC-SEARCH.md) — how indexing, hybrid retrieval, and reranking work.
Meaning-based search is **opt-in** and needs two things:
1. **The embeddings dependency** — `@huggingface/transformers` is an
`optionalDependencies` entry, so a normal `npx calibre-mcp` / `npm install` gets it
automatically. (Only the MCPB bundle excludes it.)
2. **An index** — ask Claude to run `calibre_build_index` for the books you care about
(by ids or a Calibre query). The first build downloads the embedding model
(`multilingual-e5-small`, ~118 MB, one-time) into the index directory; after that
everything runs offline. Indexing runs at roughly 100 chunks/sec on Apple Silicon.
> [!IMPORTANT]
> **Search results are sharpened by a cross-encoder reranker whose model is a separate
> ~576 MB one-time download.** `calibre_build_index` pre-downloads it during the build —
> the step you already expect to be slow. If you skip straight to searching on a machine
> without the cached model, your **first** hybrid/vector search triggers that download
> instead. Reranking also adds seconds of CPU per semantic search; set
> `CALIBRE_MCP_RERANK=off` to disable it (faster, noticeably less precise ranking).
Then `calibre_semantic_search` answers queries like *“which of my books explain consumer
group rebalancing?”* — across the library (`scope: library`, ranks books) or within one
book (`scope: book`, returns located passages). Retrieval is **hybrid** by default:
vector cosine + stemmed keyword FTS, fused with reciprocal rank fusion, then reranked by
the cross-encoder (top 30 candidates) when its model is available. Queries in one
language find passages in another (EN⇄RU verified).
**No embeddings? Keyword search still works.** `mode: keyword` uses no model *at query
time*, but it needs an index. If the embedding model isn’t installed (the default MCPB
bundle ships without it), build a **keyword-only** index — `calibre_build_index` with
`keywordOnly: true`, or it happens automatically when the model is absent — and search with
`mode: keyword`. That path has zero ML dependencies. `mode: vector` then errors actionably
and `mode: hybrid` degrades to keyword (with a note); rebuild with the model installed
(`force: true`) to add semantic ranking.
## 🧰 Tools
> Full reference with parameters and examples: [`docs/TOOLS.md`](./docs/TOOLS.md).
| Tool | Access | What it does |
|---|---|---|
| `calibre_search` | read | Find books by title/author/ISBN/tag or Calibre query syntax (`mode: meta`), or full text (`mode: fts`); `scope: book` searches inside one book; `filter` scopes to a bundle |
| `calibre_get_book` | read | Full metadata, formats, and cover link for one book (id or uuid); `include_cover: true` embeds the cover image in the result |
| `calibre_get_content` | read | Read a book’s text as capped excerpts; walk the whole book via cursor. `structure: true` returns a chapter map (headings, offsets, per-chapter cursors) — EN + RU/UK |
| `calibre_get_figures`\* | read | List a book’s figures/illustrations with captions and page locations; fetched ones render in an in-chat figure viewer |
| `calibre_list_categories` | read | Browse tags, authors, series, publishers, custom columns with counts |
| `calibre_list_libraries` | read | List the libraries the Content Server exposes (+ which is default) |
| `calibre_semantic_search` | read | Meaning-based search; `mode: hybrid\|vector\|keyword`, library- or book-scoped; `filter` scopes to a bundle |
| `calibre_build_index` | read* | Build/refresh the local semantic index for selected books (writes only a local index file); `keywordOnly: true` builds a model-free keyword index |
| `calibre_find_duplicates` | read | Duplicate groups with merge-safety scores; `mode: compare` diffs two books |
| `calibre_quality_report` | read | Audit: missing metadata, raw-filename titles, invalid ISBNs, author-sort issues, series gaps |
| `calibre_recover_metadata` | read | Propose real metadata via Open Library → Google Books; **preview-only**, apply with `calibre_update_book` |
| `calibre_extract_isbn` | **write** | Scan a book’s own text for a valid ISBN and set its `isbn` identifier; preview-first, apply with `apply: true` |
| `calibre_update_book` | **write** | Set metadata fields on one book (incl. `#custom` columns); returns the applied diff |
| `calibre_bulk_update` | **write** | Same change across a set of books; selection required, preview-first |
| `calibre_add_book` | **write** | Import a local ebook file (path-whitelisted) |
| `calibre_remove_book` | **write, destructive** | Permanently delete books (records + files); dry-run unless confirmed |
| `calibre_merge_books` | **write, destructive** | Merge duplicate records: move formats into a target, merge metadata per Calibre's rules, trash sources; dry-run plan unless confirmed |
| `calibre_manage_bundles` | **write** | List/create/update/delete Bundles — named topical filters backed by Calibre saved searches; `-`-named bundles auto-hide their books from discovery searches; preview-first |
| `calibre_ping` | read | Health check: is Calibre reachable end-to-end? |
\* Figures reach the assistant as real images, but models sometimes describe a figure from
memory before looking at it — if the first description doesn’t match the picture, re-ask
with *“look at the image — what does it actually show?”* (details in
[Troubleshooting](./docs/TROUBLESHOOTING.md#the-assistant-describes-a-figure-wrongly-on-the-first-try)).
In MCP Apps hosts, `calibre_search` and `calibre_semantic_search` (library scope) render
their results as a cover-board carousel, `calibre_get_book` as a book card, and
`calibre_get_figures` as a figure viewer (reading pane + margin rail, click to zoom to 100%)
so you see the diagrams the assistant is reading — covers load from your local Content
Server. Everywhere else the same tools return their usual text results; no configuration
needed either way.
## 📚 Companion skill: calibre-distill
An Agent Skill that distills a book from your library into a reusable, structured skill
(frameworks, mental models, glossary, cheatsheet) by driving the tools above — the chapter
map (`calibre_get_content structure=true`) plus in-book keyword + semantic search. Works on
EN and RU/UK books, no temp files, and can optionally stamp what you learned back into the
catalog (tags + a distill note) through the gated write tools.
It ships in this repo at [`skills/calibre-distill/`](./skills/calibre-distill). Install it
via `npx skills@latest add caelum29/calibre-mcp` or the Claude Code plugin (see
[Quick start](#-quick-start)), or manually by symlinking:
```sh
ln -s "$PWD/skills/calibre-distill" ~/.claude/skills/calibre-distill
```
Then ask, e.g., *“distill book 187 into a skill called kafka-ops”*. Note: the MCPB bundle
can’t ship skills — install the skills separately from the MCP server on Claude Desktop.
### Companion skill: calibre-distill-topic
A sibling skill that synthesizes **one topic across several books** (≥3) into a single
**concept-keyed** skill — a decision framework, per-concept sections, a cross-source config
table, an explicit *“where the sources disagree or complement”* section, and an ISBN
bibliography that doubles as a live-source binding. Use it when you want a topic study aid
built from a shelf of books rather than a single-book distill (single-book requests belong
to `calibre-distill`). Ships at [`skills/calibre-distill-topic/`](./skills/calibre-distill-topic);
installed by the same skills.sh / plugin / symlink paths as above.
Then ask, e.g., *“synthesize kafka reliability from books 187 182 571 186 into a skill.”*
Generated skills can be checked with the bundled verifier — verbatim-overlap (8-gram
shingles vs the source books), quote budget, compression floor, heading mirroring,
cursor leaks, and attribution:
```sh
pnpm build && node scripts/legal-gate.mjs <skill-dir> --book <id> [--book <id>…]
```
## ⚙️ Configuration
Everything is optional — with a running Content Server on the default port, zero config
works. Environment variables (the Desktop bundle exposes the same settings as UI fields):
| Variable | Default | Purpose |
|---|---|---|
| `CALIBRE_MCP_SERVER_URL` | `http://localhost:8080` | Calibre Content Server base URL |
| `CALIBRE_MCP_LIBRARY` | *auto-detect* | Library name; empty = the server’s default library |
| `CALIBRE_MCP_ENABLE_WRITE` | off | Master write gate (`1`/`true`/`yes`) |
| `CALIBRE_MCP_CALIBREDB_PATH` | *auto-discover* | `calibredb` binary; found via standard install paths, then `PATH` |
| `CALIBRE_MCP_INDEX_DIR` | platform data dir¹ | Semantic index + embedding-model cache |
| `CALIBRE_MCP_SEMANTIC_FLOOR` | `0.78` | Cosine score below which semantic results are flagged low-confidence |
| `CALIBRE_MCP_RERANK` | on | Cross-encoder rerank stage on semantic search (~576 MB model, seconds of CPU per query); set `off`/`false`/`0` to disable |
| `CALIBRE_MCP_MAX_BOOK_BYTES` | `268435456` (256 MB) | Largest book download `calibre_build_index` / `calibre_get_content` will extract; bigger books are skipped² |
| `CALIBRE_MCP_ADD_ROOTS` | `~/Documents`, `~/Downloads` | Folders `calibre_add_book` may import from (path-delimiter separated) |
| `CALIBRE_MCP_BOARD_STYLE` | `shelf` | Search-results widget style in MCP Apps hosts: `shelf` (scrolling cover shelf) or `coverflow` (3D cover flow; the Desktop bundle exposes this as a *Coverflow search results* toggle) |
¹ macOS `~/Library/Application Support/calibre-mcp/index`, Windows
`%APPDATA%\calibre-mcp\index`, Linux `$XDG_DATA_HOME/calibre-mcp/index`.
² Size the cap against what the **Content Server serves**, not the file on disk — it can hand
back a much heavier copy (an 8 MB PDF served as 70 MB), so a disk-sized cap silently skips books.
## 🩺 Troubleshooting
> More symptoms and fixes: [`docs/TROUBLESHOOTING.md`](./docs/TROUBLESHOOTING.md).
- **“Calibre unreachable” / connection refused** — the Content Server isn’t running.
In Calibre: *Connect/share → Start Content server*, or point
`CALIBRE_MCP_SERVER_URL` at the right host/port.
- **Write refused / “Forbidden”** — the Content Server doesn’t allow local writes.
See *Enabling writes* above: run a standalone server with
`--enable-local-write`, or tick the GUI’s *Sharing over the net → Advanced* option
and restart the Content Server.
- **Full-text search returns nothing / errors** — Calibre’s FTS index isn’t enabled for
the library. In Calibre: *Preferences → Searching → Full text search*, enable it, and
let indexing finish (it can take a while on large libraries).
- **“embedding model unavailable”** — the optional `@huggingface/transformers` package
isn’t installed (expected with the MCPB bundle). Use the npx install, or
`npm install @huggingface/transformers` next to the server. To search without it, build a
keyword-only index (`calibre_build_index keywordOnly=true`) and use `mode: keyword`.
- **`calibredb` not found** — install Calibre, or set `CALIBRE_MCP_CALIBREDB_PATH` to
the binary (macOS: `/Applications/calibre.app/Contents/MacOS/calibredb`).
- **A PDF extracts to empty text** — it’s a scanned/image PDF; Calibre has no OCR, and
neither do we.
- **Library not found (404)** — pass the library’s *display name* or *ID* as shown by
`calibre_list_libraries`; when in doubt, leave the library unset and let the server
pick its default.
## 🛠️ Development
```sh
pnpm install
pnpm build # tsc → dist/
pnpm test # vitest (unit; no network, no model download)
pnpm test:model # gated embedding-model integration tests (~118 MB download)
pnpm inspect # MCP Inspector against the built server
pnpm pack:mcpb # build the Claude Desktop .mcpb bundle
```
The codebase is Clean Architecture: tool handlers, Calibre clients, and the semantic
core are SDK-free; only `src/server.ts` touches the MCP SDK. User docs — the tool
reference and the semantic-search guide — live in [`docs/`](./docs).
Questions, ideas, and setups welcome in
[**Discussions**](https://github.com/caelum29/calibre-mcp/discussions); bug reports and PRs
in [Issues](https://github.com/caelum29/calibre-mcp/issues).
## 📄 License
[MIT](./LICENSE) © 2026 Artem Sorochynskyi
An independent project, not affiliated with Calibre.
[Calibre](https://calibre-ebook.com) itself is
[Kovid Goyal's open-source project](https://github.com/kovidgoyal/calibre) (GPLv3) —
this server drives it as a separate program via `calibredb` and the Content Server.