Skip to main content
Glama
shelfmark-mcp

shelfmark-mcp

Official

shelfmark-mcp

An MCP server for Shelfmark, the self-hosted book and audiobook downloader. It lets an AI assistant do what a person does in Shelfmark's web UI: search for a book, look at the releases its sources offer, pick one, queue the download and follow it until it lands in the library. It can also work through Shelfmark's request queue, which its Hardcover "Want to Read" sync fills.

It speaks MCP over streamable HTTP behind a bearer token, talks to Shelfmark's REST API, and keeps nothing on disk. Built against Shelfmark 1.6.1; 1.5.x has the same API.

Tools

The usual flow is search_books → list_releases → download_release → download_status.

Finding a book

Tool

shelfmark_status

Health, version, the enabled release sources and metadata provider, default content type and languages, accepted formats, the release search budget, and whether the request tools work.

search_books

Search the metadata provider (Hardcover, Open Library, ...) by free text or by author, title or series. Each book has a book_id, year, series position, whether the library already holds it, and the provider's ratings and reader counts.

get_book

One book's full metadata: description, ISBNs, publisher, series, provider link.

list_releases

Ask the enabled release sources for copies of a book: source, indexer, format, size, language, protocol, seeders and peers, download counts. Filters by format; expand broadens the search.

Downloading

Tool

download_release

Queue a release; returns a download_id.

download_status

The queue now, each download's state and progress; or one download, also found in history.

download_history

Completed, failed and cancelled downloads, newest first, including ones cleared from the activity list.

cancel_download

Stop a queued or running download.

retry_download

Queue a failed or cancelled download again.

Requests (Shelfmark with user accounts only)

Tool

list_requests

Books people asked for, with who asked, the content type and a book_id to list releases for.

fulfil_request

Approve one with a chosen release, the requester's own pick, or as already in the library.

reject_request

Decline one, with a note.

Annotations are honest: the reads are readOnlyHint; download_release, retry_download and fulfil_request start downloads from the internet (openWorldHint); cancel_download and reject_request are destructiveHint, so a client can ask before them.

Related MCP server: Readbook MCP Server

Running it

Requirements: a reachable Shelfmark, and Python 3.12+ with the dependencies in pyproject.toml, or Nix:

nix run .                # from a checkout; or: nix build

Variable

MCP_BEARER_TOKEN

Required, 16+ characters, no whitespace: the token clients present as Authorization: Bearer …. The server refuses to start without it.

SHELFMARK_URL

Required: Shelfmark's address, e.g. http://shelfmark:8084, with its base path if it has one (https://example.org/shelfmark).

SHELFMARK_API_KEY

Optional: Shelfmark's SHELFMARK_API_KEY, sent as X-Api-Key. Needed when Shelfmark has user accounts (any AUTH_METHOD but none); with it, this server acts as Shelfmark's first admin.

MCP_LISTEN

Optional, default 0.0.0.0:8080.

MCP is served at /mcp. GET /healthz needs no token and returns no library data: ok (200) only when Shelfmark's /api/health answers ok, otherwise 503 with a reason (unavailable: shelfmark_unavailable, …_coordinator_stopped, …_http_<status>).

Logs go to stderr, one line per tool call with its name, outcome, duration and how many connection attempts had to be repeated. They never carry a token, a key or an upstream body.

Behind an MCP gateway

The server is stateless (every POST to /mcp is one JSON exchange), so a gateway can open a session per call. For LiteLLM:

mcp_servers:
  shelfmark:
    url: http://shelfmark-mcp:8080/mcp
    transport: http
    auth_type: bearer_token
    auth_value: <MCP_BEARER_TOKEN>
    description: Search, download and follow books in Shelfmark

list_releases can take as long as Shelfmark's release search budget (its RELEASE_SEARCH_TIMEOUT, 300 s by default, shown by shelfmark_status): give the gateway's and the client's tool-call timeouts at least that much, or lower the budget in Shelfmark.

How it behaves

  • Text from outside is untrusted. Titles, authors, descriptions, release names, notes and status messages come back under an untrusted key, and the server's instructions tell the model to read them, never follow them.

  • Opaque ids. book_id is Shelfmark's own provider:id. Shelfmark's download task ids can be a kilobyte long (a torrent source's id embeds its magnet link), so download_id is a short digest the server resolves against Shelfmark's queue and history. A release_id names a release from the last listing: queueing one takes the whole release as Shelfmark listed it, so listings are kept in memory for 12 hours; after that, or a restart, the id is stale_id and the releases have to be listed again.

  • Downloads are queued the way the web UI queues them: title, authors, year, cover and series from the book's metadata, everything else from the release as listed.

  • Connections are retried, requests are not. A new connection to a port published from a rootless container's network namespace sometimes stalls on the SYN and fails only after ~10 s. Each request connects with escalating timeouts (0.4, 0.8, 1.5, 2.5 s) and retries only a failed connection, where nothing was sent, a POST included. A request that was sent is never repeated: no answer is no_answer (for a write, outcome: unknown: check download_status before repeating it), and an HTTP error is Shelfmark answering, returned as a typed error.

  • Typed errors. {"error": kind, "message": …}, with Shelfmark's status and code where it gave one: shelfmark_unavailable, no_answer, auth_failed, forbidden, refused_by_policy, requests_unavailable, source_unavailable, not_found, conflict, already_queued, invalid_argument, invalid_id, stale_id, shelfmark_error.

Shelfmark's behaviour it is built around

From reading Shelfmark 1.6.1 (and 1.5.1); the tests use answers shaped like a real instance's:

  • GET /api/releases is synchronous and searches each enabled source in turn under one wall-clock budget, so it is slow; when every source fails it answers 503 with the first source's error.

  • POST /api/releases/download wants the release as listed plus the book's metadata, and answers a duplicate with HTTP 500 "Release is already in the download queue". The task id is the release's source_id.

  • GET /api/status holds the live queue; finished downloads also live in the activity snapshot and, once cleared in the UI, in /api/activity/history. JSON keys come back sorted, so order comes from timestamps.

  • A release's content_type is the source's label (for example 📕 book (fiction)), not ebook or audiobook; the content type searched for is what the download is queued as.

  • The request endpoints answer 403 requests_unavailable when Shelfmark runs with AUTH_METHOD=none, and an API key is ignored in that mode. With user accounts, SHELFMARK_API_KEY makes each request an admin's.

  • The Hardcover sync and its auto-download can run even in AUTH_METHOD=none: the requests stay out of reach, but their downloads appear in the queue with a request_id, and with the source's label (📘 book (non-fiction)) as their content type, which is reported here as ebook or audiobook.

  • 1.6.1's /api/health adds coordinator and answers 503 when the download coordinator has stopped; 1.5.x always answers {"status": "ok"}.

Development

nix flake check -L      # the test suite (in the package build), ruff and nixfmt
nix fmt                 # format the nix files; ruff format for the Python

License

MIT

Related MCP Connectors

Related MCP Servers

  • F
    license
    C
    quality
    D
    maintenance
    Enables users to manage and interact with a bookstore through natural language, supporting book searching, inventory checking, purchasing, and restocking operations. Provides seamless integration with AI assistants for complete bookstore management functionality.
    8
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to help users manage their reading experience by searching books, tracking reading progress, managing bookmarks, and generating personalized recommendations and summaries.
    -
  • A
    license
    A
    quality
    B
    maintenance
    Enables MCP-compatible AI assistants to search the Hardcover book catalogue and manage personal library data, reading progress, reading statistics, goals, activities, and more through natural language.
    25
    1
    MIT