Skip to main content
Glama

libby-mcp

An MCP server for Libby / OverDrive. Search library catalogs and compare ebook and audiobook availability across several libraries without a login, and, once you link your Libby account, see and manage your loans and holds.

Unofficial. The catalog tools use the public catalog API behind the Libby app, which OverDrive can change at any time; a nightly integration test watches for that.

The account tools use Libby's private account API. OverDrive's terms prohibit other clients from using it and say they may suspend accounts. Use them at your own risk.

Tools

Catalog (no login, read-only)

Tool

What it does

find_libraries

Find Libby libraries by name, city or postal code and get their keys (e.g. spl).

search_titles

Search or browse one or more libraries with availability at each. Filters: format, available now, language, subjects, BISAC categories. Sorts by relevance, popular or newest.

get_availability

Copies, holds and estimated wait for specific editions (title ids) at each library.

get_title

Full details: description, series, narrators, duration, publisher, ISBNs.

list_subjects

A library's subjects (genres) with ids for search_titles.

Editions differ by country. Libraries often own different editions of the same book: Sapiens is 3255516 (HarperCollins) at Seattle and 3461405 (McClelland & Stewart) at Burnaby. search_titles merges editions by title, first author and format, and each availability entry carries its library's own title_id.

Account (your Libby account)

Tool

What it does

connect_account

Link your account with an 8-digit setup code (Libby menu > Copy To Another Device).

get_account

Your library cards, loans (due and renewal dates) and holds (queue position, estimated wait).

get_history

Everything you have borrowed in Libby, most recent first, as data: borrow count and dates, status (on loan, on hold, returned), time spent, sessions, reading-position marker (and ebook chapter), audiobook length, share actually heard, marker gap and pace (to spot skipping), BISAC categories, ISBNs, and your other Libby tags such as "Finished".

place_hold / cancel_hold

Place or cancel a hold.

borrow / renew_loan / return_loan

Borrow an available title or ready hold (and add it to Libby's borrowing history, as the app does), renew or return a loan.

Write tools take the library key of the card to use (optional with one card). Once linked, searches default to your cards' libraries. Set LIBBY_READ_ONLY=true to hide the write tools.

Where the login lives. connect_account saves the account token to ~/.config/libby-mcp/identity.json (mode 600) on the machine running the server; it is never returned to the agent. Tokens expire after 7 days unless used, and the server refreshes them on use. In temporary environments such as cloud sessions, the file disappears with the container, so link again each session.

The account tools were checked against a real linked account (linking, cards, loans, holds, history); write tools are tested against mocked responses only.

Related MCP server: calibre-mcp

Setup

Requires uv. No configuration is needed.

Claude Code (.mcp.json in your project):

{
  "mcpServers": {
    "libby": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/puneetghodasara/libby-mcp", "libby-mcp"]
    }
  }
}

Claude Desktop (claude_desktop_config.json) takes the same mcpServers block.

Choosing libraries. Every tool takes one library key ("spl") or several (["spl", "burnaby"]) in libraries. When none is given, the agent asks which library you use and looks it up with find_libraries. To skip that question, set optional defaults in the server's env, e.g. "LIBBY_LIBRARIES": "spl,burnaby"; a libraries argument on a call still overrides them.

Development

uv sync
uv run pytest              # unit tests (HTTP mocked)
uv run pytest -m live      # integration tests against the real API
uv run ruff check . && uv run ruff format --check .

License

MIT

Available Tools

13 tools
borrowA

Borrow an available title, or a hold that is ready. Confirm with the user first.

Inputs: title_id (required), days, library. Returns: result

cancel_holdA
Destructive

Cancel a hold; the user loses their place in the queue. Confirm with the user first.

Inputs: title_id (required), library. Returns: result

connect_accountA

Link the user's Libby account with a one-time setup code. Returns the linked library cards.

Inputs: code (required). Returns: result

find_librariesA
Read-only

Find libraries that use Libby by name, city or postal code, and return their keys.

Several libraries can match (branches, consortia, special collections); confirm the right one with the user before using its key.

Inputs: query (required). Returns: result

get_accountB
Read-only

The user's library cards, current loans (with due dates) and holds (with queue position).

