Skip to main content
Glama
monch1962
by monch1962

Calibre MCP

CI Python MCP Calibre Licence: MIT

Ein schreibgeschützter Model Context Protocol-Server für eine bestehende Calibre-E-Book-Bibliothek.

Calibre MCP ermöglicht MCP-kompatiblen Clients, Buchmetadaten zu durchsuchen, den Volltextindex von Calibre abzufragen, Buchdetails einzusehen, Bibliothekskategorien zu durchstöbern und verwandte Bücher zu entdecken. Es verwendet die von Calibre unterstützte Befehlszeilenschnittstelle calibredb, anstatt metadata.db direkt zu lesen.

Features

  • Metadatensuche mit der Suchsprache von Calibre

  • Volltextsuche mit passenden Textausschnitten

  • Detaillierte Metadaten für einzelne Bücher

  • Zuletzt hinzugefügte Bücher

  • Autoren, Schlagwörter, Serien, Verlage und Sprachkategorien

  • Entdeckung verwandter Bücher

  • MCP-Ressourcen für Bücher, Suchen und Bibliotheksstatus

  • Optionale Links zum Calibre Content Server

  • In-Memory-TTL-Cache

  • Streamable-HTTP-Transport

  • Podman-Quadlet-Bereitstellung

  • Keine MCP-Tools, die Metadaten verändern

Related MCP server: calibre-manager

Verfügbare Tools

Tool

Zweck

server_info

Server-, Calibre-, Cache- und Bibliothekskonfiguration anzeigen

library_status

Buchanzahl und Status der Volltextindizierung anzeigen

search_books

Calibre-Metadaten durchsuchen

search_fulltext

In indizierten E-Books suchen und Textausschnitte zurückgeben

get_book_metadata

Alle verfügbaren Metadaten für ein Buch zurückgeben

list_recent_books

Zuletzt hinzugefügte Bücher auflisten

list_categories

Autoren, Schlagwörter, Serien, Verlage und Sprachen durchstöbern

find_related_books

Bücher mit übereinstimmenden Autoren, Serien oder Schlagwörtern finden

clear_cache

Den In-Memory-Lesecache leeren

MCP-Ressourcen

URI

Zweck

calibre://library/status

Status der Bibliothek und des Volltextindex

calibre://book/{book_id}

Detaillierte Metadaten für ein Buch

calibre://search/{query}

Ergebnisse der Metadatensuche

Voraussetzungen

  • Eine Calibre-Bibliothek mit metadata.db

  • Calibre 9.x

  • Python 3.11 oder neuer

  • Ein MCP-Client, der Streamable HTTP unterstützt

  • Podman und systemd für die enthaltene Quadlet-Bereitstellung

Die Volltext-Tools setzen voraus, dass der Volltextindex von Calibre aktiviert und vollständig aufgebaut ist.

Schnellstart mit Podman Quadlet

1. Repository klonen

git clone https://github.com/monch1962/calibre-mcp.git
cd calibre-mcp

2. Ihre Calibre-Bibliothek bestätigen

Das mitgelieferte Quadlet geht von Folgendem aus:

/tank/media/Books

Bestätigen Sie, dass die Bibliotheksdatenbank vorhanden ist:

test -f /tank/media/Books/metadata.db && echo "Calibre library found"

3. Den Besitzer der Bibliothek ermitteln

stat -c 'uid=%u gid=%g owner=%U:%G' /tank/media/Books

Bearbeiten Sie quadlet/calibre-mcp.container und setzen Sie User= auf die zurückgegebene numerische UID und GID:

User=1000:1000

Ändern Sie außerdem den Host-Bibliothekspfad, falls Ihrer abweicht:

Volume=/tank/media/Books:/books

4. Image erstellen

sudo podman build \
  --build-arg CALIBRE_VERSION=9.11.0 \
  -t localhost/calibre-mcp:1.0.0 .

5. Quadlet installieren

sudo mkdir -p /etc/containers/systemd

sudo cp quadlet/calibre-mcp.container \
  /etc/containers/systemd/calibre-mcp.container

sudo systemctl daemon-reload
sudo systemctl start calibre-mcp.service

Führen Sie systemctl enable calibre-mcp.service nicht aus. Der erzeugte Dienst ist transient; der Abschnitt [Install] des Quadlets erstellt die Boot-Abhängigkeit.

6. Bereitstellung überprüfen

