@cyanheads/openlibrary-mcp-server

v0.1.12 pre-1.0

Search books and authors, fetch editions, browse subjects, and resolve cover images from Open Library via MCP. STDIO or Streamable HTTP.

@cyanheads/openlibrary-mcp-server
claude mcp add --transport http openlibrary-mcp-server https://openlibrary.caseyjhand.com/mcp
codex mcp add openlibrary-mcp-server --url https://openlibrary.caseyjhand.com/mcp
{
  "mcpServers": {
    "openlibrary-mcp-server": {
      "url": "https://openlibrary.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http openlibrary-mcp-server https://openlibrary.caseyjhand.com/mcp
{
  "mcpServers": {
    "openlibrary-mcp-server": {
      "command": "bunx",
      "args": [
        "@cyanheads/openlibrary-mcp-server@latest"
      ]
    }
  }
}
{
  "mcpServers": {
    "openlibrary-mcp-server": {
      "type": "http",
      "url": "https://openlibrary.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://openlibrary.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

9

openlibrary_search_books

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "openlibrary_search_books",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "description": "Full-text search query. Supports Solr field prefixes: title:, author:, subject:, publisher:, isbn:, language:. Omit to use the filter parameters instead.",
      "type": "string"
    },
    "title": {
      "description": "Filter by title. Matched against work title and alternative titles.",
      "type": "string"
    },
    "author": {
      "description": "Filter by author name. Partial names work.",
      "type": "string"
    },
    "subject": {
      "description": "Filter by subject tag (e.g., \"science fiction\", \"history\").",
      "type": "string"
    },
    "publisher": {
      "description": "Filter by publisher name. Partial names work (e.g., \"Penguin\").",
      "type": "string"
    },
    "isbn": {
      "description": "Find works that have editions with this ISBN (10 or 13 digits, hyphens ignored).",
      "type": "string"
    },
    "language": {
      "description": "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.",
      "type": "string"
    },
    "sort": {
      "default": "relevance",
      "description": "Sort order. \"relevance\" uses Solr scoring. \"new\"/\"old\" sort by first publish year. \"rating\" by average community rating. \"editions\" by edition count.",
      "type": "string",
      "enum": [
        "relevance",
        "new",
        "old",
        "rating",
        "editions"
      ]
    },
    "limit": {
      "default": 10,
      "description": "Max results to return. Higher values increase response size; prefer 10–20 for exploration.",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "default": 0,
      "description": "Zero-based offset for pagination.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    },
    "include_availability": {
      "default": false,
      "description": "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.",
      "type": "boolean"
    }
  },
  "required": [
    "sort",
    "limit",
    "offset",
    "include_availability"
  ],
  "additionalProperties": false
}
view source ↗

openlibrary_get_work

open-world

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. Note: author names are not included — use openlibrary_get_author or openlibrary_search_books for names.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "openlibrary_get_work",
    "arguments": {
      "work_id": "<work_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "work_id": {
      "type": "string",
      "description": "Open Library Work ID. Format: OL…W (e.g., \"OL45804W\"). A leading \"/works/\" prefix is stripped if provided."
    }
  },
  "required": [
    "work_id"
  ],
  "additionalProperties": false
}
view source ↗

openlibrary_get_editions

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "openlibrary_get_editions",
    "arguments": {
      "work_id": "<work_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "work_id": {
      "type": "string",
      "description": "Open Library Work ID (OL…W). A leading \"/works/\" prefix is stripped if provided."
    },
    "limit": {
      "default": 10,
      "description": "Max editions to return. Prefer 10–20 for exploration.",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "default": 0,
      "description": "Zero-based offset for pagination.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "work_id",
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

openlibrary_get_edition

open-world

Fetch a single edition by identifier: ISBN-10, ISBN-13, OCLC, LCCN, or Open Library Edition ID (OL…M). Returns full edition metadata including authors, publisher, language, all identifier types, and the parent work ID. Use for ISBN lookups — pass id_type "isbn" for both ISBN-10 and ISBN-13.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "openlibrary_get_edition",
    "arguments": {
      "identifier": "<identifier>",
      "id_type": "<id_type>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "identifier": {
      "type": "string",
      "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)."
    },
    "id_type": {
      "type": "string",
      "enum": [
        "isbn",
        "oclc",
        "lccn",
        "olid"
      ],
      "description": "Identifier type. \"isbn\" handles both ISBN-10 and ISBN-13. \"olid\" is the native Open Library edition ID (OL…M)."
    }
  },
  "required": [
    "identifier",
    "id_type"
  ],
  "additionalProperties": false
}
view source ↗

openlibrary_search_authors

open-world

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).

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "openlibrary_search_authors",
    "arguments": {
      "query": "<query>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "Author name search query. Partial names and alternate names work."
    },
    "limit": {
      "default": 10,
      "description": "Max results to return.",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "default": 0,
      "description": "Zero-based offset for pagination.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "query",
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

openlibrary_get_author

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "openlibrary_get_author",
    "arguments": {
      "author_id": "<author_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "author_id": {
      "type": "string",
      "description": "Open Library Author ID. Format: OL…A (e.g., \"OL24638A\"). A leading \"/authors/\" prefix is stripped if provided."
    }
  },
  "required": [
    "author_id"
  ],
  "additionalProperties": false
}
view source ↗

