Skip to main content
Glama
monch1962
by monch1962

Calibre MCP

CI Python MCP Calibre Licence: MIT

Сервер Model Context Protocol только для чтения для существующей библиотеки электронных книг Calibre.

Calibre MCP позволяет MCP-совместимым клиентам искать метаданные книг, запрашивать полнотекстовый индекс Calibre, просматривать сведения о книгах, обозревать категории библиотеки и находить связанные книги. Он использует поддерживаемый интерфейс командной строки calibredb вместо прямого чтения metadata.db.

Возможности

  • Поиск по метаданным с использованием языка поиска Calibre

  • Полнотекстовый поиск с соответствующими фрагментами

  • Подробные метаданные для отдельных книг

  • Недавно добавленные книги

  • Авторы, теги, серии, издатели и языковые категории

  • Обнаружение связанных книг

  • Ресурсы MCP для книг, поисковых запросов и статуса библиотеки

  • Необязательные ссылки на Calibre Content Server

  • Кэш TTL в памяти

  • Транспорт Streamable HTTP

  • Развёртывание Podman Quadlet

  • Нет инструментов MCP, изменяющих метаданные

Related MCP server: calibre-manager

Доступные инструменты

Инструмент

Назначение

server_info

Показать конфигурацию сервера, Calibre, кэша и библиотеки

library_status

Показать количество книг и статус полнотекстового индексирования

search_books

Поиск по метаданным Calibre

search_fulltext

Поиск внутри индексированных электронных книг и возврат фрагментов

get_book_metadata

Возврат всех доступных метаданных для одной книги

list_recent_books

Список недавно добавленных книг

list_categories

Просмотр авторов, тегов, серий, издателей и языков

find_related_books

Поиск книг с пересекающимися авторами, сериями или тегами

clear_cache

Очистка кэша чтения в памяти

Ресурсы MCP

URI

Назначение

calibre://library/status

Статус библиотеки и полнотекстового индекса

calibre://book/{book_id}

Подробные метаданные книги

calibre://search/{query}

Результаты поиска по метаданным

Требования

  • Библиотека Calibre с metadata.db

  • Calibre 9.x

  • Python 3.11 или новее

  • MCP-клиент, поддерживающий Streamable HTTP

  • Podman и systemd для включённого развёртывания Quadlet

Инструменты полнотекстового поиска требуют, чтобы полнотекстовый индекс Calibre был включён и построен.

Быстрый старт с Podman Quadlet

1. Клонируйте репозиторий

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

2. Проверьте вашу библиотеку Calibre

Поставляемый Quadlet предполагает:

/tank/media/Books

Убедитесь, что база данных библиотеки существует:

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

3. Определите владельца библиотеки

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

Отредактируйте quadlet/calibre-mcp.container и установите User= в возвращённые числовые UID и GID:

User=1000:1000

Также измените путь к библиотеке на хосте, если он у вас другой:

Volume=/tank/media/Books:/books

4. Соберите образ

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

5. Установите Quadlet

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

Не запускайте systemctl enable calibre-mcp.service. Сгенерированный сервис является временным; раздел [Install] в Quadlet создаёт зависимость при загрузке.

6. Проверьте развёртывание

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

Проверьте Calibre внутри контейнера:

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

Конечная точка по умолчанию:

http://localhost:8008/mcp

Тестирование с MCP Inspector

npx @modelcontextprotocol/inspector

Выберите Streamable HTTP и подключитесь к:

http://YOUR_SERVER:8008/mcp

Пример поиска по метаданным:

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

Пример полнотекстового поиска:

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

Пример ограниченного полнотекстового поиска:

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

Подключение MCP-клиента

Используйте конечную точку Streamable HTTP, предоставляемую сервером:

http://YOUR_SERVER:8008/mcp

Форматы конфигурации клиентов различаются. Обратитесь к документации MCP вашего клиента и выберите Streamable HTTP, а не stdio или устаревший SSE.

Примеры поиска Calibre

search_books принимает выражения поиска Calibre:

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

Пустой запрос возвращает все книги с учётом ограничения на количество результатов.

Необязательные ссылки Content Server

Укажите URL вашего существующего Calibre Content Server в Quadlet:

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

При настройке результаты метаданных включают ссылки для просмотра и загрузки форматов.

Конфигурация

Переменная окружения

По умолчанию

Описание

CALIBRE_LIBRARY_PATH

/books

Библиотека Calibre внутри контейнера

CALIBREDB

calibredb

Путь к CLI Calibre