sudo systemctl status calibre-mcp.service --no-pager
sudo journalctl -u calibre-mcp.service -n 100 --no-pager
sudo podman ps --filter name=calibre-mcp

Überprüfen Sie Calibre im Container:

sudo podman exec calibre-mcp \
  calibredb list \
  --with-library /books \
  --for-machine \
  --fields title \
  --limit 1

sudo podman exec calibre-mcp \
  calibredb fts_index status \
  --with-library /books

Der Standard-Endpunkt ist:

http://localhost:8008/mcp

Mit MCP Inspector testen

npx @modelcontextprotocol/inspector

Wählen Sie Streamable HTTP und verbinden Sie sich mit:

http://YOUR_SERVER:8008/mcp

Beispiel für eine Metadatensuche:

{
  "query": "author:asimov",
  "limit": 10
}

Beispiel für eine Volltextsuche:

{
  "query": "zero trust architecture",
  "limit": 10
}

Beispiel für eine eingeschränkte Volltextsuche:

{
  "query": "encryption",
  "limit": 10,
  "restrict_to": "search:tags:security"
}

Einen MCP-Client verbinden

Verwenden Sie den vom Server bereitgestellten Streamable-HTTP-Endpunkt:

http://YOUR_SERVER:8008/mcp

Die Konfigurationsformate der Clients variieren. Konsultieren Sie die MCP-Dokumentation Ihres Clients und wählen Sie Streamable HTTP statt stdio oder Legacy-SSE.

Beispiele für Calibre-Suchen

search_books akzeptiert Calibre-Suchausdrücke:

author:asimov
title:"i robot"
tags:history
series:"Discworld"
publisher:penguin
languages:eng
rating:>=4

Eine leere Abfrage gibt alle Bücher zurück, vorbehaltlich des Ergebnislimits.

Setzen Sie die URL Ihres vorhandenen Calibre Content Servers im Quadlet:

Environment=CALIBRE_CONTENT_SERVER_URL=http://mini-nas:8083

Wenn konfiguriert, enthalten die Metadaten-Ergebnisse Links zum Anzeigen im Browser und zum Herunterladen von Formaten.

Konfiguration

Umgebungsvariable

Standard

Beschreibung

CALIBRE_LIBRARY_PATH

/books

Calibre-Bibliothek im Container

CALIBREDB

calibredb

Pfad zur Calibre-CLI

CALIBRE_COMMAND_TIMEOUT

120

Befehls-Timeout in Sekunden

CALIBRE_MAX_RESULTS

100

Maximale Anzahl von Ergebnissen, die ein Tool zurückgibt

CALIBRE_CACHE_TTL

300

Cache-Lebensdauer in Sekunden; auf 0 setzen, um zu deaktivieren

CALIBRE_CACHE_SIZE

256

Maximale Anzahl zwischengespeicherter Einträge

CALIBRE_MAX_CONCURRENT_COMMANDS

4

Maximale Anzahl gleichzeitiger calibredb-Unterprozesse

CALIBRE_CONTENT_SERVER_URL

unset

Optionale Basis-URL des Content Servers

MCP_HOST

0.0.0.0

MCP-HTTP-Bindeadresse

MCP_PORT

8000

MCP-Port im Container

HOME

/tmp/calibre-home

Beschreibbarer Speicherort für die Calibre-Konfiguration

Warum der Bibliotheks-Mount beschreibbar ist

Calibre prüft, ob das Dateisystem der Bibliothek case-sensitiv ist, indem es kurzzeitig eine Testdatei im Stammverzeichnis der Bibliothek erstellt und wieder löscht. Folglich kann der Bind-Mount nicht schreibgeschützt eingehängt werden.

Dieser Server bleibt funktional schreibgeschützt, da er keine Tools bereitstellt, die Calibre-Befehle wie die folgenden aufrufen:

  • add

  • remove

  • set_metadata

  • add_format

  • remove_format

Führen Sie den Container mit derselben unprivilegierten UID und GID aus, der die Bibliothek gehört. Führen Sie ihn nicht als root aus, es sei denn, Ihre Umgebung erfordert dies ausdrücklich.

Sicherheit

  • Halten Sie Port 8008 auf vertrauenswürdige LAN- oder Tailscale-Clients beschränkt.

  • Setzen Sie den Endpunkt nicht direkt dem öffentlichen Internet aus.

  • Streamable HTTP fügt in dieser Bereitstellung keine Authentifizierung hinzu.

  • Platzieren Sie vor einer breiteren Freigabe einen authentifizierenden Reverse-Proxy vor dem Dienst.

  • Pinnen Sie Release-Versionen, anstatt ein sich änderndes Container-Tag zu verwenden.

  • Lesen Sie SECURITY.md, bevor Sie eine Sicherheitslücke melden.