openlibrary_get_author_works

open-world

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.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "openlibrary_get_author_works",
    "arguments": {
      "author_id": "<author_id>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "author_id": {
      "type": "string",
      "description": "Open Library Author ID (OL…A). A leading \"/authors/\" prefix is stripped if provided."
    },
    "limit": {
      "default": 20,
      "description": "Max works to return.",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "default": 0,
      "description": "Zero-based offset for pagination.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "author_id",
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

openlibrary_get_subject

open-world

Browse works by subject. Returns matching works with edition counts and cover IDs, plus the total work count for the subject. Subjects are user-contributed and may be inconsistent ("science fiction", "Science fiction", "SF" are separate tags). Try lowercase forms first.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "openlibrary_get_subject",
    "arguments": {
      "subject": "<subject>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "subject": {
      "type": "string",
      "description": "Subject name. Spaces are converted to underscores internally (e.g., \"science fiction\" → \"science_fiction\"). Use lowercase for best results."
    },
    "limit": {
      "default": 12,
      "description": "Max works to return. Subject pages typically show 12 at a time.",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "default": 0,
      "description": "Zero-based offset for pagination.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "subject",
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

openlibrary_get_cover_url

Resolve a cover image URL for a book or author photo. Returns a direct HTTPS URL in the requested size (S/M/L). The Covers API always returns HTTP 200 — missing covers return a 1×1 placeholder GIF, not a 404. URLs can be embedded in markdown as ![cover](url).

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "openlibrary_get_cover_url",
    "arguments": {
      "identifier": "<identifier>",
      "id_type": "<id_type>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "identifier": {
      "type": "string",
      "description": "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\"."
    },
    "id_type": {
      "type": "string",
      "enum": [
        "id",
        "isbn",
        "olid"
      ],
      "description": "\"id\" is the numeric cover_i / cover ID from search or work results. \"isbn\" and \"olid\" look up the cover from those identifiers."
    },
    "target": {
      "default": "book",
      "description": "\"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).",
      "type": "string",
      "enum": [
        "book",
        "author"
      ]
    },
    "size": {
      "default": "M",
      "description": "Image size. S = small (~45px tall), M = medium (~150px tall), L = large (~400px tall).",
      "type": "string",
      "enum": [
        "S",
        "M",
        "L"
      ]
    }
  },
  "required": [
    "identifier",
    "id_type",
    "target",
    "size"
  ],
  "additionalProperties": false
}
view source ↗

Resources

2

Work detail by Open Library Work ID (OL…W). Provides title, description, subjects, cover IDs, and author IDs as injectable context for a conversation about a specific book.

uri openlibrary://works/{work_id} mime application/json

Author detail by Open Library Author ID (OL…A). Provides name, bio, dates, photo IDs, and linked external identifiers as injectable context for a conversation about a specific author.

uri openlibrary://authors/{author_id} mime application/json