gutenberg-mcp-server
Provides tools to search, browse, and retrieve books and full plain texts from Project Gutenberg's library of public-domain works.
Public Hosted Server: https://gutenberg.caseyjhand.com/mcp
Overview
Project Gutenberg's library of 78,000+ public-domain books. Search by title, author, topic, or language, fetch full book metadata, and read supported UTF-8 plain-text and HTML editions in manageable chunks.
Tools
Tool | Description |
| Search the catalog by title, author, topic, translator, language, or author lifespan, with pagination and popularity sorting |
| Fetch complete metadata for a book by ID — authors, translators, editors, full formats map, subjects, copyright status |
| Retrieve a book's plain-text content stripped of license boilerplate, with offset/limit chunking or a |
| Browse the most-downloaded books, optionally filtered by language or topic |
The published gutenberg-guide skill covers deciding whether a book can be read, ruling out search blind spots before calling a book missing, finding openings and chapters past front matter, paging long texts, and ranking editions. Plugin installs include it; MCP clients can discover it through the Skills extension and its skill resource.
Related MCP server: books-catalog
Capability reference
gutenberg_search_books tool
Filters:
query(title/author words),topic,translator,languages(catalog codes exactly as results report them, two or three letters:en, noteng),author_year_start/author_year_end,ids,mime_type, andcopyright("true","false","null"; false means public domain in the USA). Live fallback rejects queries over four words and thetranslatorfilterWith both author-year bounds, one author must meet both. The live fallback checks the bounds separately and says so in a notice
sortispopular(default) orascending/descendingby Gutenberg ID. Up to 32 books per page; usetotalCountandhasMoreto pageEach result carries
is_readable(eligible Text formats; mirror file availability is not guaranteed) andhas_plain_text. The local mirror ignores case and accents in query, translator and topic matching; live matching is upstream-defined. Result rows omit translators;gutenberg_get_bookreports them. Fails withtranslator_requires_mirror,query_requires_mirror,page_out_of_range,catalog_rejected, orcatalog_unavailable
gutenberg_get_book tool
Returns the full
formatsmap (MIME type → download URL) and authors, translators, and editors with birth/death yearsAlso carries
is_readable,has_plain_text,summary,source_notes, anddownload_count(downloads in the last 30 days, not lifetime)Reads the local mirror, then the book's own record on the content mirror. Fails with
not_found,catalog_rejected, orcatalog_unavailable
gutenberg_get_text tool
Reads a book in
offset/limitchunks (defaultlimit20,000, capped at 50,000), with the Gutenberg license header and footer stripped.requestedLimitandappliedLimitreport bothPrefers UTF-8 plain text and falls back to HTML converted to text;
sourceFormatsays which. ReturnstotalChars,length,remainingChars,hasMore, andprovenance(ID, title, license URL). Uselength, notlimit, to compute the nextoffsetfindjumps to a passage instead of paging to it: the chunk starts at the first match at or afteroffset, andmatchreports itsoffset,length, andlaterMatches. Matching ignores letter case and whitespace runs, and treats straight and curly quotes alike; accents and punctuation must matchConverted HTML editions blank every line that holds no visible character, keep each table row on one line with tab-separated cells, and keep a verse line break as one newline
Files over 8 MiB are read as four parallel byte ranges when the mirror supports them; a file over 40 MiB fails with
text_too_largeFails with
not_found,audio_book(media_type "Sound"),no_text_format,offset_out_of_range,passage_not_found,text_file_not_found,text_fetch_rejected,text_too_large,invalid_text_response,text_fetch_failed,catalog_rejected, orcatalog_unavailable
gutenberg_browse_popular tool
Returns up to 32 titles (
limit, default 20), most downloaded in the last 30 days first.requestedLimitandappliedLimitreport the capOptional
languages,topic,mime_type, andcopyrightfilters work as in search.totalInCataloggives the full countOutput reports truncation and carries a
continuationpointing atgutenberg_search_books. Empty results succeed with a notice; fails withcatalog_rejectedorcatalog_unavailable
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
Gutenberg-specific:
Searches and lookups read a local SQLite+FTS5 catalog mirror. When the mirror is cold, searches fall back to Gutendex; a book the mirror lacks is read from its per-book RDF record on the content mirror
Full plain-text retrieval from a Project Gutenberg content mirror, with UTF-8/HTML fallback
Book text is cached per tenant, so later chunk reads skip the fetch
No API key required
Agent-friendly output:
is_readableflags Text records with UTF-8 plain text, or HTML without audio formats; a missing mirror file still returnstext_file_not_foundoffset,length,totalChars,remainingChars, andhasMoresupport reliable sequential readsprovenanceandsourceFormaton every text response cover attribution and fidelity
Getting started
Connect to the hosted instance, no install:
claude mcp add --transport http gutenberg-mcp-server https://gutenberg.caseyjhand.com/mcpOr run it locally:
claude mcp add gutenberg-mcp-server -- npx -y @cyanheads/gutenberg-mcp-serverFor other clients, add this to the MCP config file:
{
"mcpServers": {
"gutenberg-mcp-server": {
"command": "npx",
"args": ["-y", "@cyanheads/gutenberg-mcp-server"]
}
}
}No API key required. For Docker or a source build, see Running the server.
Configuration
Variable | Description | Default |
| Gutendex catalog API base URL, used for search and popularity browse when the local catalog mirror cannot answer. |
|
| Content mirror serving the |
|
| SQLite catalog path; use a persistent volume in containers. |
|
| Cron schedule for in-process catalog refresh. | Unset |
| Transport: |
|
| HTTP session mode: |
|
| Port for HTTP server. |
|
| Auth mode: |
|
| Log level (RFC 5424). |
|
| Directory for log files (Node.js only). |
|
| Storage backend. |
|
| Enable OpenTelemetry instrumentation. |
|
Build the local catalog with npx -y @cyanheads/gutenberg-mcp-server mirror init and check it with mirror verify; mirror refresh re-harvests when the archive has been rebuilt. Each runs under Node or Bun from any directory and prints mirror path: <absolute path> first. From a source checkout, bun run mirror:init, mirror:verify, and mirror:refresh run the built dist/ (build first). The server never harvests on startup, and answers searches from Gutendex and book lookups from each book's RDF record until the first harvest completes. Keep the catalog up to date with mirror refresh on a host scheduler, or set GUTENBERG_MIRROR_REFRESH_CRON.
An existing ./.mirror/gutenberg-catalog.sqlite is read only when GUTENBERG_MIRROR_PATH points at it. A blank or unsubstituted ${…} value for any of these variables reads as unset.
Running the server
Local development
Requires Bun v1.4.4 or higher (or Node.js v24+).
Clone and install:
git clone https://github.com/cyanheads/gutenberg-mcp-server.git cd gutenberg-mcp-server && bun install cp .env.example .env # optional overridesBuild and run:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:httpRun checks and tests:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker run --rm -p 3010:3010 ghcr.io/cyanheads/gutenberg-mcp-server:latestThe image defaults to HTTP transport, stateless session mode, and logs to /var/log/gutenberg-mcp-server. To run it over stdio from an MCP client, use "command": "docker" with "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/gutenberg-mcp-server:latest"]. To build locally, docker build -t gutenberg-mcp-server .; OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing (Gutendex and content-mirror URLs, catalog mirror path and refresh schedule). |
| Tool definitions ( |
| Catalog service — mirror reads, live Gutendex search and browse, per-book RDF lookup. |
| Local SQLite+FTS5 catalog mirror — RDF ingestion, read helpers, and the |
| Full plain-text retrieval, boilerplate stripping, tenant-scoped caching, and chunking. |
| Published agent skill for reading and discovery workflows, also served over MCP. |
| Unit and integration tests mirroring |
Development guide
See CLAUDE.md / AGENTS.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storageRegister new tools via the entry arrays in
src/index.tsWrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testData attribution
Data from Project Gutenberg is in the public domain. Catalog metadata comes from Project Gutenberg's RDF catalog and, for live searches, Gutendex (MIT license).
License
Apache-2.0 — see LICENSE for details.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Gutendex MCP — wraps Gutendex API for Project Gutenberg books (free, no auth)
Books MCP — wraps Open Library API (free, no auth)
Read-only search and retrieval of published books, articles and authors, with public catalog links.
Open Library MCP — Internet Archive's open book metadata
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server that gives AI agents access to the world's public domain library. Search, read, and navigate books and audiobooks from Project Gutenberg and LibriVox.MIT
- AlicenseNot gradedqualityDmaintenanceA well-documented MCP server that exposes a local SQLite catalog of public-domain books through tools like search, get, filter by genre, top-rated, and catalog stats.MIT
- 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
- AlicenseAqualityBmaintenanceThis MCP server enables AI agents to search and retrieve exact, cited passages from a large corpus of public-domain books, including full-text search, book metadata, chapters, quotes, and 'ask book' Q&A. Payments are handled via x402 micropayments on Base.8167 npmMIT