Red-Team-Härtung (Runde 1)

Zehn adversariale Angriffsvektoren wurden mit fehlschlagenden Tests nachgewiesen und anschließend behoben. Jeder TestAttack_*-Test in tests/attack_round1_test.py ist eine dauerhafte Regressions-Fixture für seinen Vektor.

#

Angriffsvektor

Einstiegspunkt

Verteidigung

1

Unbegrenzter Cache-Schlüssel — eine mehrere Megabyte große Abfrage wird pro Cache-Eintrag im Speicher behalten

search_books / search_fulltext

Schlüssel über 512 Bytes werden per SHA-256 gehasht (_cache_key)

2

Unbegrenzter Cache-Wert — große calibredb-Ausgaben (Kommentare, Textausschnitte) werden pro Eintrag behalten

_run

Werte über 1 MiB umgehen den Cache (_cache_put)

3

Hängender server_info-Unterprozess — calibredb --version lief ohne Timeout

server_info

Timeout angewendet; TimeoutExpiredToolError

4

Unbehandelter JSONDecodeError bei ungültiger calibredb-Ausgabe → roher interner Fehler

_list_books / search_fulltext

_loads_json-Wrapper → ToolError

5

Unbehandelter ValueError bei einem nicht-numerischen Buch-ID-Schlüssel → roher interner Fehler

_normalise_books

Gekapselt → ToolError

6

Suchsyntax-Injektion über Bibliotheksmetadaten — Anführungszeichen/Backslashes in Autoren, Serien oder Schlagwörtern brechen aus der generierten Abfrage aus

find_related_books

_exact_match_clause entfernt " und \ aus Klauselwerten

7

Unbegrenzte Abfragelänge — Abfragen im MB-Bereich erreichen calibredb und den Cache

search_books / search_fulltext

Abfragen über 8192 Zeichen werden mit ToolError abgelehnt

8

Unbegrenzte Erfassung der transienten calibredb-Standardausgabe bei gleichzeitigen Fluten

_run

Restrisiko — durch CALIBRE_COMMAND_TIMEOUT begrenzt; dokumentiert

9

Nicht authentifizierter Endpunkt auf 0.0.0.0

Bereitstellung

Akzeptierte Haltung — dokumentiert in SECURITY.md

10

Informationsoffenlegung — Bibliothekspfad, Calibre-Version

server_info / library_status

Für einen schreibgeschützten Wissensserver akzeptiert; dokumentiert

In dieser Runde verifizierte, bekanntermaßen sichere Oberflächen: Shell-Injektion (argv-Liste, kein shell=True), Optionswert-Injektion (--sort-by/--categories/--restrict-to lehnen Werte mit führendem Bindestrich im Parser von Calibre ab), Pfad-Traversal bei Ressourcen-URIs (nicht-numerische IDs abgelehnt), Ergebnislimit-Begrenzung (_limit) und Cache-Race-Conditions (durch Sperren geschützt).

Red-Team-Härtung (Runde 2)

Sechs Validierungsvektoren für die Eingabeform wurden nachgewiesen und behoben; Fixtures in tests/attack_round2_test.py.

#

Angriffsvektor

Einstiegspunkt

Abwehr

11

Unbegrenzte book_id-Größe — intern erstellte id:{huge}-Abfrage umgeht das Abfragelimit aus Runde 1 und erreicht calibredb als argv-Eintrag im MB-Bereich

get_book_metadata / book_resource / find_related_books

_validate_book_id begrenzt IDs auf 1..2³¹−1 (_book)

12

Unbegrenzter categories-String → argv im MB-Bereich

list_categories

1024-Zeichen-Limit → ToolError

13

Unbegrenzter restrict_to-String → argv im MB-Bereich

search_fulltext

2048-Zeichen-Limit → ToolError

14

Unbegrenzter sort_by-String → argv im MB-Bereich

search_books

128-Zeichen-Limit → ToolError

15

Nicht iterierbare formats-Metadaten → TypeError → roher 500

_content_links

Nicht-Listen-/Tupel-Formate ignoriert; details-Link wird weiterhin zurückgegeben

16

Format-Erweiterungs-Injektion in generierten Download-Links (.., x;rm -rf)

_content_links

