关于 gutenberg-mcp-server
gutenberg-mcp-server 让读者和研究工作流能够搜索并阅读 Project Gutenberg 公版图书目录。它提供书籍元数据,并分块读取支持的文本;目录搜索使用本地镜像,并可回退到 Gutendex。
主要功能
- 01按书名、作者或主题搜索
- 02按语言等字段筛选
- 03获取书籍元数据和格式
- 04按偏移量分块读取文本
- 05浏览热门图书
适用场景
- 01按作者、主题或语言查找图书
- 02获取选定版本的元数据
- 03分块顺序阅读长篇图书
- 04按主题浏览热门书目
MCP 相关
通过四个工具向 MCP 客户端提供 Project Gutenberg 目录搜索、元数据、文本读取和热门图书浏览功能。支持 STDIO 或 Streamable HTTP。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://gutenberg.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-gutenberg https://gutenberg.caseyjhand.com/mcp{"mcpServers":{"cyanheads-gutenberg":{"type":"http","url":"https://gutenberg.caseyjhand.com/mcp"}}}在 Cursor 中打开{"servers":{"cyanheads-gutenberg":{"type":"http","url":"https://gutenberg.caseyjhand.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"cyanheads-gutenberg":{"type":"http","url":"https://gutenberg.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-gutenberg":{"serverUrl":"https://gutenberg.caseyjhand.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
4| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| ids | array | 否 | 将结果缩小到指定的 Gutenberg ID。其他筛选条件仍然生效。适用于批量预先获取已知 ID;单个 ID 查询请使用 gutenberg_get_book。 |
| page | integer | 否 | 分页结果的页码(从 1 开始)。每页最多返回 32 本书。使用 totalCount 确定总页数。 |
| sort | enum | 否 | 结果排序方式。"popular"(默认)按源数据快照中最近 30 天的下载量降序排序。"ascending" 和 "descending" 按 Gutenberg ID 排序。popular | ascending | descending |
| query | string | 否 | 用于匹配书名和作者姓名的词语(不区分大小写,以空格分隔)。示例:"dickens expectations" 匹配 Charles Dickens 的《Great Expectations》。 |
| topic | string | 否 | 用于匹配主题和书架的不区分大小写短语。示例:"detective" 会返回 "Detective and Mystery Stories" 书架上的书籍。与 query 分开——topic 搜索分类元数据,而非书名/作者。 |
| languages | array | 否 | 筛选为任意这些两字符 ISO 639-1 语言代码对应的图书。示例:["en"] 表示英语,["fr", "de"] 表示法语或德语。 |
| author_year_end | integer | 否 | 仅包含至少有一位作者在此年份或之前仍在世的图书。示例:author_year_start=1800 且 author_year_end=1899 时,返回作者属于 19 世纪的图书。 |
| author_year_start | integer | 否 | 仅包含至少有一位作者在此年份或之后仍在世的图书(正数 = 公元,负数 = 公元前)。与 author_year_end 组合可指定范围。 |
详细介绍
@cyanheads/gutenberg-mcp-server
通过 MCP 搜索、浏览并阅读 Project Gutenberg 中 78,000+ 本公版书籍,支持完整纯文本检索及基于 offset/limit 的分块读取。支持 STDIO 或 Streamable HTTP。
概览
Project Gutenberg 收录了 78,000+ 本公版书籍。可按书名、作者、主题或语言进行搜索,获取完整的书籍元数据,并分块阅读受支持的 UTF-8 纯文本和 HTML 版本。
工具
| 工具 | 描述 |
|---|---|
gutenberg_search_books | 按书名、作者、主题、语言或作者生卒年份搜索目录,支持分页和按热度排序 |
gutenberg_get_book | 按 ID 获取书籍的完整元数据——作者、译者、编辑、完整格式映射、主题和版权状态 |
gutenberg_get_text | 获取去除许可证声明文本后的纯文本内容,并支持基于 offset/limit 的分块读取 |
gutenberg_browse_popular | 浏览下载量最高的书籍,可选按语言或主题筛选 |
功能参考
gutenberg_search_books 工具
- 筛选条件:
query(书名/作者关键词)、topic、languages(ISO 639-1)、author_year_start/author_year_end、ids、mime_type和copyright("true"、"false"、"null";false 表示在美国属于公版)。实时回退查询不接受超过四个词的查询 sort可设为popular(默认值),或按 Gutenberg ID 以ascending/descending排序。每页最多 32 本书;使用totalCount和hasMore翻页- 每条结果都包含
is_readable(可通过gutenberg_get_text阅读)和has_plain_text。可能返回query_requires_mirror、page_out_of_range或catalog_unavailable错误
gutenberg_get_book 工具
- 返回完整的
formats映射(MIME 类型 → 下载 URL),以及包含出生和去世年份的作者、译者和编辑信息 - 还包含
is_readable、has_plain_text、summary、source_notes和download_count(过去 30 天的下载量,而非累计下载量) - 失败时返回
not_found或catalog_unavailable
gutenberg_get_text 工具
- 以
offset/limit分块读取图书(默认limit为 20,000,上限为 50,000),并剥除 Gutenberg 许可声明的页眉和页脚。requestedLimit和appliedLimit会分别报告请求值和实际值 - 优先使用 UTF-8 纯文本,无法使用时则回退到转换为文本的 HTML;
sourceFormat会说明所用格式。返回totalChars、length、remainingChars、hasMore和provenance(ID、标题、许可 URL)。计算下一个offset时请使用length,而不是limit - 失败时返回
not_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或catalog_unavailable
gutenberg_browse_popular 工具
- 返回最多 32 本图书(
limit默认值为 20),按过去 30 天的下载量从高到低排列。requestedLimit和appliedLimit会报告上限 - 可选的
languages、topic、mime_type和copyright筛选条件与搜索中的相同。totalInCatalog提供目录中的完整条目数 - 输出会报告结果是否经过截断,并包含指向
gutenberg_search_books的continuation。无结果时会成功返回通知;失败时返回catalog_unavailable
功能
基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none / jwt / oauth)、可切换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及结构化日志和可选的 OpenTelemetry 跟踪。
Gutenberg 专属功能:
- 搜索和查询会读取本地 SQLite+FTS5 目录镜像;镜像尚未加载或缺少记录时,会回退到 Gutendex
- 从 Project Gutenberg 内容镜像获取完整纯文本,并在 UTF-8/HTML 之间回退
- 图书文本按租户缓存,因此后续分块读取无需再次获取
- 无需 API 密钥
便于 Agent 使用的输出:
- 每条搜索和浏览结果中的
is_readable会标记gutenberg_get_text可读取的版本 offset、length、totalChars、remainingChars和hasMore支持可靠的顺序读取- 每个文本响应中的
provenance和sourceFormat都会提供来源归属和保真度信息
开始使用
公共托管实例
可使用公共实例 https://gutenberg.caseyjhand.com/mcp,无需安装。通过 Streamable HTTP 将任何 MCP 客户端指向该实例:
{
"mcpServers": {
"gutenberg-mcp-server": {
"type": "streamable-http",
"url": "https://gutenberg.caseyjhand.com/mcp"
}
}
}
自托管 / 本地部署
无需 API 密钥。将以下内容添加到 MCP 客户端配置文件中:
{
"mcpServers": {
"gutenberg-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/gutenberg-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
也可以使用 npx(无需 Bun):
{
"mcpServers": {
"gutenberg-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/gutenberg-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
也可以使用 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"
]
}
}
}
若要使用 Streamable HTTP,请设置传输方式并启动服务:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
前置条件
- Bun v1.4.0 或更高版本(或 Node.js v24+)。
- 无需 API 密钥 — Project Gutenberg 数据可免费获取。
安装
- 克隆仓库:
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
配置
| 变量 | 描述 | 默认值 |
|---|---|---|
GUTENDEX_BASE_URL | Gutendex 目录 API 基础 URL。 | https://gutendex.com/books/ |
GUTENBERG_TEXT_BASE_URL | 提供 /cache/epub 文件树的内容镜像。 | https://gutenberg.pglaf.org |
GUTENBERG_MIRROR_PATH | SQLite 目录路径;在容器中请使用持久卷。 | ./.mirror/gutenberg-catalog.sqlite |
GUTENBERG_MIRROR_REFRESH_CRON | 进程内目录刷新的 Cron 计划。 | 未设置 |
MCP_TRANSPORT_TYPE | 传输方式:stdio 或 http。 | stdio |
MCP_SESSION_MODE | HTTP 会话模式:auto、stateful 或 stateless。覆盖服务在 createApp() 中声明的 stateless 状态。 | stateless |
MCP_HTTP_PORT | HTTP 服务端口。 | 3010 |
MCP_AUTH_MODE | 身份验证模式:none、jwt 或 oauth。 | none |
MCP_LOG_LEVEL | 日志级别(RFC 5424)。 | info |
LOGS_DIR | 日志文件目录(仅限 Node.js)。 | <project-root>/logs |
STORAGE_PROVIDER_TYPE | 存储后端。 | in-memory |
OTEL_ENABLED | 启用 OpenTelemetry 插桩。 | false |
使用 bun run mirror:init 构建本地目录,并使用 bun run mirror:verify 检查。服务启动时不会抓取数据,在首次抓取完成前会使用 Gutendex。可通过主机计划任务运行 bun run mirror:refresh 来更新目录,或设置 GUTENBERG_MIRROR_REFRESH_CRON。
运行服务
本地开发
-
构建并运行:
# 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 spec
Docker
docker build -t gutenberg-mcp-server .
docker run --rm -p 3010:3010 gutenberg-mcp-server
Dockerfile 默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/gutenberg-mcp-server。默认会安装 OpenTelemetry 对等依赖项——构建时使用 --build-arg OTEL_ENABLED=false 可省略这些依赖项。
项目结构
| 目录 | 用途 |
|---|---|
src/index.ts | createApp() 入口点——注册工具并初始化服务。 |
src/config/server-config.ts | 服务专用环境变量解析(Gutendex 和文件服务 URL 覆盖项)。 |
src/mcp-server/tools/definitions/ | 工具定义(*.tool.ts)。 |
src/services/gutendex/ | Gutendex 目录 API 客户端——搜索和书籍元数据。 |
src/services/catalog-mirror/ | 本地 SQLite+FTS5 目录镜像——RDF 导入和读取辅助函数。 |
src/services/gutenberg-text/ | 完整纯文本检索、模板内容剥离、租户范围缓存和分块。 |
tests/ | 与 src/ 对应的单元测试和集成测试。 |
开发指南
开发指南和架构规则请参阅 CLAUDE.md / AGENTS.md。简要来说:
- 处理器抛出异常,由框架捕获——工具逻辑中不要使用
try/catch - 使用
ctx.log进行请求范围内的日志记录,使用ctx.state进行租户范围内的存储 - 通过
src/index.ts中的入口数组注册新工具 - 封装外部 API 调用:验证原始数据 → 规范化为领域类型 → 返回输出模式;绝不捏造缺失字段
贡献
欢迎提交问题。提交前请运行检查和测试:
bun run devcheck
bun run test
数据归属
Project Gutenberg 的数据属于公共领域。目录元数据来源于 Gutendex(MIT 许可证)。
许可证
Apache-2.0——详情请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。