Connects Claude to Project Gutenberg's 75,000+ public domain books through a clean four-tool interface: search by title, author, topic, or language; fetch full metadata including format maps and contributor details; retrieve plain text with offset/limit chunking for context management; and browse by popularity. Built on the Gutendex JSON API with direct plain-text retrieval from Gutenberg's file servers. No API key required. The chunking support is the standout feature here since classic novels routinely hit 500KB to 2MB and you need to read them in manageable pieces. Each response includes provenance data and precise pagination fields so you can walk through long works reliably. Strips license boilerplate automatically and falls back through UTF-8, ASCII, then HTML conversion as needed.
Search, browse, and read 75,000+ public-domain books from Project Gutenberg with full plain-text retrieval and offset/limit chunking via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://gutenberg.caseyjhand.com/mcp
Four tools for searching and reading Project Gutenberg's public-domain library:
| Tool | Description |
|---|---|
gutenberg_search_books | Search the Gutenberg catalog by title, author, topic, language, or author lifespan — returns popularity-ordered results with IDs ready for follow-up calls |
gutenberg_get_book | Fetch complete metadata for a book by ID — full formats map, translators, editors, subjects, bookshelves, copyright status, and the has_plain_text flag |
gutenberg_get_text | Retrieve the plain-text content of a book, stripped of license boilerplate, with offset/limit chunking for context-budget management |
gutenberg_browse_popular | Browse the most-downloaded books, optionally filtered by language or topic — useful as a discovery entry point |
gutenberg_search_booksSearch the Project Gutenberg catalog of 78,000+ public-domain books.
["en"], ["fr", "de"])author_year_start / author_year_endids parametertotalCount to determine total pageshas_plain_text to indicate whether gutenberg_get_text will workgutenberg_get_bookFetch complete metadata for a single Project Gutenberg book.
has_plain_text flag confirms whether a UTF-8 or ASCII plain-text format is availablemedia_type distinguishes readable text books from audio recordingsgutenberg_get_text to confirm text availability and inspect the formats mapgutenberg_get_textRetrieve the plain-text content of a Project Gutenberg book, stripped of license boilerplate.
totalChars, offset, length, and remainingChars for precise paginationlimit — use length (not limit) to compute the next offsetmedia_type "Sound") with a clear recovery hintprovenance field carries the Gutenberg ID, title, and license URL for attributiongutenberg_browse_popularBrowse the most-downloaded Project Gutenberg books.
totalInCatalog provides full context — "top 20 of 60,000"Built on @cyanheads/mcp-ts-core:
none, jwt, oauthin-memory, filesystem, Supabase, Cloudflare KV/R2/D1Project Gutenberg integration:
Agent-friendly output:
has_plain_text flag on every search/browse result so agents can pre-filter before attempting text retrievaloffset, length, totalChars, remainingChars, hasMore on every gutenberg_get_text response for reliable sequential readsprovenance field on every text response for attributionsourceFormat field (text/plain; charset=utf-8, text/plain; charset=us-ascii, text/html) so agents know the fidelity of the textA public instance is available at https://gutenberg.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"gutenberg-mcp-server": {
"type": "streamable-http",
"url": "https://gutenberg.caseyjhand.com/mcp"
}
}
}
No API key required. Add the following to your MCP client configuration file:
{
"mcpServers": {
"gutenberg-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/gutenberg-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"gutenberg-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/gutenberg-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"gutenberg-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/gutenberg-mcp-server:latest"
]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
git clone https://github.com/cyanheads/gutenberg-mcp-server.git
cd gutenberg-mcp-server
bun install
cp .env.example .env
# edit .env if you need to override any defaults
| Variable | Description | Default |
|---|---|---|
GUTENDEX_BASE_URL | Base URL for the Gutendex catalog API. Override for self-hosted instances. | https://gutendex.com/books/ |
GUTENBERG_TEXT_BASE_URL | Base URL for Project Gutenberg file servers. Override for mirrors. | https://www.gutenberg.org |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for HTTP server. | 3010 |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (RFC 5424). | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend. | in-memory |
OTEL_ENABLED | Enable OpenTelemetry instrumentation. | false |
See .env.example for the full list of optional overrides.
Build and run:
# One-time build
bun run rebuild
# Run the built server
bun run start:stdio
# or
bun run start:http
Run 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 build -t gutenberg-mcp-server .
docker run --rm -p 3010:3010 gutenberg-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/gutenberg-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| Path | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools and inits services. |
src/config/server-config.ts | Server-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/gutenberg-text/ | Full plain-text retrieval, boilerplate stripping, in-session caching, and chunking. |
tests/ | Unit and integration tests mirroring src/. |
See CLAUDE.md / AGENTS.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagesrc/index.tsIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.
Data from Project Gutenberg is in the public domain. Catalog metadata sourced from Gutendex (MIT license).
MCP_LOG_LEVELdefault: infoSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_AUTH_MODEdefault: noneAuthentication mode to use: 'none', 'jwt', or 'oauth'.