Erweiterungs-Whitelist [a-z0-9]{1,10} — nicht übereinstimmende Formate übersprungen

Red-Team-Härtung (Runde 3)

Drei Fehlerpfad-Robustheitsvektoren wurden nachgewiesen und behoben; Fixtures in tests/attack_round3_test.py.

#

Angriffsvektor

Einstiegspunkt

Abwehr

17

Übergroßes CSV-Feld (über dem 128-KiB-Limit für CSV-Feldgröße) → roher csv.Error → 500

list_categories

Iteration gekapselt → ToolError

18

calibredb-Listenausgabe als Array von Nicht-Dict-Elementen → AttributeError in search_books → 500

_normalise_books

Nicht-Dict-Array-Elemente abgelehnt → ToolError

19

fts_search-Dict-Payload mit einem unerwarteten listenwertigen Schlüssel wird ohne Limit durchgereicht → Antwortverstärkung

search_fulltext

Jeder listenwertige Schlüssel wird auf das Ergebnislimit gekürzt

Red-Team-Härtung (Runde 4)

Zwei Nebenläufigkeits-/Prozessflut-Vektoren wurden nachgewiesen und behoben; Fixtures in tests/attack_round4_test.py.

#

Angriffsvektor

Einstiegspunkt

Abwehr

20

Nebenläufige calibredb-Prozessflut — N parallele Tool-Aufrufe erzeugen N Unterprozesse (CPU-/Speichererschöpfung, Calibre-DB-Zugriffskonflikt)

_run

threading.Semaphore begrenzt laufende Befehle auf CALIBRE_MAX_CONCURRENT_COMMANDS (Standard: 4); überbuchte Aufrufe → ToolError

21

server_info-Versions-Unterprozessflut — ein ungecachter Unterprozess pro Aufruf

server_info

Versionsaufruf über denselben Semaphor geleitet (_run_version)

Red-Team-Härtung (Runde 5 — abschließende Verifikation)

Keine neuen Schwachstellen. Ein Audit der Abdeckungslücken fügte 11 Verifikationstests (tests/attack_round5_test.py) hinzu, die jeden noch nicht von den Runden 1–4 abgedeckten Einstiegspunkt testen — search_resource, book_resource (nicht-numerisch, traversal-artig, im gültigen Bereich), status_resource, library_status, list_recent_books, clear_cache, search_fulltext-Listen-Payloads, Null-/Negativ-Limits, Cache-Deaktivierung bei TTL null und Leerzeichen-Abfragen. Alle bestanden sofort und bestätigen, dass die Abwehrmaßnahmen der Runden 1–4 auf der gesamten Tool-/Ressourcenoberfläche Bestand haben.

Zwei Dokumentationsbefunde zur Bereitstellungshaltung wurden in SECURITY.md festgehalten (keine Codeänderung): die Containerfile hat keine USER-Direktive (läuft als root, wenn sie außerhalb des Quadlet erstellt wird, das User=1000:1000 setzt), und das Quadlet setzt SecurityLabelDisable=true (SELinux-Label-Trennung ist deaktiviert).

Lokale Entwicklung

Virtuelle Umgebung erstellen:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e .
python -m pip install pytest ruff

Tests ausführen:

pytest

Lint-Prüfungen ausführen:

ruff check .

Server lokal starten:

export CALIBRE_LIBRARY_PATH="/path/to/Calibre Library"
python server.py

Projektstatus

Version 1.0.0 eignet sich für persönliche Bereitstellungen und Bereitstellungen in vertrauenswürdigen Netzwerken. Die öffentliche API kann in zukünftigen Minor-Releases zusätzliche Tools und Ressourcen erhalten, während bestehende Tool-Namen und Argumentformen nach Möglichkeit stabil gehalten werden.

Mitwirken

Issues und Pull-Requests sind willkommen. Siehe CONTRIBUTING.md.

Lizenz

Veröffentlicht unter der MIT-Lizenz.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that enables querying and managing Calibre libraries via chat by interacting with the Calibre content server over HTTP. It allows users to search for books, update metadata, manage authors and tags, and handle book file uploads or conversions.
    3
    BSD 3-Clause
  • A
    license
    A
    quality
    D
    maintenance
    An MCP server to manage and organize a Calibre ebook library, enabling metadata editing, search, conversion, and more through AI assistants.
    17
    5
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A local stdio MCP server that enables AI tools to search a self-hosted Calibre library over SSH, supporting metadata queries, full-text search, and book details.
    7
    MIT