CALIBRE_COMMAND_TIMEOUT

120

Тайм-аут команды в секундах

CALIBRE_MAX_RESULTS

100

Максимальное количество результатов, возвращаемых инструментом

CALIBRE_CACHE_TTL

300

Время жизни кэша в секундах; установите 0 для отключения

CALIBRE_CACHE_SIZE

256

Максимальное количество записей в кэше

CALIBRE_MAX_CONCURRENT_COMMANDS

4

Максимальное количество одновременных подпроцессов calibredb

CALIBRE_CONTENT_SERVER_URL

unset

Необязательный базовый URL Content Server

MCP_HOST

0.0.0.0

Адрес привязки MCP HTTP

MCP_PORT

8000

Порт MCP внутри контейнера

HOME

/tmp/calibre-home

Место для записи конфигурации Calibre

Почему точка монтирования библиотеки доступна для записи

Calibre проверяет, чувствительна ли файловая система библиотеки к регистру символов, кратковременно создавая и удаляя пробный файл в корне библиотеки. Следовательно, bind-монтирование не может быть смонтировано в режиме только для чтения.

Этот сервер остаётся функционально доступным только для чтения, поскольку он не предоставляет инструментов, вызывающих такие команды Calibre, как:

  • add

  • remove

  • set_metadata

  • add_format

  • remove_format

Запускайте контейнер от того же непривилегированного UID и GID, которым принадлежит библиотека. Не запускайте его от root, если ваше окружение специально этого не требует.

Безопасность

  • Держите порт 8008 ограниченным для доверенных клиентов LAN или Tailscale.

  • Не открывайте конечную точку напрямую в публичный Интернет.

  • Streamable HTTP не добавляет аутентификацию в этом развёртывании.

  • Поместите аутентифицирующий обратный прокси перед сервисом перед более широким доступом.

  • Закрепляйте версии релизов, а не используйте плавающий тег контейнера.

  • Изучите SECURITY.md перед сообщением об уязвимости.

Усиление red-team (раунд 1)

Десять векторов атак со стороны злоумышленника были подтверждены падающими тестами, а затем исправлены. Каждый тест TestAttack_* в tests/attack_round1_test.py является постоянным регрессионным тестом для своего вектора.

#

Вектор атаки

Точка входа

Защита

1

Неограниченный ключ кэша — много мегабайт запроса сохраняется в памяти для каждой записи кэша

search_books / search_fulltext

Ключи длиннее 512 байт хешируются SHA-256 (_cache_key)

2

Неограниченное значение кэша — большой вывод calibredb (комментарии, фрагменты) сохраняется для каждой записи

_run

Значения более 1 МиБ обходят кэш (_cache_put)

3

Зависание подпроцесса server_infocalibredb --version выполнялся без тайм-аута

server_info

Применён тайм-аут; TimeoutExpiredToolError

4

Необработанная JSONDecodeError при недопустимом выводе calibredb → сырая внутренняя ошибка

_list_books / search_fulltext

Обёртка _loads_jsonToolError

5

Необработанная ValueError для нечислового ключа book-id → сырая внутренняя ошибка

_normalise_books

Обёрнуто → ToolError

6

Инъекция синтаксиса поиска через метаданные библиотеки — кавычки/обратные слеши в авторах, сериях или тегах выходят за пределы сгенерированного запроса

find_related_books

_exact_match_clause удаляет " и \ из значений условий

7

Неограниченная длина запроса — запросы масштаба МБ достигают calibredb и кэша

search_books / search_fulltext

Запросы длиннее 8192 символов отклоняются с ToolError

8

Неограниченный временный захват stdout calibredb при одновременных всплесках нагрузки

_run

Остаточный риск — ограничен CALIBRE_COMMAND_TIMEOUT; задокументировано

9

Неаутентифицированная конечная точка на 0.0.0.0

deployment

Принятая позиция — задокументировано в SECURITY.md

10

Раскрытие информации — путь к библиотеке, версия Calibre

server_info / library_status

Принято для сервера знаний только для чтения; задокументировано

Известные безопасные поверхности, проверенные в этом раунде: инъекция команд оболочки (список argv, без shell=True), инъекция значений параметров (--sort-by/--categories/--restrict-to отклоняют значения с ведущим дефисом в парсере Calibre), обход пути в URI ресурсов (нечисловые идентификаторы отклоняются), ограничение количества результатов (_limit) и состояния гонки в кэше (защищены блокировкой).

Усиление red-team (раунд 2)

