Skip to main content
Glama
README.md
# libby-mcp

An [MCP](https://modelcontextprotocol.io) 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, 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.

## Setup

Requires [uv](https://docs.astral.sh/uv/). No configuration is needed.

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

```json
{
  "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

```bash
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

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
ResponsivenessNo issues