Skip to main content

CI Nightly compliance Ask DeepWiki Maintenance assisted by Hivecommons Hive ACMM L5 Semi-Autonomous AI assisted License: GPL-3.0

📚 goodreads-mcp

A read-only MCP server for Goodreads — built without the Goodreads API, because there hasn't been one since December 2020. Lets an LLM find and research books, ratings, and reviews. Tools ride on RSS feeds, the JSON autocomplete endpoint, the __NEXT_DATA__ blob embedded in book pages, and the AppSync GraphQL backend the Goodreads website itself uses. No login, no cookies, no writes — public data only.

tools

tool source / what it returns
search_books JSON autocomplete endpoint (stable) — book_id, title, author, rating, cover; max_results defaults to 10, but the endpoint returns about 5 matches at most
get_book __NEXT_DATA__ via the .xml page (stable) — details, cover, ratings histogram, every series membership, review-language breakdown (review_language_limit, default 5, max 25)
get_reviews GraphQL — paginated reader reviews (text, rating, likes, date, spoiler flag, permalink); limit default 10, capped at 100; server-side min_rating / max_rating (1–5, min ≤ max) and exclude_spoilers; reports has_more
similar_books GraphQL — paginated "readers also enjoyed" recommendations; limit up to 100
author_books GraphQL — paginated author bibliography, ranked by popularity, from any of their books, plus author_url; limit up to 100
series_books GraphQL — paginated series books with reading-order placement; series_index (zero-based, in get_book's series_memberships order) picks the series; limit up to 100
get_editions GraphQL — paginated editions (format, ISBN, publisher, date); limit up to 100
book_lists GraphQL — paginated Listopia lists a book appears on (title, votes, size); limit up to 100
popular_books GraphQL — most popular books by release year, or a single month (1–12), ranked; limit capped at 50
compare_books get_book for each id (__NEXT_DATA__ via .xml) — ranks 1–10 books by rating with positive/critical share; more than 10 ids is refused; a book that fails comes back as an error entry
get_shelf shelf RSS feed (stable) — books on a public shelf; page starts at 1, about 100 items per page; user_id overrides the configured user
list_shelves best-effort HTML scrape of the public profile page — shelf names; raises LoginRequired for a private profile

Every tool is registered with MCP read-only annotations (read-only, non-destructive, idempotent).

The discovery tools all take a book_id and return results carrying book_id/title/author/rating/url, so an agent can chain them — e.g. similar_books → get_reviews on a recommendation. This is the structured book graph a general web search can't assemble.

The five paginated discovery tools (similar_books, author_books, series_books, get_editions, book_lists) page in batches of 20 and accept a total limit up to 100; popular_books caps limit at 50. Responses include returned and has_more, keeping larger lookups useful without allowing unbounded traffic.

WAF and login note: Goodreads book HTML pages now sit behind an AWS WAF JavaScript challenge (HTTP 202) that plain HTTP clients can't solve. get_book routes around it via the .xml-suffixed page, so it still works without a browser. If Goodreads ever extends the WAF to a path we depend on, the client raises WAFChallenge with a clear message instead of a confusing parse error. The review-list page (/review/list/{uid}) became login-only in Sep 2026; the client raises LoginRequired on a sign-in redirect for the same reason, and list_shelves reads the public profile page instead.

install

With pip:

cd goodreads-mcp
python3.10 -m venv .venv && .venv/bin/pip install -e .

Or with uv, which is also what the Claude Desktop bundle uses:

cd goodreads-mcp
uv sync
uv run goodreads-mcp

Requires Python ≥ 3.10.

Each date-numbered release is also published to PyPI as goodreads-mcp-ai (the goodreads-mcp name there belongs to an unrelated project) and listed on the official MCP registry as io.github.Danathar/goodreads-mcp-ai, from server.json. The listing carries a uvx runtime hint; a client that follows it runs uvx goodreads-mcp-ai, which you can also run yourself.

config (optional)

No login or cookies — everything is public data. The only setting is your numeric user_id, the default for the shelf tools. It's the number in goodreads.com/user/show/<ID>-yourname; you can also pass user_id to each shelf tool per call.

mkdir -p ~/.config/goodreads-mcp
cat > ~/.config/goodreads-mcp/config.json << 'EOF'
{ "user_id": "12345678" }
EOF

Env var GOODREADS_USER_ID overrides the file. A config file that can't be read, isn't valid JSON, isn't a JSON object, or has a non-string user_id is ignored with a warning on stderr; the server still starts.

Claude Desktop config

Bundle. Each release carries a goodreads-mcp.mcpb. Releases come out monthly when the server itself changed, numbered by date (2026.10.0, 2026.10.1, 2026.11.0); 0.1.1 was the last of the old numbering, and every date-numbered release is newer than it. See CONTRIBUTING.md for how one is cut. Open the .mcpb in Claude Desktop to install. The bundle ships no dependencies — the manifest launches the server with uv run, and the host resolves pyproject.toml into a private environment on first launch — so one bundle runs on macOS, Windows and Linux with any Python ≥ 3.10. The bundle's optional "Goodreads User ID" setting (user_config.goodreads_user_id) is passed to the server as GOODREADS_USER_ID.

Manual. Add the server to claude_desktop_config.json — on macOS ~/Library/Application Support/Claude/claude_desktop_config.json, on Windows %APPDATA%\Claude\claude_desktop_config.json; in any version, Settings → Developer → Edit Config opens it:

{
  "mcpServers": {
    "goodreads": {
      "command": "/path/to/goodreads-mcp/.venv/bin/goodreads-mcp"
    }
  }
}

Or for development, mcp dev goodreads_mcp/server.py gives you the Inspector UI to poke each tool.

first-run verification

The endpoints are unofficial, so verify in this order:

  1. search_books("project hail mary") — should just work
  2. get_book("54493401") — confirms the .xml/WAF workaround; check the histogram is populated
  3. get_reviews("54493401") — should return real review text
  4. get_shelf("to-read") — checks your user_id + RSS
  5. list_shelves() — best-effort shelf-name scrape

For an end-to-end example that chains the tools, see prompts/research-a-book.md.

tests

.venv/bin/pip install -e ".[test]"     # pytest + pytest-cov
.venv/bin/pytest                       # offline parser/unit tests
GOODREADS_LIVE=1 .venv/bin/pytest      # + live network smoke tests

The offline suite runs on fixtures; CI runs it with pytest-cov and enforces a coverage floor (--cov-fail-under in ci.yml). The live smoke tests are in tests/e2e/test_smoke_live.py and skip unless GOODREADS_LIVE=1 is set. The nightly compliance run runs the live suite against the real endpoints every night, so upstream drift shows up within a day.

documentation

about this project

license

This fork is licensed under the GNU General Public License v3.0, version 3 only (GPL-3.0-only) — no automatic upgrade to later versions.

It incorporates code from shreeyachand/goodreads-mcp, Copyright (c) 2026 Shreeya Chand, released under the MIT License. That code remains under MIT; its licence text and copyright notice are preserved in LICENSE.MIT as the MIT licence requires. The combined work — upstream code together with this fork's changes — is distributed under GPL-3.0.

Release files for goodreads-mcp-ai 2026.9.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for goodreads-mcp-ai 2026.9.0
File Size Uploaded
goodreads_mcp_ai-2026.9.0.tar.gz 35.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for goodreads-mcp-ai 2026.9.0
File Interpreter ABI Platform
goodreads_mcp_ai-2026.9.0-py3-none-any.whl Python 3 none any Details

Total release size: 72.9 kB

Release files / goodreads_mcp_ai-2026.9.0.tar.gz

Download URL goodreads_mcp_ai-2026.9.0.tar.gz
Size 35.1 kB
Tags Source
SHA-256 checksum
How to use checksums
8fc48b1b4c357b6decf68712ff7bed69f06cbb6681a378861bae7f1774baebdb
BLAKE2b-256 checksum
How to use checksums
3129f062fd12157bc507a7e95f87a290f4153ad099e5aeadce7197c6bf3ef5bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.

Transparency log

Release files / goodreads_mcp_ai-2026.9.0-py3-none-any.whl

Download URL goodreads_mcp_ai-2026.9.0-py3-none-any.whl
Size 37.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
933b8c0f371ba2bbd8ff9ea859aad8c1a6e2a77d6d153e83326563967d701110
BLAKE2b-256 checksum
How to use checksums
1813f9fb0bc26ddb626932e9b2f6f24009d02b532d7bc9c58fcc21e8178fb587
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2026.9.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page