Шесть векторов проверки формы входных данных подтверждены и исправлены; фикстуры в tests/attack_round2_test.py.

#

Вектор атаки

Точка входа

Защита

11

Неограниченное значение book_id — внутренне построенный запрос id:{huge} обходит ограничение запросов раунда 1 и попадает в calibredb как аргумент argv мегабайтного размера

get_book_metadata / book_resource / find_related_books

_validate_book_id ограничивает id диапазоном 1..2³¹−1 (_book)

12

Неограниченная строка categories → аргумент argv мегабайтного размера

list_categories

Ограничение 1024 символа → ToolError

13

Неограниченная строка restrict_to → аргумент argv мегабайтного размера

search_fulltext

Ограничение 2048 символов → ToolError

14

Неограниченная строка sort_by → аргумент argv мегабайтного размера

search_books

Ограничение 128 символов → ToolError

15

Неитерируемые метаданные formatsTypeError → необработанная ошибка 500

_content_links

Форматы, не являющиеся списком/кортежем, игнорируются; ссылка details по-прежнему возвращается

16

Инъекция расширения формата в генерируемые ссылки для скачивания (.., x;rm -rf)

_content_links

Белый список расширений [a-z0-9]{1,10} — несоответствующие форматы пропускаются

Усиление защиты от Red-team (раунд 3)

Три вектора надёжности обработки ошибок подтверждены и исправлены; фикстуры в tests/attack_round3_test.py.

#

Вектор атаки

Точка входа

Защита

17

Поле CSV слишком большого размера (превышает лимит размера поля csv в 128 KiB) → необработанная csv.Error → 500

list_categories

Итерация обёрнута → ToolError

18

Вывод списка calibredb в виде массива элементов, не являющихся словарями, → AttributeError в search_books → 500

_normalise_books

Элементы массива, не являющиеся словарями, отклоняются → ToolError

19

Полезная нагрузка fts_search в виде dict с неожиданным ключом, значение которого — список, проходит без ограничения → усиление ответа

search_fulltext

Каждый ключ со значением-списком обрезается до лимита результатов

Усиление защиты от Red-team (раунд 4)

Два вектора, связанных с параллелизмом и флудом процессов, подтверждены и исправлены; фикстуры в tests/attack_round4_test.py.

#

Вектор атаки

Точка входа

Защита

20

Флуд процессами calibredb при параллелизме — N параллельных вызовов инструментов порождают N подпроцессов (истощение CPU/памяти, конкуренция за БД Calibre)

_run

threading.Semaphore ограничивает выполняемые команды значением CALIBRE_MAX_CONCURRENT_COMMANDS (по умолчанию 4); вызовы сверх лимита → ToolError

21

Флуд подпроцессами версии server_info — по одному некэшируемому подпроцессу на вызов

server_info

Вызов версии направляется через тот же семафор (_run_version)

Усиление защиты от Red-team (раунд 5 — финальная проверка)

Ноль новых уязвимостей. Аудит пробелов в покрытии добавил 11 проверочных тестов (tests/attack_round5_test.py), охватывающих каждую точку входа, ещё не покрытую раундами 1–4: search_resource, book_resource (нечисловые, похожие на обход каталога, в допустимом диапазоне), status_resource, library_status, list_recent_books, clear_cache, search_fulltext с полезными нагрузками в виде списков, нулевые/отрицательные лимиты, отключение кэша при TTL=0 и запросы из пробелов. Все тесты прошли сразу, подтвердив, что защиты раундов 1–4 действуют на всей поверхности инструментов/ресурсов.

Два замечания к документации о развёртывании зафиксированы в SECURITY.md (без изменения кода): в Containerfile отсутствует директива USER (при сборке вне Quadlet контейнер запускается от root, тогда как Quadlet задаёт User=1000:1000), а Quadlet устанавливает SecurityLabelDisable=true (разделение меток SELinux отключено).

Локальная разработка

Создайте виртуальное окружение:

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

Запустите тесты:

pytest

Запустите lint-проверки:

ruff check .

Запустите сервер локально:

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

Статус проекта

Версия 1.0.0 подходит для личного использования и развёртывания в доверенных сетях. Публичный API может пополняться дополнительными инструментами и ресурсами в будущих минорных релизах, при этом существующие имена инструментов и формы аргументов будут сохраняться стабильными, где это практически возможно.

Участие в разработке

Приветствуются issues и pull request'ы. См. CONTRIBUTING.md.

Лицензия

Распространяется под лицензией MIT.

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