.codex-plugin — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited .codex-plugin (MCP Server) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<div align="center"> <h1>@cyanheads/gutenberg-mcp-server</h1> <p><b>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.</b> <div>4 Tools</div> </p> </div>
<div align="center">
</div>
<div align="center">
</div>
<div align="center">
Public Hosted Server: https://gutenberg.caseyjhand.com/mcp
</div>
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.
| Tool | Description |
|---|---|
gutenberg_search_books | Search the catalog by title, author, topic, language, or author lifespan, with pagination and popularity sorting |
gutenberg_get_book | Fetch complete metadata for a book by ID — authors, translators, editors, full formats map, subjects, copyright status |
gutenberg_get_text | Retrieve a book's plain-text content stripped of license boilerplate, with offset/limit chunking |
gutenberg_browse_popular | 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.
gutenberg_search_books <sub>tool</sub>query (title/author words), topic, languages (ISO 639-1), 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 wordssort is popular (default) or ascending/descending by Gutenberg ID. Up to 32 books per page; use totalCount and hasMore to pageis_readable (readable by gutenberg_get_text) and has_plain_text. Fails with query_requires_mirror, page_out_of_range, or catalog_unavailablegutenberg_get_book <sub>tool</sub>formats map (MIME type → download URL) and authors, translators, and editors with birth/death yearsis_readable, has_plain_text, summary, source_notes, and download_count (downloads in the last 30 days, not lifetime)not_found or catalog_unavailablegutenberg_get_text <sub>tool</sub>offset/limit chunks (default limit 20,000, capped at 50,000), with the Gutenberg license header and footer stripped. requestedLimit and appliedLimit report bothsourceFormat says which. Returns totalChars, length, remainingChars, hasMore, and provenance (ID, title, license URL). Use length, not limit, to compute the next offsetnot_found, audio_book (media_type "Sound"), no_text_format, offset_out_of_range, text_file_not_found, text_fetch_rejected, invalid_text_response, text_fetch_failed, or catalog_unavailablegutenberg_browse_popular <sub>tool</sub>limit, default 20), most downloaded in the last 30 days first. requestedLimit and appliedLimit report the caplanguages, topic, mime_type, and copyright filters work as in search. totalInCatalog gives the full countcontinuation pointing at gutenberg_search_books. Empty results succeed with a notice; fails with catalog_unavailableBuilt 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:
Agent-friendly output:
is_readable on every search and browse result flags editions gutenberg_get_text can readoffset, length, totalChars, remainingChars, and hasMore support reliable sequential readsprovenance and sourceFormat on every text response cover attribution and fidelityConnect 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.
| Variable | Description | Default |
|---|---|---|
GUTENDEX_BASE_URL | Gutendex catalog API base URL. | https://gutendex.com/books/ |
GUTENBERG_TEXT_BASE_URL | Content mirror serving the /cache/epub file tree. | https://gutenberg.pglaf.org |
GUTENBERG_MIRROR_PATH | SQLite catalog path; use a persistent volume in containers. | ./.mirror/gutenberg-catalog.sqlite |
GUTENBERG_MIRROR_REFRESH_CRON | Cron schedule for in-process catalog refresh. | Unset |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_SESSION_MODE | HTTP session mode: auto, stateful, or stateless. Overrides the stateless posture the server declares in createApp(). | stateless |
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 |
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.
Requires Bun v1.4.0 or higher (or Node.js v24+).
git clone https://github.com/cyanheads/gutenberg-mcp-server.git
cd gutenberg-mcp-server && bun install
cp .env.example .env # optional overrides # One-time build
bun run rebuild
# Run the built server
bun run start:stdio
# or
bun run start:http bun run devcheck # Lint, format, typecheck, security
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions against specdocker 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.
| Directory | 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/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/. |
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 are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testData from Project Gutenberg is in the public domain. Catalog metadata sourced from Gutendex (MIT license).
Apache-2.0 — see LICENSE for details.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.