Calibre Librarian MCP Server
# Calibre Librarian MCP Server
[](https://github.com/chepetime/calibre-librarian-mcp/actions/workflows/mcp.yml)
Model Context Protocol (MCP) server that surfaces your Calibre catalog to Claude via xmcp.
<!-- markdownlint-disable MD033 -->
<p align="center">
<img src="assets/mcp-calibre.png" alt="Claude MCP view of Calibre Librarian" width="420" />
</p>
<!-- markdownlint-enable MD033 -->
## Requirements
- **Node.js**: `v24.13.0` (auto-managed if you use `nvm use`).
- **pnpm**: version `10.28.0` or newer.
- **Calibre CLI tools**: `calibredb` and `ebook-convert` must be installable on your PATH.
- **Environment variables**:
- `CALIBRE_LIBRARY_PATH` – absolute path to your Calibre library directory.
- `CALIBRE_DB_COMMAND` – location of the `calibredb` executable (e.g., `/opt/homebrew/bin/calibredb`).
- `FAVORITE_SEARCH_ENGINE_URL` – base URL used when the server offers external book lookups (defaults to DuckDuckGo: `https://duckduckgo.com/?q=`).
## Setup
1. Clone and enter the repo:
```bash
git clone https://github.com/chepetime/calibre-librarian-mcp.git
cd calibre-librarian-mcp
```
2. Install dependencies with pnpm:
```bash
pnpm install
```
3. Copy the sample environment file and fill in your paths:
```bash
cp .env.example .env
```
Update the variables so the server can reach your Calibre library.
> The env is just for local development. For Claude Desktop, you'll need to configure the server in the Claude Desktop settings.
### Local development workflow
Use these scripts while iterating locally:
- `pnpm run dev` – watches files and serves the MCP server over stdio.
- `pnpm run lint` – type-checks and lints the project.
- `pnpm test` – runs the full unit test suite once.
- `pnpm test:watch` – reruns tests whenever source files change.
### Build for Claude Desktop (no Docker)
Follow this flow when you want Claude Desktop (or any MCP client) to run the compiled server directly:
1. Build the project so `dist/stdio.js` exists:
```bash
pnpm run build
```
2. (Optional) Run the built output locally for a quick smoke test:
```bash
pnpm start # equivalent to: node dist/stdio.js
```
3. Configure Claude Desktop by editing `~/Library/Application Support/Claude/claude_desktop_config.json` (or via the in-app UI). Set `command` to `node`, include the absolute path to `dist/stdio.js` as the first `args` entry, and provide the required environment variables:
```json
{
"globalShortcut": "",
"mcpServers": {
"calibre-librarian": {
"command": "node",
"args": ["/Users/you/path/to/calibre-librarian-mcp/dist/stdio.js"],
"env": {
"CALIBRE_LIBRARY_PATH": "<Absolute path to your>/Calibre",
"CALIBRE_DB_COMMAND": "/opt/homebrew/bin/calibredb",
"FAVORITE_SEARCH_ENGINE_URL": "https://duckduckgo.com/?q="
}
}
},
"preferences": {
"quickEntryShortcut": "off",
"menuBarEnabled": false
}
}
```
After Claude Desktop reloads, it will list **calibre-librarian** as an available MCP server whenever MCP-enabled conversations start.
### Docker deployment
Run the server in a container with Calibre pre-installed when you prefer an isolated environment.
#### Quick start
```bash
# Build the image
docker build -t calibre-librarian-mcp .
# Run with your Calibre library mounted
docker run -it \
-v /path/to/your/calibre/library:/library:ro \
-e CALIBRE_LIBRARY_PATH=/library \
calibre-librarian-mcp
```
#### Docker Compose
1. Copy and customize `docker-compose.yml`.
2. Set your library path and launch the stack:
```bash
export CALIBRE_LIBRARY_PATH=/path/to/your/calibre/library
docker compose up --build
```
#### Claude Desktop with Docker
To let Claude Desktop run the container directly, point it at `docker run`:
```json
{
"mcpServers": {
"calibre-librarian": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-v",
"/path/to/your/calibre/library:/library:ro",
"-e",
"CALIBRE_LIBRARY_PATH=/library",
"calibre-librarian-mcp"
]
}
}
}
```
**Note:** Remove `:ro` from the volume mount and add `-e CALIBRE_ENABLE_WRITE_OPERATIONS=true` to enable write operations.
## Tool Catalog & Examples
### Installing the MCP CLI
The examples below use the `mcp` CLI published by Anthropic. Install (or run) it with any of the following options:
- Global install (recommended if you call MCP tools frequently):
```bash
npm install -g @anthropic-ai/mcp-cli
# now `mcp --help` should work
```
- One-off execution without a global install:
```bash
npx @anthropic-ai/mcp-cli --help
# or
pnpm dlx @anthropic-ai/mcp-cli --help
```
### CLI usage
All tools can be invoked from MCP Inspector or the CLI:
```bash
mcp call calibre-librarian <toolName> '<json payload>'
```
Prompts (e.g., `merge_duplicates`, `library_cleanup`, `search_library`) use the companion command:
```bash
mcp prompt calibre-librarian library_cleanup '{"focus":"missing covers"}'
```
Swap `library_cleanup` for any prompt listed below, and replace `calibre-librarian` with the server name you configured in `mcp.json`.
### Library Overview & Metadata
| Tool | Example |
| -------------------- | --------------------------------------------------------------------------- |
| `list_sample_books` | `mcp call calibre-librarian list_sample_books '{"limit":5}'` |
| `get_book_details` | `mcp call calibre-librarian get_book_details '{"bookId":42}'` |
| `get_library_stats` | `mcp call calibre-librarian get_library_stats '{}'` |
| `get_all_tags` | `mcp call calibre-librarian get_all_tags '{"sortBy":"count","minCount":5}'` |
| `get_custom_columns` | `mcp call calibre-librarian get_custom_columns '{"includeDisplay":true}'` |
### Search & Discovery
| Tool | Example |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `search_books` | `mcp call calibre-librarian search_books '{"query":"author:Sanderson and tag:fantasy","limit":10}'` |
| `search_books_by_title` | `mcp call calibre-librarian search_books_by_title '{"title":"stormlight","exact":false}'` |
| `search_authors_by_name` | `mcp call calibre-librarian search_authors_by_name '{"name":"ng","sortBy":"count"}'` |
| `get_books_by_author` | `mcp call calibre-librarian get_books_by_author '{"author":"Robin Hobb","sortBy":"series","ascending":true}'` |
| `get_books_by_author_id` | `mcp call calibre-librarian get_books_by_author_id '{"authorId":17}'` |
| `get_books_by_series` | `mcp call calibre-librarian get_books_by_series '{"series":"The Expanse","exact":true}'` |
| `get_books_by_tag` | `mcp call calibre-librarian get_books_by_tag '{"tag":"cozy mystery","limit":25}'` |
| `search_books_by_tag_pattern` | `mcp call calibre-librarian search_books_by_tag_pattern '{"pattern":"*punk","limit":10}'` |
### Full-Text & Content Access
| Tool | Example |
| --------------------- | ----------------------------------------------------------------------------------------------------- |
| `full_text_search` | `mcp call calibre-librarian full_text_search '{"query":"\"winter is coming\"","matchAll":false}'` |
| `search_book_content` | `mcp call calibre-librarian search_book_content '{"bookId":12,"query":"quantum","contextChars":120}'` |
| `fetch_excerpt` | `mcp call calibre-librarian fetch_excerpt '{"bookId":8,"maxChars":1500}'` |
### Cleanup & Duplicate Workbench
| Tool | Example |
| ------------------------- | -------------------------------------------------------------------------------------------------------- |
| `find_duplicates` | `mcp call calibre-librarian find_duplicates '{"mode":"author_title","threshold":0.85}'` |
| `compare_books` | `mcp call calibre-librarian compare_books '{"bookIds":[101,205],"fields":["title","series","formats"]}'` |
| `quality_report` | `mcp call calibre-librarian quality_report '{"checks":["missing_cover","missing_tags"],"limit":20}'` |
| `merge_duplicates` prompt | `mcp prompt calibre-librarian merge_duplicates '{"bookIds":[101,205]}'` |
| `library_cleanup` prompt | `mcp prompt calibre-librarian library_cleanup '{"focus":"missing covers"}'` |
| `search_library` prompt | `mcp prompt calibre-librarian search_library '{"query":"hopepunk","searchType":"tag"}'` |
### Smart Maintenance Recipes
| Tool | Example |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `normalize_author_sort` | `mcp call calibre-librarian normalize_author_sort '{"preview":true,"limit":25}'` |
| `bulk_retag` | `mcp call calibre-librarian bulk_retag '{"query":"author:Sanderson","action":"add","tags":"cosmere","preview":true}'` |
| `library_maintenance` | `mcp call calibre-librarian library_maintenance '{"operation":"check"}'` |
| `missing_book_scout` | `mcp call calibre-librarian missing_book_scout '{"readingList":"Dune\n1984\nThe Hobbit","searchEngine":"annas_archive"}'` |
### Metadata Editing & Custom Columns
> Requires `CALIBRE_ENABLE_WRITE_OPERATIONS=true`
| Tool | Example |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `set_custom_column` | `mcp call calibre-librarian set_custom_column '{"bookId":42,"column":"#reading_status","value":"Started"}'` |
| `set_metadata` | `mcp call calibre-librarian set_metadata '{"bookId":42,"title":"The Final Empire (Revised)","tags":["cosmere","favorite"]}'` |
### Setup & Configuration Tools
| Tool | Example |
| ------------------------ | ---------------------------------------------------------------------------- |
| `generate_claude_config` | `mcp call calibre-librarian generate_claude_config '{"enableWrites":false}'` |
## Environment Variables
| Variable | Required | Default | Description |
| --------------------------------- | -------- | ---------------------------- | ---------------------------------------------------- |
| `CALIBRE_LIBRARY_PATH` | Yes | — | Absolute path to your Calibre library directory |
| `CALIBRE_DB_COMMAND` | No | `calibredb` | Path to the `calibredb` executable |
| `CALIBRE_COMMAND_TIMEOUT_MS` | No | `15000` | Timeout for calibredb commands in milliseconds |
| `CALIBRE_ENABLE_WRITE_OPERATIONS` | No | `false` | Enable metadata editing tools (`set_metadata`, etc.) |
| `FAVORITE_SEARCH_ENGINE_URL` | No | `https://duckduckgo.com/?q=` | Base URL for external book search links |
| `MCP_SERVER_NAME` | No | `Calibre Librarian MCP` | Server name shown in MCP clients |
## Resources
The server exposes these MCP resources:
| URI | Description |
| ---------------------------------- | ------------------------------------ |
| `calibre://library/info` | Library configuration and statistics |
| `calibre://library/custom-columns` | Custom column definitions |
| `calibre://docs/inspector-guide` | MCP Inspector verification guide |
## Troubleshooting
### "calibredb: command not found"
The server can't find the Calibre CLI tools. Solutions:
- **macOS (Homebrew)**: `brew install calibre` or set `CALIBRE_DB_COMMAND=/Applications/calibre.app/Contents/MacOS/calibredb`
- **macOS (App)**: `CALIBRE_DB_COMMAND=/Applications/calibre.app/Contents/MacOS/calibredb`
- **Windows**: `CALIBRE_DB_COMMAND=C:\Program Files\Calibre2\calibredb.exe`
- **Linux**: Install Calibre via package manager, usually adds `calibredb` to PATH
### "Library path does not exist"
Verify your `CALIBRE_LIBRARY_PATH`:
```bash
# Check the path contains metadata.db
ls "$CALIBRE_LIBRARY_PATH/metadata.db"
```
### "Write operations are disabled"
Write tools (`set_metadata`, `set_custom_column`, `bulk_retag` with `preview:false`, etc.) require:
```bash
CALIBRE_ENABLE_WRITE_OPERATIONS=true
```
Add this to your `.env` file or Claude Desktop config.
### "Command timed out"
For large libraries, increase the timeout:
```bash
CALIBRE_COMMAND_TIMEOUT_MS=60000 # 60 seconds
```
### "Full-text search returns no results"
Calibre FTS must be enabled:
1. Open Calibre
2. Go to **Preferences → Searching**
3. Enable **Full text searching**
4. Click **Re-index all books**
### Server not appearing in Claude Desktop
1. Verify the config file path:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`
2. Check JSON syntax is valid
3. Restart Claude Desktop completely
4. Check Claude Desktop logs for errors
### Testing with MCP Inspector
Use the built-in verification guide:
```bash
# Start dev server
npm run dev
# In another terminal, run inspector
npx @anthropic/mcp-inspector
```
Or use the `generate_claude_config` tool to get your configuration.
## License
MIT
TDQS
Scored across 26 tools
Most tools have distinct purposes, but there is some overlap between several search variants (search_books, search_books_by_title, search_books_by_tag_pattern) and between get_books_by_author and get_books_by_author_id. Descriptions help differentiate, but an agent might occasionally misselect when looking for a simple book lookup.
All tools use a consistent snake_case verb_noun pattern (e.g., bulk_retag, compare_books, fetch_excerpt). The naming is predictable and makes the action-object relationship clear across the entire set.
With 26 tools, the server is on the heavy side. While the scope of a Calibre library manager can justify many operations, some tools feel redundant (e.g., multiple search variants), and the count exceeds the typical well-scoped range of 3-15.
The tool surface covers most core library operations: search, retrieval, updates, duplicates, quality reports, and maintenance. Minor gaps include lack of direct CRUD for series or publishers, but these can be managed via metadata updates.