openlibrary-mcp-server
Server Details
Search books and authors, fetch editions, browse subjects, and resolve cover images.
- Status
- Healthy
- Uptime
- 99.9% over 78 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- cyanheads/openlibrary-mcp-server
- GitHub Stars
- 4
- Server Listing
- @cyanheads/openlibrary-mcp-server
- ChatGPT
- –
- Claude
- –
TDQS
Scored across 10 tools
The read surface is cleanly partitioned by resource and action: author, work, edition(s), subject, cover, and three distinct search modes. The only real friction is the get_edition vs get_editions pair, which differ by lookup-by-identifier versus list-by-work; the descriptions resolve it, but the near-identical names invite misselection.
Every tool follows the same openlibrary_<verb>_<noun> snake_case pattern with a consistent verb vocabulary (get_* for direct lookups, search_* for queries). Prefixing all names with the server namespace is uniform, not a deviation.
Ten tools is squarely in the well-scoped range, and each one covers a distinct access path in the catalogue (ID lookup, listing, cover URL construction, metadata search, full-text search). No tool looks like filler or a duplicate of another.
Coverage spans the core lifecycle: search to find IDs, resolve authors/works/editions/subjects, drill from work to editions, and retrieve covers. Gaps are minor and mostly outside the read-only catalogue scope — e.g. no subject browsing/list endpoint or trending/recent listing — but nothing blocks the primary research workflows.
Available Tools
10 toolsopenlibrary_get_authorGet AuthorARead-onlyIdempotentInspect
Fetch author detail by Open Library Author ID (OL…A). Returns bio, birth/death dates, photo IDs, and linked identifiers from Wikidata, VIAF, ISNI, Goodreads, and LibraryThing. Use openlibrary_search_authors to find an author ID first.
| Name | Required | Description | Default |
|---|---|---|---|
| author_id | Yes | Open Library Author ID. Format: OL…A (e.g., "OL24638A"). A leading "/authors/" prefix is stripped if provided. |
Output Schema
| Name | Required | Description |
|---|---|---|
| bio | No | Author biography. Absent when not provided. |
| name | No | Primary author name. |
| error | No | Present when the call failed. Absent on success. |
| notice | No | Set when the requested author ID was merged into a different canonical ID. |
| author_id | No | Canonical Open Library Author ID (OL…A). |
| photo_ids | No | Numeric photo IDs. Pass to openlibrary_get_cover_url with target "author" and id_type "id". |
| birth_date | No | Birth date string. Absent when not recorded. |
| death_date | No | Death date string. Absent when not recorded. |
| remote_ids | No | Remote identifiers for cross-referencing with other databases. |
| fuller_name | No | Full name including middle names. Absent when not recorded. |
| personal_name | No | Personal or given name. Absent when not recorded. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the core behavioral profile is covered. The description adds a helpful list of returned identifiers but does not disclose additional behavioral traits such as rate limits, authentication, or failure modes; this is acceptable given the strong annotation coverage.
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?
The description is compact and front-loaded: it states the action, ID format, return fields, and prerequisite in three focused sentences. Every sentence contributes useful information, and there is no redundant or filler content.
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 read-only tool with one required parameter and an output schema, the description covers all necessary context: what the tool does, what the ID looks like, what data will be returned, and how to first find the ID. No critical 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?
There is only one parameter and schema description coverage is 100%, so the schema already documents the ID format and prefix-stripping behavior. The description repeats this information rather than adding substantially new parameter semantics, warranting the baseline score.
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 uses a specific verb ('Fetch') and resource ('author detail') and identifies the exact ID format (OL…A). It also lists the returned data, making the tool's purpose distinct from sibling tools like openlibrary_get_author_works and openlibrary_search_authors.
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 explicitly instructs the agent to use openlibrary_search_authors first to obtain an author ID, which defines the correct entry condition. This provides clear guidance on the prerequisite workflow without leaving the agent to infer when this tool should be used.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openlibrary_get_author_worksGet Author WorksARead-onlyInspect
List works by an author. Returns titles, cover IDs, and work OLIDs for drilling into editions or details. Use openlibrary_get_author for author bio and details, or openlibrary_get_editions to explore specific printings.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max works to return; values above 100 apply 100 when limit clamping is enabled. | |
| offset | No | Zero-based offset for pagination. | |
| author_id | Yes | Open Library Author ID (OL…A). A leading "/authors/" prefix is stripped if provided. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| total | No | Total works by this author. |
| works | No | Works by this author, up to limit. |
| notice | No | Guidance for a merged author ID or a requested limit above the page ceiling. |
| offset | No | Zero-based offset of the first returned result — echoes the requested offset, so an empty page still records the offset that produced it. |
| author_id | No | Open Library Author ID. |
| totalCount | No | Total works by this author across all pages. |
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 that OLIDs can be used for drilling into editions or details, which is useful context, but says nothing about pagination, limit clamping, or result ordering. With annotations doing the heavy lifting, a 3 is appropriate.
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?
Three short sentences, front-loaded with purpose and return contents, followed by the routing guidance. No filler and no repetition of schema detail.
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 read-only list endpoint with annotations, a fully described three-parameter schema, and an output schema, the description covers purpose, return shape, and alternatives. Nothing an agent needs to invoke it correctly 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 description coverage is 100%, including the OL…A ID format, prefix stripping, default limit of 20 and offset semantics, so the schema already carries the parameter burden. The description adds only an indirect hint that work OLIDs feed into edition lookups and does not elaborate on limit or offset. 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?
The description opens with a specific verb and resource ('List works by an author') and immediately states the returned identifiers (titles, cover IDs, work OLIDs). It also names the sibling tools it is not, so an agent can distinguish it from openlibrary_get_author and openlibrary_get_editions without inspecting either 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?
It explicitly routes the agent to alternatives with conditions: openlibrary_get_author for bio/details, openlibrary_get_editions for specific printings. The implied 'use this when you want the author's work list' is made concrete by contrast with those siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openlibrary_get_cover_urlGet Cover URLARead-onlyIdempotentInspect
Construct a cover image URL for a book or author photo without fetching the image. Returns a direct HTTPS URL in the requested size (S/M/L). The identifier format is validated locally: "id" must be numeric, "isbn" 10 or 13 digits (an ISBN-10 may end in an X check digit), "olid" an edition OLID (OL…M) for target "book" and an author OLID (OL…A) for target "author". Identifiers with path separators or control characters, and author-by-ISBN lookups, are rejected. A returned URL does not verify that a cover exists.
| Name | Required | Description | Default |
|---|---|---|---|
| size | No | Image size. S = small (~45px tall), M = medium (~150px tall), L = large (~400px tall). | M |
| target | No | "book" returns a book cover from covers.openlibrary.org/b/. "author" returns an author photo from covers.openlibrary.org/a/ — use with id_type "id" (photo_id) or "olid" (author OLID). | book |
| id_type | Yes | "id" is the numeric cover_i / cover ID from search or work results. "isbn" and "olid" look up the cover from those identifiers. | |
| identifier | Yes | The identifier value, validated against id_type before the URL is built. For "id": a numeric cover or photo ID from work/edition/author data. For "isbn": 10 or 13 digits, hyphens optional — an ISBN-10 may end in an X check digit (e.g., 080442957X). For "olid": an edition OLID (OL…M) for target "book", an author OLID (OL…A) for target "author". |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Direct HTTPS URL to the cover image; not fetched or verified by this tool. |
| note | No | Reminder that the image is unverified and a missing cover may return a placeholder. |
| error | No | Present when the call failed. Absent on success. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only/idempotent, and the description goes well beyond them: validation happens locally, no network request is made, a returned URL does not verify a cover exists, and author-by-ISBN is refused. Those caveats are exactly the behavioral facts an agent needs to avoid misinterpreting a synthesized URL as confirmed content.
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?
Front-loaded with the core action and the no-fetch property, then the constraints. The identifier-format sentence partially restates schema enums/descriptions, which costs a little density, but every sentence carries either scope or a validation rule.
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 need not be explained, and the description covers validation, non-fetching behavior, and the non-verification caveat. The only residual gap is that it never routes the agent to a sibling when the identifier cannot be used.
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; the description still adds value by explaining per-id_type validation (numeric id, 10/13-digit ISBN with optional X check digit, OL…M vs OL…A OLID depending on target) and the cross-parameter constraint that author plus ISBN is rejected. That constraint and validation behavior are not visible in 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 ("Construct a cover image URL") and immediately scopes it with "without fetching the image," which separates it from every sibling that retrieves author/work/edition data. An agent can distinguish this URL-builder from the fetch-style tools without opening any 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?
The rejection rules (path separators, control characters, author-by-ISBN) effectively define when the tool will not work, and the no-fetch framing implies when to prefer it over a data-fetching sibling. It stops short of naming a specific alternative tool to use instead when the call is invalid.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openlibrary_get_editionGet EditionARead-onlyIdempotentInspect
Resolve one or more editions by identifier: ISBN-10, ISBN-13, OCLC, LCCN, or Open Library Edition ID (OL…M). Every identifier in a call shares one id_type — pass id_type "isbn" for both ISBN-10 and ISBN-13. Up to 50 identifiers resolve in a single upstream batch; with limit clamping enabled, exact duplicates collapse and remaining identifiers are returned as unprocessed for another call. Returns full edition metadata including authors, publisher, languages, all identifier types, and the parent work ID. Author names come inline when recorded; otherwise bounded lookups recover parent-work credits marked as such, and a notice names any edition whose recovery failed. Identifiers that resolve come back in editions; processed misses are listed in unresolved with a reason. The call fails only when no processed identifier resolves, and any unprocessed remainder remains in its error data and recovery guidance.
| Name | Required | Description | Default |
|---|---|---|---|
| id_type | Yes | Identifier type shared by every entry in identifiers. "isbn" handles both ISBN-10 and ISBN-13. "olid" is the native Open Library edition ID (OL…M). Mixing types within one call is not supported — issue one call per type. | |
| identifiers | Yes | Identifiers to resolve, 1–1000 raw entries, all of the type named by id_type. Exact duplicate strings collapse in first-occurrence order; the first 50 distinct entries are processed, including malformed entries, and remaining strings are returned in unprocessed. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Present when the identifier batch was shortened or author lookups failed or were skipped; includes all applicable guidance. |
| editions | No | Editions that resolved, in request order. Shorter than identifiers when any entry missed. |
| unresolved | No | Identifiers that produced no edition. Empty when every identifier resolved; never overlaps editions. |
| unprocessed | No | Remaining distinct identifiers in input order, preserved verbatim for another call. Empty when the entire batch was processed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the readOnly/idempotent/openWorld annotations: discloses the 50-identifier upstream batch cap, duplicate collapsing in first-occurrence order, malformed entries counting toward the limit, partial-failure semantics (fails only when no processed identifier resolves), and that the unprocessed remainder is carried in the error data with recovery guidance. It also explains the inline-vs-recovered author credit path and the failure notice, which is the kind of behavior an agent cannot guess.
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?
Front-loaded with the core verb, resource, and identifier set, and every subsequent sentence is operational rather than filler. It is dense and clause-heavy, and the batching/duplicate-collapse sentence partly duplicates the identifiers schema description, but nothing is wasted on restating the name or title.
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 two-parameter batch-resolution tool with full annotation coverage and an output schema, the description supplies everything an agent still needs: batching limits, per-call id_type homogeneity, partial-success vs total-failure behavior, and what happens to leftover identifiers. Return-value detail is redundant with the output schema but does not leave a gap.
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 the schema already documents id_type's enum, the ISBN-10/13 sharing, OLID format, and the 50-distinct/maxItems rule. The description mainly restates these ("pass id_type 'isbn' for both ISBN-10 and ISBN-13", "exact duplicates collapse"), adding little meaning the schema does not already carry, so 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?
Specific verb and resource ("Resolve one or more editions by identifier") plus an exhaustive enumeration of accepted identifier types (ISBN-10/13, OCLC, LCCN, OLID) makes the operation unmistakable. It does not name a sibling such as openlibrary_get_editions or openlibrary_search_books, so the distinction from those tools is only implicit in the identifier-based framing.
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 context is implied by the identifier types and reinforced by batching rules (one id_type per call, up to 50 per batch, re-call for the unprocessed remainder). However, no alternative tool is named and no when-not condition is stated, so an agent must infer that search_books or get_editions is the right choice when it has a title or work ID rather than an identifier.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openlibrary_get_editionsGet EditionsARead-onlyIdempotentInspect
List editions of a work — different publishers, languages, formats, and print runs. Returns ISBNs, publisher, language, page count, and edition OLIDs. Use after openlibrary_get_work or openlibrary_search_books to find a specific printing. A merged work ID resolves to the work it was merged into. To reach a work from an ISBN, call openlibrary_get_edition with id_type "isbn" — its work_id output is the parent work.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max editions to return; values above 100 apply 100 when limit clamping is enabled. Prefer 10–20 for exploration. | |
| offset | No | Zero-based offset for pagination. | |
| work_id | Yes | Open Library Work ID. Format: OL…W (e.g., "OL45804W"), optionally prefixed "/works/". Not an ISBN — resolve an ISBN to its work with openlibrary_get_edition (id_type "isbn"). |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| total | No | Total editions for this work. |
| notice | No | Guidance for a merged work ID or a requested limit above the page ceiling. |
| offset | No | Zero-based offset of the first returned result — echoes the requested offset, so an empty page still records the offset that produced it. |
| work_id | No | Canonical Open Library Work ID the editions were found under — differs from the requested work_id when that ID was merged into this work. |
| editions | No | Editions of the work, up to limit. |
| totalCount | No | Total editions for this work across all pages. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, open-world, so the bar is lower. The description still adds real behavioral information the annotations cannot: the payload fields returned and the edge case that a merged work ID silently resolves to the work it was merged into. It does not mention behavior for an unknown/invalid work_id, which would complete the picture.
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?
Front-loaded with the purpose, then sequencing, then edge case — a sensible order with no filler. The closing ISBN-routing sentence partially duplicates the work_id schema description, costing a little efficiency.
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 values needn't be detailed, yet the description still summarizes them usefully. Paging is delegated to a well-documented schema and the merged-work case is called out; only error/empty-result behavior is unaddressed.
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 limit (with guidance to prefer 10–20) and offset are fully documented in the schema, so the baseline of 3 applies. The description's work_id note about ISBNs largely restates the schema's own warning rather than adding new semantics.
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 ("List editions of a work") and immediately scopes what an edition is: publishers, languages, formats, print runs. It distinguishes itself from openlibrary_get_edition (single printing) and openlibrary_get_work (parent work) by naming both siblings explicitly.
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 explicit sequencing ("Use after openlibrary_get_work or openlibrary_search_books to find a specific printing") and an explicit anti-pattern with the correct alternative: ISBN lookups should go to openlibrary_get_edition with id_type "isbn". An agent has no ambiguity about which sibling to call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openlibrary_get_subjectGet SubjectARead-onlyInspect
Browse works by subject. Returns matching works with edition counts and cover IDs, plus the total work count for the subject. Case and spacing are normalized before lookup, so "Science Fiction" and "science_fiction" are the same request. Subject tags are user-contributed and the vocabulary varies — when a subject returns no works, try a different word form (singular/plural), a synonym, or a broader term.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max works to return. Subject pages typically show 12 at a time. | |
| offset | No | Zero-based offset for pagination. | |
| subject | Yes | Subject name. Normalized before lookup — trimmed, lowercased, and internal whitespace converted to underscores (e.g., " Science Fiction " → "science_fiction") — so varying case or surrounding whitespace does not change the result. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| works | No | Works under this subject, up to limit. |
| notice | No | Recovery guidance when work_count is 0, composed with requested/applied page limits and next offset when the limit was reduced to 100. Absent when neither applies. |
| offset | No | Zero-based offset of the first returned result — echoes the requested offset, so an empty page still records the offset that produced it. |
| totalCount | No | Total works tagged with this subject across all pages. |
| work_count | No | Total works tagged with this subject. |
| subject_key | No | Normalized subject key (lowercase, underscores). |
| subject_name | No | Canonical subject name as stored on Open Library. |
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 still adds the returned fields and the important caveat that subject tags are user-contributed with inconsistent vocabulary. That vocabulary volatility is non-obvious behavior an agent would otherwise misdiagnose as an empty result.
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?
Three sentences, each carrying distinct information: what it does, what it returns, and how to handle empty results. Front-loaded with the purpose and free of redundant wording despite repeating the normalization note.
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 and annotations cover the safety profile, so the description only needs to add purpose, return shape hints, and the vocabulary caveat — all present. Nothing an agent needs to invoke it correctly 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 subject normalization is already fully documented in the schema, and the description's restatement of case/spacing normalization adds little. It says nothing about limit/offset semantics, 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?
States a specific verb and resource ('Browse works by subject') and describes what comes back (matching works with edition counts and cover IDs, plus total work count). This cleanly separates it from the search_books and get_work siblings without needing 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?
Gives actionable guidance for the failure case — if no works return, try singular/plural, synonyms, or a broader term — which is real usage context. It stops short of naming an alternative tool (e.g. search_books) for free-text queries, so no exclusions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openlibrary_get_workGet WorkARead-onlyIdempotentInspect
Fetch a work by Open Library Work ID (OL…W). Returns title, description, subjects, cover IDs, and linked author IDs for follow-up lookups. Works represent the abstract book concept independent of any specific edition. A merged work ID resolves to the work it was merged into. To reach a work from an ISBN, call openlibrary_get_edition with id_type "isbn" — its work_id output is the parent work. Note: author names are not included — use openlibrary_get_author or openlibrary_search_books for names.
| Name | Required | Description | Default |
|---|---|---|---|
| work_id | Yes | Open Library Work ID. Format: OL…W (e.g., "OL45804W"), optionally prefixed "/works/". Not an ISBN — resolve an ISBN to its work with openlibrary_get_edition (id_type "isbn"). |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| title | No | Work title. |
| notice | No | Set when the requested work ID was merged into a different canonical ID. Absent otherwise. |
| created | No | ISO 8601 creation timestamp. Absent when not available. |
| work_id | No | Canonical Open Library Work ID (OL…W) — differs from the requested work_id when that ID was merged into this work. |
| subjects | No | Subject tags for this work. |
| cover_ids | No | Numeric cover IDs. Pass to openlibrary_get_cover_url with id_type "id". |
| author_ids | No | Open Library Author IDs (OL…A). Use openlibrary_get_author for names and bio. |
| description | No | Work description or blurb. Absent when not provided. |
| last_modified | No | ISO 8601 last-modified timestamp. Absent when not available. |
| subject_times | No | Time period subjects. |
| subject_people | No | People subjects. |
| subject_places | No | Geographic subjects. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and openWorld, so safety is covered. The description adds genuinely non-obvious behavior: a merged work ID resolves to the work it was merged into, and author names are omitted from the response. Listing return fields is mildly redundant with the output schema, which keeps this from 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?
Front-loaded with purpose and ID format, then scope clarification, then routing hints — all sentences earn their place. The response-field enumeration is the one line that partially duplicates the output 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?
For a single-parameter read tool with annotations and an output schema, the description covers the remaining gaps an agent would hit: work vs edition semantics, merged-ID edge case, missing author names, and the ISBN resolution path. Nothing needed to call it correctly is absent.
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 work_id property already documents the OL…W format, optional /works/ prefix, and the ISBN exclusion. The description restates the same format guidance without adding new semantics, 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?
States a specific verb and resource (Fetch a work by Open Library Work ID), gives the ID format, and explains the domain concept of a 'work' versus an edition, which is the key distinction among siblings like openlibrary_get_edition and openlibrary_get_editions.
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?
Explicitly routes the agent both ways: from an ISBN use openlibrary_get_edition (id_type "isbn") and take its work_id, and for author names use openlibrary_get_author or openlibrary_search_books. These are concrete when-to-use-this-vs-alternative instructions tied to named siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openlibrary_search_authorsSearch AuthorsARead-onlyInspect
Search Open Library authors by name. Returns Open Library Author IDs, names, birth/death dates, top works, and subject associations. Use author IDs for openlibrary_get_author (bio, remote IDs) or openlibrary_get_author_works (list of works).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max results to return; values above 100 apply 100 when limit clamping is enabled. | |
| query | Yes | Author name search query. Partial names and alternate names work. | |
| offset | No | Zero-based offset for pagination. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| total | No | Total matching authors across all pages. |
| notice | No | Guidance for an empty page or a requested limit above the page ceiling. Absent when neither applies. |
| offset | No | Zero-based offset of the first returned result — echoes the requested offset, so an empty page still records the offset that produced it. |
| authors | No | Matching authors, up to limit. |
| totalCount | No | Total matching authors across all pages — the upstream match count, reported even when this page is empty because offset ran past the end. |
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 the result shape (IDs, names, birth/death dates, top works, subject associations) and the recommended next call. It does not mention pagination behavior or the limit-clamping nuance, which matters for a paginated search.
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?
Three tight sentences: purpose first, result shape second, next-step guidance third. No filler, and the most decision-relevant information is front-loaded.
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 100% schema coverage plus read-only annotations, the description is nearly self-sufficient. The only gap is that pagination/limit semantics are left entirely to the schema, which is acceptable but not fully spelled out in the narrative.
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 query, limit, and offset are all fully documented in the schema, including the limit-clamping caveat. The description adds nothing parameter-specific, 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?
States a specific verb+resource+scope ('Search Open Library authors by name') and immediately differentiates itself from the sibling getters by naming openlibrary_get_author and openlibrary_get_author_works as the follow-on tools. An agent can distinguish it from openlibrary_search_books and openlibrary_search_inside 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?
Explains what to do with the result ('Use author IDs for openlibrary_get_author ... or openlibrary_get_author_works'), which is genuine routing guidance to siblings. It stops short of stating when *not* to use this tool (e.g., direct lookup when an ID is already known), so it falls short of the explicit when/when-not bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openlibrary_search_booksSearch BooksARead-onlyInspect
Full-text book search across Open Library works. Supports field filters (title, author, subject, publisher, ISBN, language) and returns work-level records with edition counts, cover IDs, and reading availability. Use query for general search or combine specific field filters. Results are work-level — drill into editions via openlibrary_get_editions.
| Name | Required | Description | Default |
|---|---|---|---|
| isbn | No | Find works that have editions with this ISBN (10 or 13 digits, hyphens ignored). | |
| sort | No | Sort order. "relevance" uses Solr scoring. "new"/"old" sort by first publish year. "rating" by average community rating. "editions" by edition count. | relevance |
| limit | No | Max results to return. Higher values increase response size; prefer 10–20 for exploration. | |
| query | No | Full-text search query. Supports Solr field prefixes: title:, author:, subject:, publisher:, isbn:, language:. Omit to use the filter parameters instead. | |
| title | No | Filter by title. Matched against work title and alternative titles. | |
| author | No | Filter by author name. Partial names work. | |
| offset | No | Zero-based offset for pagination. | |
| subject | No | Filter by subject tag (e.g., "science fiction", "history"). | |
| language | No | Restrict results to one language. Takes a 3-letter MARC code (e.g., "eng", "fre", "ger", "chi") — the same vocabulary openlibrary_get_edition and openlibrary_get_editions return. A 2-letter ISO 639-1 code (e.g., "en", "fr") is accepted and translated to its MARC equivalent; an unrecognized 2-letter code is rejected rather than silently ignored. The equivalent in-query form is language:eng. | |
| publisher | No | Filter by publisher name. Partial names work (e.g., "Penguin"). | |
| include_availability | No | Include live reading availability from Internet Archive (borrow/read status). Adds ~200ms latency. Use when the user needs to know if they can read the book online. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| total | No | Total matching works across all pages. |
| works | No | Matching works, up to limit. |
| notice | No | Guidance when the page is empty or a requested page limit was reduced to 100. Absent when neither applies. |
| offset | No | Zero-based offset of the first returned result. |
| queryEcho | No | The effective search criteria as the server interpreted them — query string plus any active field filters. Absent when only a bare query is used. |
| totalCount | No | Total matching works across all pages — the upstream match count, reported even when this page is empty because offset ran past the end. |
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 genuinely non-obvious context beyond that: results are work-level (not edition-level) and include edition counts, cover IDs, and reading availability, which prevents an agent from misreading the result shape. It omits any mention of pagination limits or the ~200ms availability cost (that only lives in the schema), so it is not fully self-sufficient.
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?
Three tightly packed sentences with no waste: purpose and scope first, then invocation modes, then result granularity and the drill-down sibling. Everything an agent needs is front-loaded.
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 11 parameters, full schema coverage, and an output schema, the description does enough: it establishes work-level granularity, query-vs-filter usage, and the next step. The remaining gap is that it never positions itself against openlibrary_search_inside, leaving a real ambiguity for an agent deciding between metadata search and full-text-in-book search.
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 the schema already documents every parameter in detail — including Solr field prefixes, sort enum meanings, and the MARC language code rules — and the description largely restates that list ("title, author, subject, publisher, ISBN, language"). It adds the useful query-vs-filters dichotomy but no syntax or format detail the schema lacks, so baseline 3 is correct.
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 ("Full-text book search across Open Library works") and immediately scopes the result granularity to work-level records. It is clearly differentiated from siblings search_authors and search_inside by naming the books/works domain and by explicitly pointing to openlibrary_get_editions for drill-down.
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 concrete invocation guidance: "Use query for general search or combine specific field filters," plus the follow-up routing to openlibrary_get_editions once a work is found. It stops short of saying when NOT to use this tool — notably it never contrasts with openlibrary_search_inside, the sibling that searches inside book text, which is the most likely confusion point.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
openlibrary_search_insideSearch Inside BooksARead-onlyInspect
Search the full text of books scanned by the Internet Archive — the "which book contains this passage?" lookup that the metadata tools cannot answer. Quote a phrase for an exact-phrase match; bare terms match anywhere in the text. Each result is an Internet Archive item with the matching passages as snippets, plus a relevance score. The full-text index is far slower than the metadata endpoints, and a search usually takes 10–30 seconds. Use it when the passage is the question, and use openlibrary_search_books to search by title, author, or subject. Results key on Internet Archive items rather than Open Library works: chain the returned ia_identifier to archive.org, or match it against the ia_identifiers on openlibrary_search_books results to reach the catalogue record.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max matching items to return. Each carries its own snippets, so higher values grow the response quickly — prefer 10–20. | |
| query | Yes | Text to find inside scanned books. Wrap in double quotes for an exact-phrase match (e.g., "the spice must flow"); unquoted terms match independently and return far broader results. | |
| offset | No | Zero-based offset for pagination. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| total | No | Total matching Internet Archive items across all pages. |
| notice | No | Guidance for an empty page or a requested limit above the page ceiling. Absent when neither applies. |
| offset | No | Zero-based offset of the first returned match. |
| matches | No | Matching items, up to limit, ordered by relevance. |
| totalCount | No | Total matching items across all pages — the upstream match count, reported even when this page is empty because offset ran past the end. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover readOnly/openWorld; the description adds the operationally critical 10–30 second latency warning and explains that results key on Internet Archive items rather than Open Library works. It also describes the result payload (IA item + passage snippets + relevance score), which is far beyond what annotations provide.
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?
Front-loaded with the core purpose and the alternative, and every sentence carries information (latency, result shape, chaining). It runs slightly long at five sentences with some overlap between the description and the parameter docs, 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?
Covers purpose, timing expectations, result format, pagination-adjacent behavior, and how to bridge IA identifiers to catalogue records. With an output schema present, return-value detail is not required, yet the agent still knows how to act on results.
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, and the description repeats the quoting semantics already documented in the query param. It earns extra credit for advising that each item carries its own snippets so limit should stay modest, which reinforces the schema's intent.
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 (full-text search of Internet Archive scanned books) and explicitly frames it as the "which book contains this passage?" lookup that metadata tools cannot answer. It is immediately distinguishable from openlibrary_search_books and the get_* 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?
Explicit routing rule: "Use it when the passage is the question, and use openlibrary_search_books to search by title, author, or subject." It also gives an in-tool heuristic (quote for exact phrase, bare terms match anywhere).
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.
9 tool updates
- Changed
openlibrary_get_author_works3 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max works to return."New value: +"Max works to return; values above 100 apply 100 when limit clamping is enabled." - changed
Input schema / properties / limit / maximumPrevious value: -100New value: +9007199254740991 - changed
Output schema / properties / notice / descriptionPrevious value: -"Set when the requested author ID was merged into a different canonical ID."New value: +"Guidance for a merged author ID or a requested limit above the page ceiling."
- Changed
openlibrary_get_cover_url2 fields changed- changed
Output schema / properties / note / descriptionPrevious value: -"Reminder that the URL always returns HTTP 200; a placeholder GIF is served when no cover exists."New value: +"Reminder that the image is unverified and a missing cover may return a placeholder." - changed
Output schema / properties / url / descriptionPrevious value: -"Direct HTTPS URL to the cover image. The Covers API returns HTTP 200 for all requests — a 1×1 placeholder GIF is returned when no cover exists for the identifier."New value: +"Direct HTTPS URL to the cover image; not fetched or verified by this tool."
- Changed
openlibrary_get_edition9 fields changed- changed
Input schema / properties / identifiers / descriptionPrevious value: -"Identifiers to resolve, 1–50, all of the type named by id_type. Resolved editions come back in request order."New value: +"Identifiers to resolve, 1–1000 raw entries, all of the type named by id_type. Exact duplicate strings collapse in first-occurrence order; the first 50 distinct entries are processed, including malformed entries, and remaining strings are returned in unprocessed." - changed
Input schema / properties / identifiers / maxItemsPrevious value: -50New value: +1000 - changed
Output schema / anyOfPrevious value: -[ - { - "not": { - "required": [ - "error" - ] - }, - "required": [ - "editions", - "unresolved" - ] - }, - { - "required": [ - "error" - ] - } -]New value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "unprocessed", + "editions", + "unresolved" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / editions / items / properties / edition_nameAdded value: +{ + "description": "Cataloged edition or printing statement, preserved verbatim. Absent when not recorded.", + "type": "string" +} - changed
Output schema / properties / editions / items / properties / language / descriptionPrevious value: -"3-letter ISO language code (e.g., \"eng\"). Absent when not recorded."New value: +"First cataloged language code (e.g., \"eng\"). Absent when not recorded; languages contains the complete cataloged list." - added
Output schema / properties / editions / items / properties / languagesAdded value: +{ + "description": "All cataloged language codes in upstream order. Absent when no languages are recorded.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / editions / items / properties / physical_formatAdded value: +{ + "description": "Cataloged physical format or binding, preserved verbatim. Absent when not recorded.", + "type": "string" +} - changed
Output schema / properties / notice / descriptionPrevious value: -"Present when author lookups for some editions failed or were skipped: names those editions, whose authors are missing or shown by author ID. Absent when every lookup completed."New value: +"Present when the identifier batch was shortened or author lookups failed or were skipped; includes all applicable guidance." - added
Output schema / properties / unprocessedAdded value: +{ + "description": "Remaining distinct identifiers in input order, preserved verbatim for another call. Empty when the entire batch was processed.", + "items": { + "type": "string" + }, + "type": "array" +}
- Changed
openlibrary_get_editions5 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max editions to return. Prefer 10–20 for exploration."New value: +"Max editions to return; values above 100 apply 100 when limit clamping is enabled. Prefer 10–20 for exploration." - changed
Input schema / properties / limit / maximumPrevious value: -100New value: +9007199254740991 - added
Output schema / properties / editions / items / properties / edition_nameAdded value: +{ + "description": "Cataloged edition or printing statement, preserved verbatim. Absent when not recorded.", + "type": "string" +} - added
Output schema / properties / editions / items / properties / physical_formatAdded value: +{ + "description": "Cataloged physical format or binding, preserved verbatim. Absent when not recorded.", + "type": "string" +} - changed
Output schema / properties / notice / descriptionPrevious value: -"Set when the requested work ID was merged into a different canonical ID."New value: +"Guidance for a merged work ID or a requested limit above the page ceiling."
- Changed
openlibrary_get_subject5 fields changed- changed
Input schema / properties / limit / maximumPrevious value: -100New value: +9007199254740991 - changed
Input schema / properties / subject / descriptionPrevious value: -"Subject name. Normalized before lookup — lowercased with spaces converted to underscores (e.g., \"Science Fiction\" → \"science_fiction\") — so varying case or spacing does not change the result."New value: +"Subject name. Normalized before lookup — trimmed, lowercased, and internal whitespace converted to underscores (e.g., \" Science Fiction \" → \"science_fiction\") — so varying case or surrounding whitespace does not change the result." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode."New value: +"Machine-readable failure mode. Declared by this tool: `invalid_subject`: The subject is empty after trimming whitespace. Other values are possible when a failure originates below the handler." - added
Output schema / properties / error / properties / data / properties / reason / examplesAdded value: +[ + "invalid_subject" +] - changed
Output schema / properties / notice / descriptionPrevious value: -"Recovery guidance when work_count is 0 — echoes the subject and suggests alternatives. Absent when works are found."New value: +"Recovery guidance when work_count is 0, composed with requested/applied page limits and next offset when the limit was reduced to 100. Absent when neither applies."
- Changed
openlibrary_get_work1 field changed- changed
Output schema / properties / notice / descriptionPrevious value: -"Set when the requested work ID was merged into a different canonical ID, and when the text output caps a long subject list (naming the omitted count and the complete array in structuredContent). Absent when neither applies."New value: +"Set when the requested work ID was merged into a different canonical ID. Absent otherwise."
- Changed
openlibrary_search_authors3 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Max results to return."New value: +"Max results to return; values above 100 apply 100 when limit clamping is enabled." - changed
Input schema / properties / limit / maximumPrevious value: -100New value: +9007199254740991 - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when the page is empty (how to vary a name that matched nothing, or which offset to retry when offset ran past the end) or when the text output capped a per-author list. Absent when neither applies."New value: +"Guidance for an empty page or a requested limit above the page ceiling. Absent when neither applies."
- Changed
openlibrary_search_books7 fields changed- changed
Input schema / properties / limit / maximumPrevious value: -100New value: +9007199254740991 - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `unknown_language_code`: A 2-letter language value has no MARC equivalent, so no filter could be applied. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `invalid_search_query`: Open Library rejects the search query with HTTP 422. `unknown_language_code`: A 2-letter language value has no MARC equivalent, so no filter could be applied. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "unknown_language_code" -]New value: +[ + "invalid_search_query", + "unknown_language_code" +] - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when the page is empty (how to broaden a query that matched nothing, or which offset to retry when offset ran past the end) or when the text output capped a per-work list. Absent when neither applies."New value: +"Guidance when the page is empty or a requested page limit was reduced to 100. Absent when neither applies." - added
Output schema / properties / works / items / properties / matching_editionAdded value: +{ + "additionalProperties": false, + "description": "One provider-ranked edition selected by query syntax and field filters, when supplied. Unfielded terms need not all match this edition; this is not every edition record.", + "properties": { + "edition_id": { + "description": "Provider-selected edition OLID (OL…M). Pass to openlibrary_get_edition with id_type \"olid\".", + "type": "string" + }, + "languages": { + "description": "Selected edition language codes, when supplied.", + "items": { + "type": "string" + }, + "type": "array" + }, + "publishers": { + "description": "Selected edition publisher names, when supplied.", + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "description": "Selected edition title, when supplied.", + "type": "string" + } + }, + "required": [ + "edition_id" + ], + "type": "object" +} - added
Output schema / properties / works / items / properties / matching_edition_countAdded value: +{ + "description": "Provider-reported matching-edition count for this search, when supplied. Distinct from the work total edition_count; may be present without a selected edition.", + "type": "number" +} - changed
Output schema / properties / works / items / properties / subjects / descriptionPrevious value: -"Every subject tag the search index returned for this work. The text output caps the rendered list; this array is complete. Absent when no subjects are tagged. For the work record's own curated subject lists (places, times, people), use openlibrary_get_work."New value: +"Every subject tag the search index returned for this work. Absent when no subjects are tagged. For the work record's own curated subject lists (places, times, people), use openlibrary_get_work."
- Changed
openlibrary_search_inside3 fields changed- changed
Input schema / properties / limit / maximumPrevious value: -100New value: +9007199254740991 - changed
Output schema / properties / matches / items / properties / snippets / descriptionPrevious value: -"Passages containing the match, with the upstream highlight markers removed. The text output caps how many are rendered per item; this array is complete."New value: +"Every passage containing the match, with the upstream highlight markers removed." - changed
Output schema / properties / notice / descriptionPrevious value: -"Guidance when the page is empty (how to broaden a query that matched nothing, or which offset to retry when offset ran past the end) or when the text output capped a per-item snippet list. Absent when neither applies."New value: +"Guidance for an empty page or a requested limit above the page ceiling. Absent when neither applies."
9 tool updates
- Changed
openlibrary_get_author1 field changed- changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: Author ID does not exist on Open Library. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: Author ID does not exist on Open Library, names a record that is not an author (a work or edition OLID), or redirects to no reachable author. Other values are possible when a failure originates below the handler."
- Changed
openlibrary_get_author_works3 fields changed- changed
Output schema / anyOfPrevious value: -[ - { - "not": { - "required": [ - "error" - ] - }, - "required": [ - "total", - "author_id", - "works" - ] - }, - { - "required": [ - "error" - ] - } -]New value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "total", + "offset", + "author_id", + "works" + ] + }, + { + "required": [ + "error" + ] + } +] - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: Author ID does not exist on Open Library. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: Author ID does not exist on Open Library, names a record that is not an author (a work or edition OLID), or redirects to no reachable author. Other values are possible when a failure originates below the handler." - added
Output schema / properties / offsetAdded value: +{ + "description": "Zero-based offset of the first returned result — echoes the requested offset, so an empty page still records the offset that produced it.", + "type": "number" +}
- Changed
openlibrary_get_cover_url1 field changed- changed
Input schema / properties / identifier / descriptionPrevious value: -"The identifier value, validated against id_type before the URL is built. For \"id\": a numeric cover or photo ID from work/edition/author data. For \"isbn\": 10 or 13 digits, hyphens optional. For \"olid\": an edition OLID (OL…M) for target \"book\", an author OLID (OL…A) for target \"author\"."New value: +"The identifier value, validated against id_type before the URL is built. For \"id\": a numeric cover or photo ID from work/edition/author data. For \"isbn\": 10 or 13 digits, hyphens optional — an ISBN-10 may end in an X check digit (e.g., 080442957X). For \"olid\": an edition OLID (OL…M) for target \"book\", an author OLID (OL…A) for target \"author\"."
- Changed
openlibrary_get_edition5 fields changed- changed
Input schema / properties / identifiers / items / descriptionPrevious value: -"One identifier value. For ISBN: 10 or 13 digits, hyphens optional. For OCLC: numeric string. For LCCN: string as-is. For OLID: Open Library edition ID (e.g., OL7353617M)."New value: +"One identifier value. For ISBN: 10 or 13 digits, hyphens optional — an ISBN-10 may end in an X check digit (e.g., 080442957X). For OCLC: numeric string. For LCCN: string as-is. For OLID: Open Library edition ID (e.g., OL7353617M)." - changed
Output schema / properties / editions / items / properties / authors / descriptionPrevious value: -"Authors credited for this edition. Empty only when neither the edition nor its parent work records an author."New value: +"Authors credited for this edition. Empty when neither the edition nor its parent work records an author, or when the lookup of the parent work failed or was skipped — the notice names those editions." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: No identifier in the batch resolved to an edition. `invalid_identifier`: Every identifier in the batch is malformed for the specified id_type. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: No identifier in the batch resolved to an edition. `invalid_identifier`: Every identifier in the batch is malformed for the specified id_type. `upstream_unavailable`: Open Library's batch edition lookup answered with an HTTP error status other than 429, or with an HTML page instead of JSON. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "not_found", - "invalid_identifier" -]New value: +[ + "not_found", + "invalid_identifier", + "upstream_unavailable" +] - added
Output schema / properties / noticeAdded value: +{ + "description": "Present when author lookups for some editions failed or were skipped: names those editions, whose authors are missing or shown by author ID. Absent when every lookup completed.", + "type": "string" +}
- Changed
openlibrary_get_editions8 fields changed- changed
Input schema / properties / work_id / descriptionPrevious value: -"Open Library Work ID (OL…W). A leading \"/works/\" prefix is stripped if provided."New value: +"Open Library Work ID. Format: OL…W (e.g., \"OL45804W\"), optionally prefixed \"/works/\". Not an ISBN — resolve an ISBN to its work with openlibrary_get_edition (id_type \"isbn\")." - added
Input schema / properties / work_id / patternAdded value: +"^(?:\\/works\\/)?OL\\d+W$" - changed
Output schema / anyOfPrevious value: -[ - { - "not": { - "required": [ - "error" - ] - }, - "required": [ - "total", - "work_id", - "editions" - ] - }, - { - "required": [ - "error" - ] - } -]New value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "total", + "offset", + "work_id", + "editions" + ] + }, + { + "required": [ + "error" + ] + } +] - changed
Output schema / properties / editions / items / properties / work_id / descriptionPrevious value: -"Parent Work ID. Usually matches the requested work_id."New value: +"Parent Work ID. Usually matches the top-level work_id." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: Work ID does not exist on Open Library. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: Work ID does not exist on Open Library, or it redirects to no reachable work. Other values are possible when a failure originates below the handler." - added
Output schema / properties / noticeAdded value: +{ + "description": "Set when the requested work ID was merged into a different canonical ID.", + "type": "string" +} - added
Output schema / properties / offsetAdded value: +{ + "description": "Zero-based offset of the first returned result — echoes the requested offset, so an empty page still records the offset that produced it.", + "type": "number" +} - changed
Output schema / properties / work_id / descriptionPrevious value: -"Open Library Work ID."New value: +"Canonical Open Library Work ID the editions were found under — differs from the requested work_id when that ID was merged into this work."
- Changed
openlibrary_get_subject2 fields changed- changed
Output schema / anyOfPrevious value: -[ - { - "not": { - "required": [ - "error" - ] - }, - "required": [ - "subject_name", - "subject_key", - "work_count", - "works" - ] - }, - { - "required": [ - "error" - ] - } -]New value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "subject_name", + "subject_key", + "work_count", + "offset", + "works" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / offsetAdded value: +{ + "description": "Zero-based offset of the first returned result — echoes the requested offset, so an empty page still records the offset that produced it.", + "type": "number" +}
- Changed
openlibrary_get_work5 fields changed- changed
Input schema / properties / work_id / descriptionPrevious value: -"Open Library Work ID. Format: OL…W (e.g., \"OL45804W\"). A leading \"/works/\" prefix is stripped if provided."New value: +"Open Library Work ID. Format: OL…W (e.g., \"OL45804W\"), optionally prefixed \"/works/\". Not an ISBN — resolve an ISBN to its work with openlibrary_get_edition (id_type \"isbn\")." - added
Input schema / properties / work_id / patternAdded value: +"^(?:\\/works\\/)?OL\\d+W$" - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `not_found`: Work ID does not exist on Open Library. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `not_found`: Work ID does not exist on Open Library, or it redirects to no reachable work. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / notice / descriptionPrevious value: -"Disclosure when the text output caps a long list — names the omitted count and points to the complete array in structuredContent. Absent when nothing was capped."New value: +"Set when the requested work ID was merged into a different canonical ID, and when the text output caps a long subject list (naming the omitted count and the complete array in structuredContent). Absent when neither applies." - changed
Output schema / properties / work_id / descriptionPrevious value: -"Canonical Open Library Work ID (OL…W)."New value: +"Canonical Open Library Work ID (OL…W) — differs from the requested work_id when that ID was merged into this work."
- Changed
openlibrary_search_books2 fields changed- changed
Output schema / properties / works / items / properties / availability / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "available_to_borrow": { - "description": "True when the book can be borrowed.", - "type": "boolean" - }, - "available_to_browse": { - "description": "True when the book can be browsed for free.", - "type": "boolean" - }, - "available_to_waitlist": { - "description": "True when a waitlist is available.", - "type": "boolean" - }, - "is_lendable": { - "description": "True when the book can be lent.", - "type": "boolean" - }, - "is_previewable": { - "description": "True when a limited preview is available.", - "type": "boolean" - }, - "is_readable": { - "description": "True when the book is freely readable online.", - "type": "boolean" - }, - "is_restricted": { - "description": "True when access is restricted.", - "type": "boolean" - }, - "openlibrary_edition": { - "description": "Edition OLID the availability check was resolved against.", - "type": "string" - }, - "status": { - "description": "Availability status string from Internet Archive.", - "type": "string" - } - }, - "required": [ - "status", - "available_to_browse", - "available_to_borrow", - "available_to_waitlist", - "is_readable", - "is_lendable", - "is_previewable", - "is_restricted" - ], - "type": "object" - }, - { - "type": "null" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "available_to_borrow": { + "description": "True when the book can be borrowed. Absent when not reported.", + "type": "boolean" + }, + "available_to_browse": { + "description": "True when the book can be browsed for free. Absent when not reported.", + "type": "boolean" + }, + "available_to_waitlist": { + "description": "True when a waitlist is available. Absent when not reported.", + "type": "boolean" + }, + "is_lendable": { + "description": "True when the book can be lent. Absent when not reported.", + "type": "boolean" + }, + "is_previewable": { + "description": "True when a limited preview is available. Absent when not reported.", + "type": "boolean" + }, + "is_readable": { + "description": "True when the book is freely readable online. Absent when not reported.", + "type": "boolean" + }, + "is_restricted": { + "description": "True when access is restricted. Absent when not reported.", + "type": "boolean" + }, + "openlibrary_edition": { + "description": "Edition OLID the availability check was resolved against. Absent when not reported.", + "type": "string" + }, + "status": { + "description": "Availability status from Internet Archive, e.g. \"open\" (freely readable), \"borrow_available\", \"borrow_unavailable\", \"private\", or \"error\" (the lending lookup failed, so no flags accompany it). \"unknown\" when Open Library sent no status.", + "type": "string" + } + }, + "required": [ + "status" + ], + "type": "object" + }, + { + "type": "null" + } +] - changed
Output schema / properties / works / items / properties / availability / descriptionPrevious value: -"Live reading availability from Internet Archive. Present when include_availability is true and the work has an Internet Archive item. Null when include_availability is true but no IA item exists."New value: +"Live reading availability from Internet Archive, present when include_availability is true. Open Library leaves flags out for some works — an absent flag is unknown, not false. Null means no availability was returned for the work: always so without an Internet Archive item, and sometimes so for a work that has one."
- Changed
openlibrary_search_inside2 fields changed- changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode."New value: +"Machine-readable failure mode. Declared by this tool: `upstream_unavailable`: Open Library's full-text search answered HTTP 200 without a result set — no hits object carrying a total. Other values are possible when a failure originates below the handler." - added
Output schema / properties / error / properties / data / properties / reason / examplesAdded value: +[ + "upstream_unavailable" +]
10 tool updates
- Changed
openlibrary_get_author6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "author_id", + "name", + "photo_ids", + "remote_ids" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `not_found`: Author ID does not exist on Open Library. Other values are possible when a failure originates below the handler.", + "examples": [ + "not_found" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "author_id", - "name", - "photo_ids", - "remote_ids" -]
- Changed
openlibrary_get_author_works6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "total", + "author_id", + "works" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `not_found`: Author ID does not exist on Open Library. Other values are possible when a failure originates below the handler.", + "examples": [ + "not_found" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "total", - "author_id", - "works" -]
- Changed
openlibrary_get_cover_url6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "url", + "note" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `invalid_identifier`: The identifier contains path separators, \"..\", or control characters, or does not match the format its id_type expects. `invalid_target`: The id_type is not valid for the target — an author photo cannot be resolved by ISBN. Other values are possible when a failure originates below the handler.", + "examples": [ + "invalid_identifier", + "invalid_target" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "url", - "note" -]
- Changed
openlibrary_get_edition6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "editions", + "unresolved" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `not_found`: No identifier in the batch resolved to an edition. `invalid_identifier`: Every identifier in the batch is malformed for the specified id_type. Other values are possible when a failure originates below the handler.", + "examples": [ + "not_found", + "invalid_identifier" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "editions", - "unresolved" -]
- Changed
openlibrary_get_editions6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "total", + "work_id", + "editions" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `not_found`: Work ID does not exist on Open Library. Other values are possible when a failure originates below the handler.", + "examples": [ + "not_found" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "total", - "work_id", - "editions" -]
- Changed
openlibrary_get_subject6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "subject_name", + "subject_key", + "work_count", + "works" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode.", + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "subject_name", - "subject_key", - "work_count", - "works" -]
- Changed
openlibrary_get_work6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "work_id", + "title", + "subjects", + "subject_places", + "subject_times", + "subject_people", + "cover_ids", + "author_ids" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `not_found`: Work ID does not exist on Open Library. Other values are possible when a failure originates below the handler.", + "examples": [ + "not_found" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "work_id", - "title", - "subjects", - "subject_places", - "subject_times", - "subject_people", - "cover_ids", - "author_ids" -]
- Changed
openlibrary_search_authors6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "total", + "offset", + "authors" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode.", + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "total", - "offset", - "authors" -]
- Changed
openlibrary_search_books6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "total", + "offset", + "works" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `unknown_language_code`: A 2-letter language value has no MARC equivalent, so no filter could be applied. Other values are possible when a failure originates below the handler.", + "examples": [ + "unknown_language_code" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "total", - "offset", - "works" -]
- Changed
openlibrary_search_inside6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "total", + "offset", + "matches" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode.", + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "total", - "offset", - "matches" -]
2 tool updates
- Changed
openlibrary_get_author1 field changed- added
Output schema / properties / noticeAdded value: +{ + "description": "Set when the requested author ID was merged into a different canonical ID.", + "type": "string" +}
- Changed
openlibrary_get_author_works1 field changed- added
Output schema / properties / noticeAdded value: +{ + "description": "Set when the requested author ID was merged into a different canonical ID.", + "type": "string" +}
3 tool updates
- Changed
openlibrary_get_cover_url1 field changed- changed
Input schema / properties / identifier / descriptionPrevious value: -"The identifier value. For \"id\": numeric cover ID from work/edition data. For \"isbn\": 10 or 13 digits, hyphens stripped. For \"olid\": edition OLID (OL…M) or author OLID (OL…A) when target is \"author\"."New value: +"The identifier value, validated against id_type before the URL is built. For \"id\": a numeric cover or photo ID from work/edition/author data. For \"isbn\": 10 or 13 digits, hyphens optional. For \"olid\": an edition OLID (OL…M) for target \"book\", an author OLID (OL…A) for target \"author\"."
- Changed
openlibrary_get_edition23 fields changed- changed
Input schema / properties / id_type / descriptionPrevious value: -"Identifier type. \"isbn\" handles both ISBN-10 and ISBN-13. \"olid\" is the native Open Library edition ID (OL…M)."New value: +"Identifier type shared by every entry in identifiers. \"isbn\" handles both ISBN-10 and ISBN-13. \"olid\" is the native Open Library edition ID (OL…M). Mixing types within one call is not supported — issue one call per type." - removed
Input schema / properties / identifierRemoved value: -{ - "description": "The identifier value. For ISBN: 10 or 13 digits, hyphens stripped. For OCLC: numeric string. For LCCN: string as-is. For OLID: Open Library edition ID (e.g., OL7353617M).", - "type": "string" -} - added
Input schema / properties / identifiersAdded value: +{ + "description": "Identifiers to resolve, 1–50, all of the type named by id_type. Resolved editions come back in request order.", + "items": { + "description": "One identifier value. For ISBN: 10 or 13 digits, hyphens optional. For OCLC: numeric string. For LCCN: string as-is. For OLID: Open Library edition ID (e.g., OL7353617M).", + "type": "string" + }, + "maxItems": 50, + "minItems": 1, + "type": "array" +} - changed
Input schema / requiredPrevious value: -[ - "identifier", - "id_type" -]New value: +[ + "identifiers", + "id_type" +] - removed
Output schema / properties / authorsRemoved value: -{ - "description": "Authors credited for this edition. Empty only when neither the edition nor its parent work records an author.", - "items": { - "additionalProperties": false, - "description": "An author contributor for this edition.", - "properties": { - "author_id": { - "description": "Open Library Author ID (OL…A). Use openlibrary_get_author for bio and details.", - "type": "string" - }, - "name": { - "description": "Author display name.", - "type": "string" - }, - "source": { - "description": "\"edition\" = the attribution is recorded on this edition record. \"work\" = the edition records no authors of its own and this credit comes from the parent work, which covers every edition of the same text.", - "enum": [ - "edition", - "work" - ], - "type": "string" - } - }, - "required": [ - "name", - "source" - ], - "type": "object" - }, - "type": "array" -} - removed
Output schema / properties / cover_idsRemoved value: -{ - "description": "Numeric cover IDs for openlibrary_get_cover_url.", - "items": { - "type": "number" - }, - "type": "array" -} - removed
Output schema / properties / descriptionRemoved value: -{ - "description": "Edition description. Absent when not provided.", - "type": "string" -} - removed
Output schema / properties / ebook_urlRemoved value: -{ - "description": "Internet Archive URL for reading/borrowing. Present when an IA item exists.", - "type": "string" -} - removed
Output schema / properties / edition_idRemoved value: -{ - "description": "Open Library Edition ID (OL…M).", - "type": "string" -} - added
Output schema / properties / editionsAdded value: +{ + "description": "Editions that resolved, in request order. Shorter than identifiers when any entry missed.", + "items": { + "additionalProperties": false, + "description": "A resolved edition record.", + "properties": { + "authors": { + "description": "Authors credited for this edition. Empty only when neither the edition nor its parent work records an author.", + "items": { + "additionalProperties": false, + "description": "An author contributor for this edition.", + "properties": { + "author_id": { + "description": "Open Library Author ID (OL…A). Use openlibrary_get_author for bio and details.", + "type": "string" + }, + "name": { + "description": "Author display name.", + "type": "string" + }, + "source": { + "description": "\"edition\" = the attribution is recorded on this edition record. \"work\" = the edition records no authors of its own and this credit comes from the parent work, which covers every edition of the same text.", + "enum": [ + "edition", + "work" + ], + "type": "string" + } + }, + "required": [ + "name", + "source" + ], + "type": "object" + }, + "type": "array" + }, + "cover_ids": { + "description": "Numeric cover IDs for openlibrary_get_cover_url.", + "items": { + "type": "number" + }, + "type": "array" + }, + "description": { + "description": "Edition description. Absent when not provided.", + "type": "string" + }, + "ebook_url": { + "description": "Internet Archive URL for reading/borrowing. Present when an IA item exists.", + "type": "string" + }, + "edition_id": { + "description": "Open Library Edition ID (OL…M).", + "type": "string" + }, + "isbn_10": { + "description": "ISBN-10 identifiers.", + "items": { + "type": "string" + }, + "type": "array" + }, + "isbn_13": { + "description": "ISBN-13 identifiers.", + "items": { + "type": "string" + }, + "type": "array" + }, + "language": { + "description": "3-letter ISO language code (e.g., \"eng\"). Absent when not recorded.", + "type": "string" + }, + "lc_classifications": { + "description": "Library of Congress call numbers (e.g., \"TL685.7 .M366 2008\") — shelving classifications describing the subject, not identifiers. Not usable as a lookup value anywhere.", + "items": { + "type": "string" + }, + "type": "array" + }, + "lccn": { + "description": "Library of Congress Control Numbers (e.g., \"2008478952\") — lookupable identifiers; each one resolves this edition back through this tool with id_type \"lccn\".", + "items": { + "type": "string" + }, + "type": "array" + }, + "oclc": { + "description": "OCLC/WorldCat numbers.", + "items": { + "type": "string" + }, + "type": "array" + }, + "page_count": { + "description": "Page count. Absent when not recorded.", + "type": "number" + }, + "publish_date": { + "description": "Publication date string. Absent when not recorded.", + "type": "string" + }, + "publishers": { + "description": "Publisher names.", + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "description": "Edition title.", + "type": "string" + }, + "work_id": { + "description": "Parent Work ID (OL…W). Use openlibrary_get_work for work-level metadata.", + "type": "string" + } + }, + "required": [ + "edition_id", + "title", + "authors", + "publishers", + "isbn_10", + "isbn_13", + "oclc", + "lccn", + "lc_classifications", + "cover_ids" + ], + "type": "object" + }, + "type": "array" +} - removed
Output schema / properties / isbn_10Removed value: -{ - "description": "ISBN-10 identifiers.", - "items": { - "type": "string" - }, - "type": "array" -} - removed
Output schema / properties / isbn_13Removed value: -{ - "description": "ISBN-13 identifiers.", - "items": { - "type": "string" - }, - "type": "array" -} - removed
Output schema / properties / languageRemoved value: -{ - "description": "3-letter ISO language code (e.g., \"eng\"). Absent when not recorded.", - "type": "string" -} - removed
Output schema / properties / lc_classificationsRemoved value: -{ - "description": "Library of Congress call numbers (e.g., \"TL685.7 .M366 2008\") — shelving classifications describing the subject, not identifiers. Not usable as a lookup value anywhere.", - "items": { - "type": "string" - }, - "type": "array" -} - removed
Output schema / properties / lccnRemoved value: -{ - "description": "Library of Congress Control Numbers (e.g., \"2008478952\") — lookupable identifiers; each one resolves this edition back through this tool with id_type \"lccn\".", - "items": { - "type": "string" - }, - "type": "array" -} - removed
Output schema / properties / oclcRemoved value: -{ - "description": "OCLC/WorldCat numbers.", - "items": { - "type": "string" - }, - "type": "array" -} - removed
Output schema / properties / page_countRemoved value: -{ - "description": "Page count. Absent when not recorded.", - "type": "number" -} - removed
Output schema / properties / publish_dateRemoved value: -{ - "description": "Publication date string. Absent when not recorded.", - "type": "string" -} - removed
Output schema / properties / publishersRemoved value: -{ - "description": "Publisher names.", - "items": { - "type": "string" - }, - "type": "array" -} - removed
Output schema / properties / titleRemoved value: -{ - "description": "Edition title.", - "type": "string" -} - added
Output schema / properties / unresolvedAdded value: +{ + "description": "Identifiers that produced no edition. Empty when every identifier resolved; never overlaps editions.", + "items": { + "additionalProperties": false, + "description": "An identifier that produced no edition.", + "properties": { + "identifier": { + "description": "The identifier as supplied, echoed so it can be matched to the request.", + "type": "string" + }, + "reason": { + "description": "\"invalid_identifier\" = the value cannot be this id_type and was never sent upstream. \"not_found\" = well-formed, but Open Library holds no edition under it.", + "enum": [ + "not_found", + "invalid_identifier" + ], + "type": "string" + } + }, + "required": [ + "identifier", + "reason" + ], + "type": "object" + }, + "type": "array" +} - removed
Output schema / properties / work_idRemoved value: -{ - "description": "Parent Work ID (OL…W). Use openlibrary_get_work for work-level metadata.", - "type": "string" -} - changed
Output schema / requiredPrevious value: -[ - "edition_id", - "title", - "authors", - "publishers", - "isbn_10", - "isbn_13", - "oclc", - "lccn", - "lc_classifications", - "cover_ids" -]New value: +[ + "editions", + "unresolved" +]
- Added
openlibrary_search_inside
3 tool updates
- Changed
openlibrary_get_subject1 field changed- changed
Input schema / properties / subject / descriptionPrevious value: -"Subject name. Spaces are converted to underscores internally (e.g., \"science fiction\" → \"science_fiction\"). Use lowercase for best results."New value: +"Subject name. Normalized before lookup — lowercased with spaces converted to underscores (e.g., \"Science Fiction\" → \"science_fiction\") — so varying case or spacing does not change the result."
- Changed
openlibrary_search_authors4 fields changed- changed
Output schema / properties / notice / descriptionPrevious value: -"Recovery guidance when no authors match — echoes the query and suggests alternatives. Absent when results are found."New value: +"Guidance when the page is empty (how to vary a name that matched nothing, or which offset to retry when offset ran past the end) or when the text output capped a per-author list. Absent when neither applies." - added
Output schema / properties / offsetAdded value: +{ + "description": "Zero-based offset of the first returned result — echoes the requested offset, so an empty page still records the offset that produced it.", + "type": "number" +} - changed
Output schema / properties / totalCount / descriptionPrevious value: -"Total matching authors across all pages. Absent when results are empty."New value: +"Total matching authors across all pages — the upstream match count, reported even when this page is empty because offset ran past the end." - changed
Output schema / requiredPrevious value: -[ - "total", - "authors" -]New value: +[ + "total", + "offset", + "authors" +]
- Changed
openlibrary_search_books3 fields changed- changed
Output schema / properties / notice / descriptionPrevious value: -"Recovery guidance when results are empty — echoes the search criteria and suggests how to broaden. Absent when results are found."New value: +"Guidance when the page is empty (how to broaden a query that matched nothing, or which offset to retry when offset ran past the end) or when the text output capped a per-work list. Absent when neither applies." - changed
Output schema / properties / totalCount / descriptionPrevious value: -"Total matching works across all pages. Absent when results are empty."New value: +"Total matching works across all pages — the upstream match count, reported even when this page is empty because offset ran past the end." - changed
Output schema / properties / works / items / properties / subjects / descriptionPrevious value: -"Up to 5 subject tags. Absent when no subjects are tagged."New value: +"Every subject tag the search index returned for this work. The text output caps the rendered list; this array is complete. Absent when no subjects are tagged. For the work record's own curated subject lists (places, times, people), use openlibrary_get_work."
2 tool updates
- Changed
openlibrary_get_edition6 fields changed- changed
Output schema / properties / authors / descriptionPrevious value: -"Authors of this edition."New value: +"Authors credited for this edition. Empty only when neither the edition nor its parent work records an author." - added
Output schema / properties / authors / items / properties / sourceAdded value: +{ + "description": "\"edition\" = the attribution is recorded on this edition record. \"work\" = the edition records no authors of its own and this credit comes from the parent work, which covers every edition of the same text.", + "enum": [ + "edition", + "work" + ], + "type": "string" +} - changed
Output schema / properties / authors / items / requiredPrevious value: -[ - "name" -]New value: +[ + "name", + "source" +] - added
Output schema / properties / lc_classificationsAdded value: +{ + "description": "Library of Congress call numbers (e.g., \"TL685.7 .M366 2008\") — shelving classifications describing the subject, not identifiers. Not usable as a lookup value anywhere.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Output schema / properties / lccn / descriptionPrevious value: -"Library of Congress Control Numbers."New value: +"Library of Congress Control Numbers (e.g., \"2008478952\") — lookupable identifiers; each one resolves this edition back through this tool with id_type \"lccn\"." - changed
Output schema / requiredPrevious value: -[ - "edition_id", - "title", - "authors", - "publishers", - "isbn_10", - "isbn_13", - "oclc", - "lccn", - "cover_ids" -]New value: +[ + "edition_id", + "title", + "authors", + "publishers", + "isbn_10", + "isbn_13", + "oclc", + "lccn", + "lc_classifications", + "cover_ids" +]
- Changed
openlibrary_search_books4 fields changed- changed
Input schema / properties / language / descriptionPrevious value: -"Two-letter ISO 639-1 language code (e.g., \"en\", \"fr\"). Influences but does not exclude results; use language:fr in query to hard-filter."New value: +"Restrict results to one language. Takes a 3-letter MARC code (e.g., \"eng\", \"fre\", \"ger\", \"chi\") — the same vocabulary openlibrary_get_edition and openlibrary_get_editions return. A 2-letter ISO 639-1 code (e.g., \"en\", \"fr\") is accepted and translated to its MARC equivalent; an unrecognized 2-letter code is rejected rather than silently ignored. The equivalent in-query form is language:eng." - added
Input schema / properties / language / patternAdded value: +"^[A-Za-z]{2,3}$" - changed
Output schema / properties / works / items / properties / ebook_access / descriptionPrevious value: -"\"public\" = freely readable. \"borrowable\" = borrow on Internet Archive. \"printdisabled\" = access for print-disabled users. \"no_ebook\" = no digital version."New value: +"\"public\" = freely readable. \"borrowable\" = borrow on Internet Archive. \"printdisabled\" = access for print-disabled users. \"no_ebook\" = no digital version. \"unclassified\" = a digital copy may exist but its access tier is not recorded." - changed
Output schema / properties / works / items / properties / ebook_access / enumPrevious value: -[ - "no_ebook", - "printdisabled", - "borrowable", - "public" -]New value: +[ + "no_ebook", + "unclassified", + "printdisabled", + "borrowable", + "public" +]
1 tool update
- Changed
openlibrary_get_work1 field changed- added
Output schema / properties / noticeAdded value: +{ + "description": "Disclosure when the text output caps a long list — names the omitted count and points to the complete array in structuredContent. Absent when nothing was capped.", + "type": "string" +}
5 tool updates
- Changed
openlibrary_get_author_works1 field changed- added
Output schema / properties / totalCountAdded value: +{ + "description": "Total works by this author across all pages.", + "type": "number" +}
- Changed
openlibrary_get_editions1 field changed- added
Output schema / properties / totalCountAdded value: +{ + "description": "Total editions for this work across all pages.", + "type": "number" +}
- Changed
openlibrary_get_subject1 field changed- added
Output schema / properties / totalCountAdded value: +{ + "description": "Total works tagged with this subject across all pages.", + "type": "number" +}
- Changed
openlibrary_search_authors1 field changed- added
Output schema / properties / totalCountAdded value: +{ + "description": "Total matching authors across all pages. Absent when results are empty.", + "type": "number" +}
- Changed
openlibrary_search_books1 field changed- added
Output schema / properties / totalCountAdded value: +{ + "description": "Total matching works across all pages. Absent when results are empty.", + "type": "number" +}
Related MCP Connectors
Search books and authors across Open Library, the Internet Archive open catalog.
Search MusicBrainz artists, releases, works, labels; resolve ISRC/ISWC/barcode; fetch cover art.
Books MCP — wraps Open Library API (free, no auth)
Search a catalog of 1.7 million books and find books by mood, vibe, pace or genre. Read-only.
Related MCP Servers
- 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.425 npmMIT
- FlicenseNot gradedqualityAmaintenanceProvides a read-only API over a book catalogue, offering tools to search books, retrieve book details and series, and inspect provenance and source agreement data.-
- AlicenseNot gradedqualityBmaintenanceProvides access to BookBrainz open book metadata, enabling search, lookup, and browsing of works, editions, authors, publishers, and series via natural language or direct tool calls.416 npmMIT
- AlicenseNot gradedqualityDmaintenanceEnables search and reading of Project Gutenberg books with tools for searching by title/author/subject and fetching word-range slices of book text.MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.