Gutenberg Mcp Server

io.github.cyanheadsPublished by GitHub account cyanheadsv0.3.2Updated Nov 1, 2026

MCP server for Project Gutenberg: 78,000+ public-domain ebooks with full plain-text retrieval.

VerifiedStreamable HTTPWeb executableWeb Search & ScrapingKnowledge & Memory

Overview

AI-generated overview

MCP server for Project Gutenberg that lets an assistant search, browse and read 78,000+ public-domain ebooks, including full plain text in chunks.

What you can do
  • Search the catalog by title, author, topic, translator, language, author lifespan, IDs, MIME type or copyright status, with paging and popularity sorting
  • Fetch full metadata for a book by ID: authors, translators, editors, subjects, copyright status and the formats map with download URLs
  • Read a book's plain text with the license boilerplate stripped, paged by offset and limit or jumped to a passage with find
  • Browse the most-downloaded titles from the last 30 days, filtered by language, topic, MIME type or copyright
When to use it
Useful when an assistant needs public-domain literature or reference texts: finding books by author or subject, checking editions and translators, or reading and quoting passages from a work without leaving the conversation.
Requirements
Either the hosted HTTP endpoint or a local process via npx (Node.js), Docker, or a source build with Bun 1.4.0+ or Node.js 24+. No API key required. Optional variables cover transport, HTTP host/port/path, auth mode, log level, catalog mirror path and refresh schedule, and upstream catalog and text mirror URLs.
Before you install
Book text is fetched from a third-party content mirror and catalog data from Gutendex, so requests leave your machine unless you point the mirror URLs elsewhere. Book text is cached per tenant. Running the HTTP transport with auth mode none leaves it unauthenticated; set MCP_AUTH_MODE if exposing it. Readability flags do not guarantee the mirror file exists.

Installation

In SourceWeft

  1. Open Gutenberg Mcp Server in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.cyanheads%2Fgutenberg-mcp-server/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "gutenberg": {
      "type": "http",
      "url": "https://gutenberg.caseyjhand.com/mcp"
    }
  }
}

README

@cyanheads/gutenberg-mcp-server

Search, browse, and read 78,000+ public-domain books from Project Gutenberg with full plain-text retrieval and offset/limit chunking via MCP. STDIO or Streamable HTTP.

4 Tools

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

ToolDescription
gutenberg_search_booksSearch the catalog by title, author, topic, translator, language, or author lifespan, with pagination and popularity sorting
gutenberg_get_bookFetch complete metadata for a book by ID — authors, translators, editors, full formats map, subjects, copyright status
gutenberg_get_textRetrieve a book's plain-text content stripped of license boilerplate, with offset/limit chunking or a find jump to a passage
gutenberg_browse_popularBrowse 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.


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, not eng), author_year_start/author_year_end, ids, mime_type, and copyright ("true", "false", "null"; false means public domain in the USA). Live fallback rejects queries over four words and the translator filter
  • With both author-year bounds, one author must meet both. The live fallback checks the bounds separately and says so in a notice
  • sort is popular (default) or ascending/descending by Gutenberg ID. Up to 32 books per page; use totalCount and hasMore to page
  • Each result carries is_readable (eligible Text formats; mirror file availability is not guaranteed) and has_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_book reports them. Fails with translator_requires_mirror, query_requires_mirror, page_out_of_range, or catalog_unavailable

gutenberg_get_book tool

  • Returns the full formats map (MIME type → download URL) and authors, translators, and editors with birth/death years
  • Also carries is_readable, has_plain_text, summary, source_notes, and download_count (downloads in the last 30 days, not lifetime)
  • Fails with not_found or catalog_unavailable

gutenberg_get_text tool

  • Reads a book in offset/limit chunks (default limit 20,000, capped at 50,000), with the Gutenberg license header and footer stripped. requestedLimit and appliedLimit report both
  • Prefers UTF-8 plain text and falls back to HTML converted to text; sourceFormat says which. Returns totalChars, length, remainingChars, hasMore, and provenance (ID, title, license URL). Use length, not limit, to compute the next offset
  • find jumps to a passage instead of paging to it: the chunk starts at the first match at or after offset, and match reports its offset, length, and laterMatches. Matching ignores letter case and whitespace runs, and treats straight and curly quotes alike; accents and punctuation must match
  • Converted HTML editions blank every line that holds no visible character and keep each table row on one line, with tab-separated cells
  • Fails 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, invalid_text_response, text_fetch_failed, or catalog_unavailable

gutenberg_browse_popular tool

  • Returns up to 32 titles (limit, default 20), most downloaded in the last 30 days first. requestedLimit and appliedLimit report the cap
  • Optional languages, topic, mime_type, and copyright filters work as in search. totalInCatalog gives the full count
  • Output reports truncation and carries a continuation pointing at gutenberg_search_books. Empty results succeed with a notice; fails with catalog_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, falling back to Gutendex when the mirror is cold or missing a record
  • 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_readable flags Text records with UTF-8 plain text, or HTML without audio formats; a missing mirror file still returns text_file_not_found
  • offset, length, totalChars, remainingChars, and hasMore support reliable sequential reads
  • provenance and sourceFormat on every text response cover attribution and fidelity

Getting started

Connect to the hosted instance, no install:

sh
claude mcp add --transport http gutenberg-mcp-server https://gutenberg.caseyjhand.com/mcp