Inputs: no named parameters. Returns: cards, holds, loans

get_availabilityA
Read-only

Current copies, holds and estimated wait for specific editions at each library.

    A library missing from a title's list doesn't own that edition; use search_titles to
    find other editions of the same book.
    

Inputs: title_ids (required), libraries. Returns: errors, availability

get_historyA
Read-only

Everything the user has borrowed in Libby, most recently borrowed first. Raw data; format it as asked.

    Per title: borrow count and dates (a minimum), status (on_loan / on_hold / returned), subjects and
    BISAC categories, the user's other Libby tags (e.g. 'Finished'), ISBNs and, with `progress`:

    - marker_percent: where the reading position is, not how much was read; it moves when skipping.
    - listened_percent (audiobooks): how much was actually heard (minutes_spent / length_minutes).
    - marker_gap_percent (audiobooks): marker minus heard. Up to ~5: at most an intro or preface
      skipped; above ~10: skipped ahead; negative: parts re-listened. Prefer it over pace early on.
    - pace (audiobooks): length covered by the marker / time spent. ~1: listened straight through
      (assuming 1x playback); above ~2: skipped ahead.
    - minutes_spent and sessions: effort; one session with many minutes was a single long sitting.
    - Ebooks have no length, so only marker_percent and minutes_spent apply.
    A marker at 90%+ with a small gap usually means finished; under ~10% with few minutes means
    sampled or abandoned. 'Finished' in tags is the user's own explicit mark.
    

Inputs: limit, library, progress. Returns: items, total

get_titleA
Read-only

Full details for one title: description, series, narrators, publisher, ISBNs.

Inputs: title_id (required). Returns: id, isbns, title, series, +15 more

list_subjectsB
Read-only

Subjects (genres) in a library's collection, largest first. Use the ids with search_titles.

Inputs: library, media_type. Returns: result

place_holdA

Place a hold on a title. Confirm with the user first.

Inputs: title_id (required), library. Returns: result

renew_loanA

Renew a loan (possible from its renewable_on date). Confirm with the user first.

Inputs: title_id (required), days, library. Returns: result

return_loanA
Destructive

Return a loan early. Confirm with the user first.

Inputs: title_id (required), library. Returns: result

search_titlesA
Read-only

Search one library or several at once, with availability at each.

Editions of the same book (title, first author and format) are merged into one result, ranked by its best position in any library.

Inputs: sort, limit, query, language, +5 more. Returns: errors, titles

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 13 tools

    Disambiguation4/5

    Each tool maps to a distinct step in the Libby workflow (find library, search, inspect availability, act on loans/holds), and the descriptions explicitly distinguish look-alikes such as search_titles vs. get_title vs. get_availability. The only mild overlap is that search_titles already reports availability at each library while get_availability drills into specific editions, but the guidance makes the intended split clear.

    Naming Consistency5/5

    All 13 tools use a clean snake_case verb_noun pattern (find_libraries, search_titles, get_availability, place_hold, cancel_hold, renew_loan, return_loan). Bare `borrow` is the one noun-less entry but still fits the verb-first convention.

    Tool Count5/5

    13 tools is squarely in the well-scoped range, and each one covers a necessary operation: discovery, account linking, reads (account, history, title details, subjects), and write actions on holds and loans. Nothing appears redundant or filler.

    Completeness4/5

    The full lifecycle is present: find library, connect account, search/inspect, borrow, renew, return, place/cancel hold, and review history. Minor gaps remain — no tool for applying or editing the user's Libby tags mentioned in get_history, and no account unlink/refresh — but these are workaround-able.

    Maintenance

    ActivityMaintained
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables searching, reading, and managing a Calibre ebook library through natural language, with features like metadata search, full-text search, content extraction, and library management.
      557 npm
      Apache 2.0
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables searching for lawful, free-to-read books across multiple open catalogues and resolving access routes (download, read, borrow, preview) via MCP tools like search_books and resolve_access.
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables users to find books by keyword, ISBN, or author and check which branches hold copies of them and whether those copies are currently available for loan or when they are due back. Currently covers Shanghai's interlinked public library network of 900+ locations, with a design open to additional cities.
      3
      Apache 2.0