libby-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@libby-mcpsearch Seattle and Burnaby libraries for Sapiens and compare availability"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 Libby libraries by name, city or postal code and get their keys (e.g. |
| 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. |
| Copies, holds and estimated wait for specific editions (title ids) at each library. |
| Full details: description, series, narrators, duration, publisher, ISBNs. |
| A library's subjects (genres) with ids for |
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 |
| Link your account with an 8-digit setup code (Libby menu > Copy To Another Device). |
| Your library cards, loans (due and renewal dates) and holds (queue position, estimated wait). |
| 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 or cancel a hold. |
| 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.
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 toolsborrowA
Borrow an available title, or a hold that is ready. Confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Loan length in days; defaults to the card's preference. | |
| library | No | Library key of the card to use; optional with a single linked card. | |
| title_id | Yes | OverDrive title id the library owns. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-read-only, non-destructive open-world action, so safety framing is partly covered. The description adds two valuable traits beyond that: the availability precondition and a mandatory user-confirmation step. It still omits what happens on a ready-hold borrow (whether the hold is consumed/converted into a loan) and failure behavior, which matter for a write operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero waste, with the action and its precondition front-loaded before the safety instruction. Nothing is padded or repeated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema and annotations present, the description only needs to cover trigger, preconditions and side effects. It covers trigger and precondition well; the one remaining gap is the hold-consumption side effect, which an agent borrowing a ready hold would benefit from knowing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with days, library and title_id all documented in-schema (including the 1-21 range and the "defaults to the card's preference" note). The description adds no parameter-level meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Borrow an available title, or a hold that is ready" gives a specific verb plus the two resource states it operates on, which meaningfully separates it from place_hold, renew_loan and return_loan. It stops short of naming those siblings, so the differentiation is implied rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description sets a clear precondition (the title must be available, or a hold must already be ready) and adds an operational rule: confirm with the user first. It does not say what to do in the negative case, e.g. route to place_hold when nothing is available, so it is good context without explicit alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cancel_holdADestructive
Cancel a hold; the user loses their place in the queue. Confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| library | No | Library key of the card to use; optional with a single linked card. | |
| title_id | Yes | OverDrive title id the library owns. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true, so the safety profile is partly covered; the description still adds real value by disclosing the concrete consequence — the user loses their place in the queue — and by requiring user confirmation before invocation. It stops short of saying whether the cancellation is reversible or whether the hold can be re-placed at the same position.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short clauses, consequence front-loaded after the action, and the confirmation requirement stated last. No filler; every phrase carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering safety, a full output schema, and 100% parameter documentation, the description supplies the one thing structured data lacks: the user-facing consequence and the confirmation requirement. Only the reversibility of the cancellation is left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters (library, title_id) are documented in the schema, so the description need not carry parameter detail. It adds nothing beyond the schema, which is the expected baseline when coverage is complete.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Cancel a hold') with the added consequence of losing queue position, so the agent knows exactly what operation is performed. It does not name or contrast with siblings like place_hold or return_loan, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The instruction 'Confirm with the user first' is a genuine usage prerequisite for a destructive action and is the most valuable guidance here. However, there is no explicit when-to-use/when-not or comparison to alternatives (e.g., vs. return_loan or place_hold), so usage context is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
connect_accountA
Link the user's Libby account with a one-time setup code. Returns the linked library cards.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | 8-digit setup code from Libby's 'Copy To Another Device'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a non-read-only, non-destructive, open-world operation, so the mutation profile is covered. The description adds that the call returns library cards, but says nothing about failure modes for an invalid/expired code, idempotency, or what re-linking does to existing state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the action and with a useful note on the return value. The return-value sentence is slightly redundant given an output schema exists, but it costs little.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A single-parameter tool with full schema coverage, an output schema, and annotations needs little more from the description. What is missing is mild: behavior on an invalid code and whether the call can be re-run safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the sole parameter is fully documented in the schema, including its provenance ("Libby's 'Copy To Another Device'"). The description adds no semantics beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
A specific verb and resource ("Link the user's Libby account") plus a statement of what comes back ("linked library cards"). It is distinguishable from get_account, which reads existing account data, but the description never names a sibling, so differentiation is by inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"one-time setup code" implies this is a first-time onboarding step rather than a repeatable operation, which is useful context. However, there is no explicit guidance on when to call this instead of get_account, or what to do if the account is already linked.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_librariesARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Library name, city or postal code. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so safety is covered. The description adds genuinely useful behavior beyond that: results may be ambiguous because branches, consortia, and special collections all match, and a user confirmation step is required before consuming the key. It omits ranking or result-count behavior, keeping it below a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the action and return value, followed by the ambiguity warning. Nothing is redundant or padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read tool with a full output schema and existing annotations, the description covers the only real risk: ambiguous matches requiring user confirmation before the key is used downstream. No essential calling information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single query parameter is already documented as 'Library name, city or postal code.' The description restates that same set without adding format details such as the two-character minimum or fuzzy-match behavior, so it stays at the baseline for schema-documented params.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (find libraries), the matching criteria (name, city, postal code), and what is returned (keys). No sibling tool in the list performs library resolution, so the tool is unambiguous against search_titles, get_availability, connect_account, etc.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operational guidance: multiple libraries can match, and the agent should confirm the correct one with the user before using its key. It does not explicitly state prerequisites or when-not-to-use (e.g., when a key is already known), so it stops short of full when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_accountBRead-only
The user's library cards, current loans (with due dates) and holds (with queue position).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| cards | Yes | |
| holds | Yes | |
| loans | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety profile is covered. The description adds useful detail about what fields come back (due dates, queue position), but says nothing about the requirement for an authenticated/connected account – a real gap given a connect_account sibling exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, dense sentence with zero filler, and the most important content (cards, loans, holds) is front-loaded. It reads as a noun fragment rather than a complete statement of action, which slightly weakens the framing but not the economy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description needn't enumerate return fields in full, and it correctly stays brief. The one thing an agent needs that is absent is the prerequisite that an account must already be connected/authenticated before this call succeeds.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is no parameter meaning for the description to carry. Baseline 4 applies; nothing is missing or misleading on this dimension.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
It names the specific resource set returned – library cards, current loans with due dates, and holds with queue position – which lets an agent distinguish it from get_history and get_availability. It lacks an explicit verb ('retrieve'), so the framing is a content listing rather than a stated action, but the resource is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use statement and no named alternative, despite siblings like get_history, connect_account and get_availability that overlap in scope. The agent must infer that this is the go-to call for a full account snapshot versus loan history or availability checks.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_availabilityARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| libraries | No | One library key or several, e.g. 'spl' or ['spl', 'burnaby']. Overrides the defaults. | |
| title_ids | Yes | OverDrive title ids (edition-specific). |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | No | |
| availability | Yes | Per title id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, and the description is consistent with a pure read. It adds interpretation context (a missing library means no ownership of that edition; waits are estimates), but says nothing about batching limits, rate limits, or how live the 'current' data is.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the main capability front-loaded and the caveat second. Slightly clipped phrasing ('A library missing from a title's list') costs a little clarity but there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and annotations covering the safety profile, the description only needs to add result-interpretation and routing, which it does. The remaining gap is operational detail (batch size of 50 title_ids, data freshness) rather than anything essential for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented, including that title_ids are edition-specific OverDrive ids and that libraries overrides defaults. The description reinforces the edition/library scoping but adds no new syntax or formatting detail, making baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the concrete payload (current copies, holds, estimated wait) scoped to 'specific editions at each library', which is far more specific than the tool name alone. It implicitly separates this lookup from mutation siblings like place_hold or borrow, though it never says outright that it only reads data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly routes the agent: if a library is absent from a title's list, that library doesn't own the edition, and search_titles is the way to find other editions. That is a real when/when-not rule with a named alternative, though no guidance is given about follow-up actions (e.g. place_hold) once availability is known.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_historyARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Most recent titles to return. | |
| library | No | Only titles borrowed from this library key. | |
| progress | No | Include reading statistics (one lookup per title). |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | Yes | Most recently borrowed first. |
| total | Yes | All titles in the borrowing history, before `library` and `limit`. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only and open-world, and the description adds substantive context beyond them: which fields exist, that history is raw and unordered for formatting, and that `progress` costs 'one lookup per title'. It still omits cost/volume limits at limit=500 and any pagination or failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and ordering are front-loaded, followed by a bulleted field glossary. The length is justified by genuinely non-obvious interpretation heuristics (marker vs. heard, gap thresholds), though a few sentences such as the ebook note could be trimmed without loss.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only raw-data tool with a full output schema, the description supplies everything an agent lacks elsewhere: the presence and meaning of derived metrics and how to read ambiguous cases. Nothing needed to call it or interpret its output is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description meaningfully elaborates the `progress` flag by enumerating exactly the derived fields it unlocks (marker_percent, listened_percent, marker_gap_percent, pace, minutes_spent, sessions). `limit` and `library` are left entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Everything the user has borrowed in Libby') plus an ordering guarantee ('most recently borrowed first'), which cleanly separates it from search_titles, get_title, and get_account. An agent can identify the tool without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the scope statement (browsing/analyzing a user's borrow history); there is no explicit 'use this when...' or 'instead use X for...' routing despite eleven sibling tools. The bulk of the text is field interpretation rather than tool selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_titleARead-only
Full details for one title: description, series, narrators, publisher, ISBNs.
| Name | Required | Description | Default |
|---|---|---|---|
| title_id | Yes | OverDrive title id. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | OverDrive title id of one edition. Each availability entry names its own edition. |
| isbns | No | |
| title | Yes | |
| series | No | |
| authors | Yes | |
| duration | No | Audiobook length, HH:MM:SS. |
| language | No | |
| subjects | No | Libby's broad subjects, e.g. 'History'. |
| subtitle | No | |
| libby_url | Yes | |
| narrators | No | |
| published | No | Publish date, YYYY-MM-DD. |
| publisher | No | |
| categories | No | Specific BISAC publishing categories. |
| media_type | Yes | |
| description | No | |
| star_rating | No | |
| availability | No | |
| series_position | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so safety and scope are covered. The description adds only the field list, which duplicates what the output schema already provides, and says nothing about not-found behavior or data freshness.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with the resource and returned fields front-loaded and no filler. Slightly phrase-like ('Full details for one title:') rather than a full clause, but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter read tool with annotations and an output schema, the description covers purpose and returned content adequately. The only gap is routing guidance versus sibling lookup tools, which is minor at this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single required parameter with 100% schema description coverage ('OverDrive title id', with a numeric pattern). The description adds no information about title_id, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Full details') and resource ('one title') and enumerates the fields returned (description, series, narrators, publisher, ISBNs). It is clearly distinct from search_titles or get_availability in spirit, though it never explicitly contrasts itself with those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'for one title' implies use after a search identifies a title id, but there is no explicit when-to-use or when-not-to-use guidance, and no mention of the close alternatives search_titles and get_availability that an agent must choose between.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_subjectsBRead-only
Subjects (genres) in a library's collection, largest first. Use the ids with search_titles.
| Name | Required | Description | Default |
|---|---|---|---|
| library | No | Library key. Defaults to the first configured one. | |
| media_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, so safety is covered. The description adds the sort order (largest first) and a handoff to search_titles, but says nothing about result size, truncation, or how media_type narrows output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, zero filler, and the core resource plus ordering is front-loaded. No restructuring needed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return shape is covered, and the tool has no required parameters. However, for a tool that supports media_type filtering and multi-library selection, the description omits anything an agent would need to pick parameters correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 50% — media_type has no schema description at all — and the description never mentions either parameter. It does not compensate for the gap, leaving the filtering behavior of media_type and the library default undocumented anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the resource clearly ('Subjects (genres) in a library's collection') plus a meaningful ordering ('largest first'). The listing verb is implied rather than stated, and no sibling is named as an alternative, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use the ids with search_titles' gives a downstream workflow hint, which is useful. But it does not say when to call this versus calling search_titles directly, nor any conditions or prerequisites for its own use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
place_holdA
Place a hold on a title. Confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| library | No | Library key of the card to use; optional with a single linked card. | |
| title_id | Yes | OverDrive title id the library owns. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a non-destructive write to an open-world system; the description adds a meaningful confirmation requirement before execution. It does not disclose failure modes (already-held, card limits) or idempotency, so the added context is helpful but thin.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero waste; the action is front-loaded and the confirmation instruction follows immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a full output schema and 100% parameter coverage, the description only needs to convey purpose and any pre-execution caveat, which it does. Minor gap: it doesn't mention the single-linked-card/library nuance, but that is covered by the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (title_id, library) are fully documented in the schema. The description adds nothing beyond the schema, which is the expected baseline when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('place a hold on a title'), distinct from siblings like cancel_hold or borrow. It doesn't explicitly contrast with borrow/renew, but the action is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Adds a workflow prerequisite ('Confirm with the user first'), which is useful, but gives no guidance on when to choose hold over borrow or what conditions make a hold appropriate (e.g., title unavailable). Usage is implied rather than explained.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
renew_loanA
Renew a loan (possible from its renewable_on date). Confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Loan length in days; defaults to the card's preference. | |
| library | No | Library key of the card to use; optional with a single linked card. | |
| title_id | Yes | OverDrive title id the library owns. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-read-only, non-destructive, open-world mutation. The description adds meaningful context beyond that: renewal is only possible from the renewable_on date, and the agent must confirm with the user before acting. It still does not describe the effect of renewal (e.g., due-date extension) or failure conditions like renewal limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two front-loaded sentences with no wasted text. The parenthetical 'its renewable_on date' is slightly ambiguous because renewable_on is not a parameter, but overall the structure is efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple three-parameter mutation with an output schema, the description covers the essential precondition and confirmation requirement. It leaves out what happens on failure (e.g., renewal limits) and what the renewal actually changes, which would be useful for a mutation tool even with annotations and schema coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so days, library, and title_id are already fully documented in the schema. The description adds no parameter-specific guidance beyond the timing context, which is appropriate given the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Renew a loan'), which is clearly distinct from siblings such as borrow, return_loan, and place_hold. It adds a timing qualifier ('possible from its renewable_on date'), but does not explicitly contrast itself with any sibling tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a concrete precondition ('possible from its renewable_on date') and a workflow rule ('Confirm with the user first'), which tells the agent when renewal is allowed and that user confirmation is required. It does not name alternatives or explain what to do when renewal is unavailable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
return_loanADestructive
Return a loan early. Confirm with the user first.
| Name | Required | Description | Default |
|---|---|---|---|
| library | No | Library key of the card to use; optional with a single linked card. | |
| title_id | Yes | OverDrive title id the library owns. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and openWorldHint=true, so the safety profile is covered. The description adds a critical behavioral requirement: confirm with the user before acting. It could say more about reversibility or effects on history, but it adds meaningful context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short, front-loaded sentences with no filler. The action is stated first and the confirmation requirement follows immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, annotations covering safety, and full parameter documentation, the description supplies what an agent needs to act safely. It doesn't elaborate on post-return state or edge cases, but enough context is available elsewhere.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both the optional library key and required title_id are fully documented in the schema. The description doesn't add syntax or format details, which is acceptable given the schema's completeness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Return a loan early'), which distinguishes it from renewing or borrowing. It doesn't explicitly name siblings like renew_loan, but the 'early' qualifier gives it a distinct scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides a necessary prerequisite ('Confirm with the user first'), which is useful for a destructive action. However, it doesn't say when to prefer this over renew_loan or cancel_hold, nor does it describe exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_titlesARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | 'popular' and 'newest' rank within each library. | relevance |
| limit | No | Results per library. | |
| query | No | Title, author, series or keywords. Omit to browse. | |
| language | No | ISO 639-1 code; null for any. | en |
| libraries | No | One library key or several, e.g. 'spl' or ['spl', 'burnaby']. Overrides the defaults. | |
| media_type | No | ||
| subject_ids | No | Subject ids from list_subjects. | |
| available_only | No | Only titles available now somewhere. | |
| category_codes | No | BISAC codes (from a title's categories), e.g. ['POL062000']; titles must match all. |
Output Schema
| Name | Required | Description |
|---|---|---|
| errors | No | Libraries that failed, with the reason. |
| titles | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint) and open-world scope, yet the description still adds non-obvious behavior: editions are merged by title/first author/format and ranked by best position across libraries, and availability is reported per library. It stops short of describing pagination or how limits interact across multiple libraries.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the core capability front-loaded and the result-shaping behavior second. Minor waste in the line-broken formatting, but every sentence carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and near-complete parameter descriptions, the description only needs to explain the search model and result merging, which it does. A note on multi-library result grouping or limits per library would round it out.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 89%, so parameters are largely documented in the schema itself (sort semantics, 'Results per library', 'Omit to browse', subject ids source). The description adds nothing parameter-specific, so the baseline 3 applies; the undocumented media_type remains unaddressed in both places.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Search' titles) and adds real scope detail: one or several libraries, with availability per library. It never names the sibling it differs from (e.g. get_title for a single known title vs get_availability), so it falls short of 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: 'Search one library or several at once' suggests a discovery context, and the schema note 'Omit to browse' hints at browsing mode, but the description gives no explicit when-to-use or when-to-prefer-get_title/get_availability guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
13 tool updates
v0.1.0- First observed
borrow - First observed
cancel_hold - First observed
connect_account - First observed
find_libraries - First observed
get_account - First observed
get_availability - First observed
get_history - First observed
get_title - First observed
list_subjects - First observed
place_hold - First observed
renew_loan - First observed
return_loan - First observed
search_titles
TDQS
Scored across 13 tools
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.
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.
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.
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
Related MCP Connectors
- LeafleOAuthnet.nanosheep
Personalised book recommendations, filtered to what's on your public library's shelf right now.
Federated search of books and papers, BibTeX/RIS citations, open-access retrieval and reading.
Search a catalog of 1.7 million books and find books by mood, vibe, pace or genre. Read-only.
Academic literature search, retrieval, and private library management on top of OpenAlex.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables searching the National Library Board Singapore catalogue by title, author, ISBN, or subject, and checking real-time availability of books across library branches.Apache 2.0
- AlicenseNot gradedqualityDmaintenanceEnables searching, reading, and managing a Calibre ebook library through natural language, with features like metadata search, full-text search, content extraction, and library management.149 npmApache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables 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.1MIT
- AlicenseNot gradedqualityBmaintenanceEnables searching for books by title, author, or keyword, retrieving edition details by ISBN, and accessing author profiles and canonical work records through the Open Library API.13 npmMIT