Or run it locally:

sh
claude mcp add gutenberg-mcp-server -- npx -y @cyanheads/gutenberg-mcp-server

For other clients, add this to the MCP config file:

json
{  "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

VariableDescriptionDefault
GUTENDEX_BASE_URLGutendex catalog API base URL.https://gutendex.com/books/
GUTENBERG_TEXT_BASE_URLContent mirror serving the /cache/epub file tree.https://gutenberg.pglaf.org
GUTENBERG_MIRROR_PATHSQLite catalog path; use a persistent volume in containers../.mirror/gutenberg-catalog.sqlite
GUTENBERG_MIRROR_REFRESH_CRONCron schedule for in-process catalog refresh.Unset
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_SESSION_MODEHTTP session mode: auto, stateful, or stateless. Overrides the stateless posture the server declares in createApp().stateless
MCP_HTTP_PORTPort for HTTP server.3010
MCP_AUTH_MODEAuth mode: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (RFC 5424).info
LOGS_DIRDirectory for log files (Node.js only).<project-root>/logs
STORAGE_PROVIDER_TYPEStorage backend.in-memory
OTEL_ENABLEDEnable OpenTelemetry instrumentation.false

Build the local catalog with bun run mirror:init and check it with bun run mirror:verify. The server never harvests on startup, and uses Gutendex until the first harvest completes. Keep the catalog up to date with bun run mirror:refresh on a host scheduler, or set GUTENBERG_MIRROR_REFRESH_CRON.


Running the server

Local development

Requires Bun v1.4.0 or higher (or Node.js v24+).

  • Clone and install:

    sh
    git clone https://github.com/cyanheads/gutenberg-mcp-server.gitcd gutenberg-mcp-server && bun installcp .env.example .env   # optional overrides
  • Build and run:

    sh
    # One-time buildbun run rebuild
    # Run the built serverbun run start:stdio# orbun run start:http
  • Run checks and tests:

    sh
    bun run devcheck   # Lint, format, typecheck, securitybun run test       # Vitest test suitebun run lint:mcp   # Validate MCP definitions against spec

Docker

sh
docker run --rm -p 3010:3010 ghcr.io/cyanheads/gutenberg-mcp-server:latest

The 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

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools and inits services.
src/config/server-config.tsServer-specific environment variable parsing (Gutendex and file-server URL overrides).
src/mcp-server/tools/definitions/Tool definitions (*.tool.ts).
src/services/gutendex/Gutendex catalog API client — search and book metadata.
src/services/catalog-mirror/Local SQLite+FTS5 catalog mirror — RDF ingestion and read helpers.
src/services/gutenberg-text/Full plain-text retrieval, boilerplate stripping, tenant-scoped caching, and chunking.
skills/gutenberg-guide/Published agent skill for reading and discovery workflows, also served over MCP.
tests/Unit and integration tests mirroring src/.

Development guide

See CLAUDE.md / AGENTS.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging, ctx.state for tenant-scoped storage
  • Register new tools via the entry arrays in src/index.ts
  • Wrap 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:

sh
bun run devcheckbun run test

Data attribution

Data from Project Gutenberg is in the public domain. Catalog metadata sourced from Gutendex (MIT license).


License

Apache-2.0 — see LICENSE for details.

Source: README.md at commit 906bc14

Tools

4

gutenberg_search_books

Search Gutenberg Books

Search the Project Gutenberg catalog of 78,000+ books. Every query word matches a title or author substring; filter by topic, language, translator, author lifespan, IDs, MIME prefix or copyright status. More than four query words, and the translator filter, require the local mirror. Empty matches succeed with criteria and a notice. Default popularity uses downloads in the last 30 days at the source snapshot. Returns IDs, titles, authors, languages, subjects, counts, and is_readable — use gutenberg_get_book for full metadata.

Parametersidspagesortquerytopiccopyrightlanguagesmime_typetranslatorauthor_year_endauthor_year_start

gutenberg_get_book

Get Gutenberg Book

Fetch complete metadata for a Project Gutenberg book by ID — title, authors (with birth/death years), translators, editors, source bibliographic notes, subjects, bookshelves, languages, copyright status, and the full formats map with download URLs (plain text, HTML, EPUB, cover image, etc.). Use is_readable before gutenberg_get_text; source_notes may identify specific editions.

Parametersidrequired

gutenberg_get_text

Get Gutenberg Book Text

Retrieve the plain-text content of a Project Gutenberg book, stripped of the standard license header and footer. Front matter such as producer credits, the title page, contents, and prefaces stays in the text. For long works — novels routinely run 500KB–2MB — use offset and limit to read in chunks rather than fetching the whole book at once, or pass find to jump to a known passage without paging. The response reports totalChars and remainingChars for reliable pagination. Prefers UTF-8 plain text; falls back to an HTML edition converted to text; refuses audio books (media_type "Sound") with a clear error.

Parametersidrequiredfindlimitoffset

Version history

8
  1. v0.3.2LatestNov 1, 2026
  2. v0.3.1Oct 31, 2026
  3. v0.3.0Oct 29, 2026
  4. v0.2.0Oct 18, 2026
  5. v0.1.11Oct 16, 2026
  6. v0.1.10Oct 9, 2026
  7. v0.1.9Sep 20, 2026
  8. v0.1.8Sep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts