关于 Hardcover OAuth MCP
Hardcover OAuth MCP 是一款远程服务,可通过 AI 助手管理 Hardcover 阅读书库。它使用 Hardcover OAuth 按账户授权,并提供面向常见任务的工具及 GraphQL 访问能力。
主要功能
- 01读取和更新书库条目
- 02跟踪阅读进度与阅读记录
- 03管理书评、日志和书单
- 04创建和查看阅读目标
- 05通过 Hardcover OAuth 登录
- 06通过 GraphQL 工具访问 Hardcover API
适用场景
- 01更新图书状态和页数进度
- 02整理并排序待读书单
- 03记录书评或阅读笔记
- 04设定并查看年度阅读目标
MCP 相关
远程 MCP 服务提供读、写和删除 Hardcover 账户数据的工具,具体工具取决于 OAuth 授权范围。它还提供 GraphQL 和模式发现工具,以执行其他 API 操作。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://hardcover.benjuntilla.com/mcpclaude mcp add --transport http benjuntilla-hardcover-oauth https://hardcover.benjuntilla.com/mcp{"mcpServers":{"benjuntilla-hardcover-oauth":{"type":"http","url":"https://hardcover.benjuntilla.com/mcp"}}}在 Cursor 中打开{"servers":{"benjuntilla-hardcover-oauth":{"type":"http","url":"https://hardcover.benjuntilla.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"benjuntilla-hardcover-oauth":{"type":"http","url":"https://hardcover.benjuntilla.com/mcp"}}}{"mcpServers":{"benjuntilla-hardcover-oauth":{"serverUrl":"https://hardcover.benjuntilla.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
hardcover-oauth-mcp
通过这个远程 模型上下文协议(MCP) 服务,你可以在 Claude、ChatGPT 和其他 AI 助手中管理自己的 Hardcover 书库、阅读进度、评论、书单和目标。连接公共实例 https://hardcover.benjuntilla.com/mcp(快速入门),或部署自己的实例。
- 支持网页端和移动端客户端。 公共实例是托管的远程服务,因此 Claude 网页版和手机版、ChatGPT 以及其他远程客户端都可以连接。其他 Hardcover MCP 服务运行在你自己的电脑上,只有桌面客户端可以连接。
- 使用 Hardcover 登录(OAuth)。 无需粘贴不安全的 API 密钥。每个人都可以通过 Hardcover 的 OAuth 连接自己的账户,并选择授予哪些权限。
- 53 个读写工具。 47 个面向任务的自定义工具涵盖书库、阅读进度、评论、日志、书单、目标、关注、通知和氛围。六个原始 GraphQL 和架构发现工具可访问 Hardcover API 中的其他所有内容。
示例工作流
追踪一本书
- “我读到 Piranesi 的第 212 页了。”这本书会移至「正在阅读」,并将页码记录到本次阅读记录中。
- “今天读完了,给 4.5 星。”这本书会移至「已读」,完读日期设为今天,并添加 4.5 星评分。

规划接下来读什么
- “把 Kindred 和 The Dispossessed 加入我的想读书单。”
- “创建一个名为 Summer 的排序书单,把这两本书都加进去,并将 Kindred 排在第一位。”
- “把 The Dispossessed 移到顶部。”
设定阅读目标
- “设定今年读 30 本书的目标。”
- “我的目标完成得怎么样了?”
记录阅读日志
- “保存 Piranesi 中这句引文:‘房子的美无可估量;它的善意无穷无尽。’”
- “显示我关于 Piranesi 的笔记。”
选择一个版本
- “Dune 有哪些有声书版本?它们分别有多长?”
- “把我的版本换成最短的那个。”
询问其他任何问题
- “我去年读过的书中,哪一本页数最多?”没有专用工具时,客户端会通过
hardcover_find_operations查询 API,并运行只读的hardcover_query。 - “用 Kindred 回答提示词‘哪本书让你哭得不能自已?’。”客户端通过
hardcover_search查找提示词,通过hardcover_find_operations查询 mutation,然后运行hardcover_mutate。
快速入门
任何拥有 Hardcover 账户的人都可以使用公共实例。将此 URL 添加到 MCP 客户端,作为远程服务:
https://hardcover.benjuntilla.com/mcp
- Claude(网页端、桌面端、移动端):依次打开 Settings → Connectors → Add custom connector,然后粘贴 URL。
- Claude Code:
claude mcp add --transport http hardcover https://hardcover.benjuntilla.com/mcp,然后运行/mcp登录。 - ChatGPT(网页端、桌面端、移动端):在 chatgpt.com 上打开 Plugins,选择 + → Add custom MCP server,粘贴 URL,将身份验证方式保留为 OAuth,然后创建服务。在聊天中输入
@即可使用。 - Cursor 和其他客户端: 使用该 URL 添加远程(Streamable HTTP)服务。客户端会自行发现 OAuth。
- MCP Inspector:
bunx @modelcontextprotocol/inspector,选择 Streamable HTTP,然后输入 URL。
客户端会打开授权页面,供你选择权限,之后 Hardcover 会要求你登录。

你可以随时在 Hardcover 的 Authorized apps 页面撤销访问权限。请参阅隐私声明和条款,或部署自己的实例。

报告问题
遇到无法正常运行的情况?请在 GitHub 上提交问题,或发送电子邮件至 [email protected]。对于安全问题,请改为遵循安全政策。
工作原理
它运行在 Cloudflare Developer Platform(Workers、Durable Objects 和 KV)上,这是因为该平台开发体验便捷且成本效益高。每个连接都由一个 Durable Object 保存令牌并提供 MCP 服务;KV 则保存 OAuth 状态。Alchemy 可以通过一条命令部署它,而 alchemy dev 会在本地运行相同的代码。它使用 Effect 4(包括 Effect 自带的 MCP 服务)、TypeScript 7、Bun、mise 和 Astro 构建。
┌──────────────┐ MCP + OAuth 2.1 ┌──────────────────────────────┐
│ MCP client │ ─────────────────▶ │ Worker │
│ (Claude, …) │ ◀───────────────── │ OAuthProvider, consent page │
└──────────────┘ MCP access token │ auth + rate limits on /mcp │
└──────────────┬───────────────┘
│ one per connection
┌──────────────▼───────────────┐
│ HardcoverConnection (DO) │
│ Hardcover tokens │
│ Effect McpServer + tools │
└──────────────┬───────────────┘
│ OAuth + GraphQL
┌──────────────▼───────────────┐
│ Hardcover API │
└──────────────────────────────┘
该 Worker 是面向 MCP 客户端的 OAuth 授权服务器,基于 @cloudflare/workers-oauth-provider 构建。它支持动态客户端注册和客户端 ID 元数据文档。
Worker 会检查每个 /mcp 请求(令牌、允许列表、服务自身的速率限制、作用域),然后将请求转发给连接对应的 Durable Object。该对象运行 Effect 的 MCP 服务。它既支持无会话的 2026-07-28 版本,也支持 2025-11-25、2025-06-18 和 2025-03-26 版本。2025 版本的会话保存在对象内存中。当 Cloudflare 回收空闲对象时,其会话也会结束:客户端会收到 404,并按协议要求开始新会话。
工具
类型:读取、写入(添加或更改数据)和删除。只有在为连接选择了相应作用域后,才会显示工具。
全部 53 个工具
| 工具 | 功能 | 类型 | 权限范围 | 需要 | | --- | --- | --- | --- | --- | | `hardcover_me` | 获取你的 Hardcover 个人资料 | 读取 | `read:me:content` | | | `hardcover_get_user` | 查找读者 | 读取 | `read:users` | | | `hardcover_list_follows` | 列出关注对象 | 读取 | `read:social` | | | `hardcover_follow_user` | 关注读者 | 写入 | `write:social`、`read:users` | | | `hardcover_unfollow_user` | 取消关注读者 | 删除 | `write:social`、`read:users` | | | `hardcover_list_notifications` | 列出通知 | 读取 | `read:notifications` | | | `hardcover_mark_notifications_read` | 将通知标记为已读 | 写入 | `write:notifications` | | | `hardcover_search` | 搜索 Hardcover | 读取 | `read:catalog` | | | `hardcover_get_book` | 获取图书 | 读取 | `read:catalog` | | | `hardcover_get_editions` | 获取版本 | 读取 | `read:catalog` | | | `hardcover_get_author` | 获取作者 | 读取 | `read:catalog` | | | `hardcover_get_series` | 获取系列 | 读取 | `read:catalog` | | | `hardcover_trending_books` | 查看热门图书 | 读取 | `read:catalog` | | | `hardcover_list_vibes` | 列出你的氛围标签 | 读取 | `read:vibes` | | | `hardcover_create_vibe` | 创建氛围标签 | 写入 | `write:vibes` | Supporter | | `hardcover_list_library` | 列出你的书库 | 读取 | `read:library` | | | `hardcover_currently_reading` | 查看正在阅读的图书 | 读取 | `read:library` | | | `hardcover_list_reviews` | 列出你的评论 | 读取 | `read:library` | | | `hardcover_get_library_entry` | 获取你为某本书创建的条目 | 读取 | `read:library` | | | `hardcover_set_status` | 设置阅读状态 | 写入 | `write:library`、`read:library` | | | `hardcover_update_progress` | 更新阅读进度 | 写入 | `write:library`、`read:library` | | | `hardcover_mark_finished` | 将图书标记为已读完 | 写入 | `write:library`、`read:library` | | | `hardcover_rate_book` | 为图书评分 | 写入 | `write:library`、`read:library` | | | `hardcover_write_review` | 撰写评论 | 写入 | `write:library`、`write:reviews`、`read:library` | | | `hardcover_delete_review` | 删除评论 | 删除 | `write:library`、`write:reviews`、`read:library` | | | `hardcover_update_library_entry` | 编辑你为某本书创建的条目 | 写入 | `write:library`、`read:library` | | | `hardcover_set_owned` | 将某个版本标记为已拥有 | 写入 | `write:library`、`read:lists`、`write:lists` | | | `hardcover_remove_from_library` | 从你的书库中移除图书 | 删除 | `write:library`、`read:library` | | | `hardcover_add_read` | 添加阅读记录 | 写入 | `write:library`、`read:library` | | | `hardcover_update_read` | 编辑阅读记录 | 写入 | `write:library`、`read:library` | | | `hardcover_delete_read` | 删除阅读记录 | 删除 | `write:library`、`read:library` | | | `hardcover_list_journal` | 列出日志条目 | 读取 | `read:journal` | | | `hardcover_add_journal_entry` | 添加日志条目 | 写入 | `write:library` | | | `hardcover_update_journal_entry` | 编辑日志条目 | 写入 | `write:library` | | | `hardcover_delete_journal_entry` | 删除日志条目 | 删除 | `write:library` | | | `hardcover_list_lists` | 列出你的书单 | 读取 | `read:lists` | | | `hardcover_get_list` | 获取书单 | 读取 | `read:lists`、`read:catalog` | | | `hardcover_create_list` | 创建书单 | 写入 | `write:lists` | | | `hardcover_update_list` | 编辑书单 | 写入 | `write:lists`、`read:lists` | | | `hardcover_delete_list` | 删除书单 | 删除 | `write:lists`、`read:lists` | | | `hardcover_add_to_list` | 将图书添加到书单 | 写入 | `write:lists` | | | `hardcover_remove_from_list` | 从书单中移除图书 | 删除 | `write:lists`、`read:lists` | | | `hardcover_reorder_list` | 重新排列书单 | 写入 | `write:lists`、`read:lists` | | | `hardcover_list_goals` | 列出你的阅读目标 | 读取 | `read:goals` | | | `hardcover_create_goal` | 创建阅读目标 | 写入 | `write:goals` | | | `hardcover_update_goal` | 编辑阅读目标 | 写入 | `write:goals`、`read:goals` | | | `hardcover_delete_goal` | 删除阅读目标 | 删除 | `write:goals`、`read:goals` | | | `hardcover_find_operations` | 查找 Hardcover API 操作 | 读取 | 无 | | | `hardcover_describe_type` | 描述 Hardcover GraphQL 类型 | 读取 | 无 | | | `hardcover_query` | 执行 Hardcover GraphQL 查询 | 读取 | 无 | | | `hardcover_mutate` | 执行 Hardcover GraphQL 修改操作 | 写入 | 任意 `write:*` 权限范围 | 使用 `write:vibes` 需要 Supporter | | `hardcover_delete` | 执行 Hardcover GraphQL 删除操作 | 删除 | 任意 `write:*` 权限范围 | 使用 `write:vibes` 需要 Supporter | | `hardcover_catalog_edit` | 向 Hardcover 目录添加内容或编辑目录 | 写入 | 任意 `write:*` 目录权限范围 | 使用 `write:catalog:edit` 需要 Librarian;使用 `write:catalog:map` 需要 Librarian (book_mapper) |Supporter 是付费的 Hardcover 会员身份,Librarian 是 Hardcover 图书管理员角色。Hardcover 会强制执行这两项要求;始终需要其中一项的工具会在标题和描述中注明。对于不具备相应角色的账户,登录时会移除 write:catalog:edit 和 write:catalog:map,但任何人都可以使用 write:catalog:append 添加目录记录。
原始工具会在发送前检查每份文档的操作类型、根字段、所需作用域和大小(最多 10 个顶层字段)。它们还会拒绝 Hardcover 已禁用的文本运算符,例如 _like 和 _regex。出错时会返回清晰的错误,而不会消耗你的 Hardcover 速率限制。hardcover_find_operations 和 hardcover_describe_type 会搜索根据 Hardcover 的 API 文档建立的索引。hardcover_find_operations 会根据操作名称和返回类型的匹配程度对操作排序,因此像“将一本书添加到书单”这样的短语也能生效。对于不存在的类型名称,hardcover_describe_type 会推荐最接近的类型,因此输入 UserBook 会指向 user_books。
Hardcover 的速率限制按用户计算,所有应用共用。每位用户每分钟可发送 60 个请求(突发上限为 10 个,Supporter 为 15 个),每天可发送 5,000 个请求(Supporter 为 50,000 个)。每个顶层字段计为一个请求。
部署你自己的实例
你需要 mise、Cloudflare 账户和 Hardcover 账户。自定义域名为可选项;不配置时,服务地址为 https://hardcover-oauth-mcp.<your-subdomain>.workers.dev。
1. 安装
git clone https://github.com/benjuntilla/hardcover-oauth-mcp
cd hardcover-oauth-mcp
mise install
cp .env.example .env
2. 注册 Hardcover 应用
在 hardcover.app/account/developer-apps/new 创建一个应用:
- 应用类型: Web 应用(服务器端)。之后无法更改。
- 重定向 URI:
https://<your-domain>/callback,以及用于本地运行的http://localhost:1337/callback。 - 此应用可以请求的作用域:
read:me:content read:me:roles read:catalog read:library write:library write:reviews read:journal read:lists write:lists read:goals write:goals read:users read:social write:social read:notifications write:notifications read:prompts write:prompts read:vibes write:vibes read:account write:catalog:append write:catalog:edit write:catalog:map openid offline_access。不要勾选all,因为它也会涵盖 Hardcover 之后添加的作用域。 - 设备授权授予: 关闭。
将客户端 ID 和密钥填入 .env,分别设为 HARDCOVER_CLIENT_ID 和 HARDCOVER_CLIENT_SECRET。Hardcover 只会显示一次密钥。
3. 配置
在 alchemy.run.ts 中编辑 DEPLOYMENTS。每个键对应一个阶段:mise run deploy --stage prod 使用 prod,而 mise run dev 使用 local。
const DEPLOYMENTS: Readonly<Record<string, DeploymentSettings>> = {
local: { allowedUsers: ["*"] },
prod: { allowedUsers: ["your-username"], domain: "hardcover.example.com" },
}
allowedUsers:你的 Hardcover 用户名(也可以填写多个用户名或数字 ID)。使用"*"允许任何人连接,和公共实例一样。每个人都使用自己的账户,并受自己的 Hardcover 速率限制。domain:Cloudflare 账户中某个区域下的主机名。省略此项即可使用自动分配的 workers.dev URL。
4. 在 Cloudflare 中为 Alchemy 登录
bun alchemy profile edit --add Cloudflare
5. 部署
mise run deploy --stage prod
这会构建网站、创建 Cloudflare 资源并打印 URL。有更改后再次运行。mise run logs --stage prod 会持续输出日志。mise run destroy --stage prod 会删除所有内容。
部署会将 Alchemy 的状态保存在你的 Cloudflare 账户中,因此任何已登录 Alchemy 的机器都可以重新部署或销毁。首次部署会在那里设置状态存储。mise run dev 和测试会将各自的状态保存在 .alchemy/ 中。
通过 mise run check 和 mise run test:e2e 检查后,推送到 main 会部署 prod。这需要一个仅用于 main 的 production 环境,其中包含 CLOUDFLARE_ACCOUNT_ID 变量,以及 CLOUDFLARE_API_TOKEN、HARDCOVER_CLIENT_ID 和 HARDCOVER_CLIENT_SECRET 密钥。该令牌需要 Account Settings 和 Zone 的读取权限,以及 Workers Scripts、Workers KV Storage、Secrets Store、Workers Routes 和 SSL and Certificates 的编辑权限。
- 计划: 使用 Workers Paid。连接对应的 Durable Object 会在唤醒时构建其 MCP 服务。这大约需要 100 ms 的 CPU 时间,是 Free 计划每个请求限制的 10 倍。此后,每次调用大约需要 5 ms。
- 服务自身的速率限制: 每个客户端 IP 每分钟可进行 10 次注册、30 个登录步骤和 60 次令牌请求。每个 Hardcover 账户每分钟可发起 120 次 MCP 请求。
- 可观测性: Workers Logs、Traces 和 Issues 已启用。Cloudflare 的请求日志会记录每个请求的路径、状态、标头和客户端 IP,但不会记录查询字符串或请求正文。Cloudflare 会对 authorization 和 cookie 标头进行脱敏。不记录查询字符串,可避免 Hardcover 的一次性登录代码出现在日志和跟踪记录中。令牌授予的权限会作为方法参数而非标头传递给 Durable Object,因此不会出现在日志中。OAuth 提供方会使用 Hardcover 用户 ID 的带密钥假名来存储授权,因此跟踪记录中的存储键不会泄露该 ID。Worker 会记录意外故障(缺陷),但不包含令牌或请求数据,并由 Issues 对这些故障进行归类。预期内的问题,例如 Hardcover 速率限制、访问权限被撤销或查询错误,则会作为工具错误返回给 Agent。
6. 连接客户端
按照与公共实例相同的方式连接,将 https://<your-domain>/mcp 作为 URL。
本地运行
使用上文步骤 1 和 2 中的应用和 .env,即可在本机运行完整流程:
- 运行
mise run dev。它会在http://localhost:1337上通过 workerd 提供 Worker 服务,使用本地 KV 和 Durable Objects,并在代码更改时重新加载。它会在启动时构建静态页面(README.md、PRIVACY.md、TERMS.md、SECURITY.md和site/)一次,因此要查看这些内容的更改,需要重启服务。你不需要 Cloudflare 账户。 - 在同一台机器上将客户端连接到
http://localhost:1337/mcp,例如运行claude mcp add --transport http hardcover-local http://localhost:1337/mcp。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。