mcpField
H
Hardcover OAuth MCP

Hardcover OAuth MCP

远程服务
hardcover.benjuntilla.com游戏娱乐31 周前更新

关于 Hardcover OAuth MCP

Hardcover OAuth MCP 是一款远程服务,可通过 AI 助手管理 Hardcover 阅读书库。它使用 Hardcover OAuth 按账户授权,并提供面向常见任务的工具及 GraphQL 访问能力。

主要功能

  1. 01读取和更新书库条目
  2. 02跟踪阅读进度与阅读记录
  3. 03管理书评、日志和书单
  4. 04创建和查看阅读目标
  5. 05通过 Hardcover OAuth 登录
  6. 06通过 GraphQL 工具访问 Hardcover API

适用场景

  1. 01更新图书状态和页数进度
  2. 02整理并排序待读书单
  3. 03记录书评或阅读笔记
  4. 04设定并查看年度阅读目标

MCP 相关

远程 MCP 服务提供读、写和删除 Hardcover 账户数据的工具,具体工具取决于 OAuth 授权范围。它还提供 GraphQL 和模式发现工具,以执行其他 API 操作。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://hardcover.benjuntilla.com/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;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 中的其他所有内容。

示例工作流

追踪一本书
  1. “我读到 Piranesi 的第 212 页了。”这本书会移至「正在阅读」,并将页码记录到本次阅读记录中。
  2. “今天读完了,给 4.5 星。”这本书会移至「已读」,完读日期设为今天,并添加 4.5 星评分。

Claude 收到“我读到 Susanna Clarke 的 Piranesi 第 212 页了”后,查看「正在阅读」,搜索 Hardcover 并更新阅读进度

规划接下来读什么
  1. “把 Kindred 和 The Dispossessed 加入我的想读书单。”
  2. “创建一个名为 Summer 的排序书单,把这两本书都加进去,并将 Kindred 排在第一位。”
  3. “把 The Dispossessed 移到顶部。”
设定阅读目标
  1. “设定今年读 30 本书的目标。”
  2. “我的目标完成得怎么样了?”
记录阅读日志
  1. “保存 Piranesi 中这句引文:‘房子的美无可估量;它的善意无穷无尽。’”
  2. “显示我关于 Piranesi 的笔记。”
选择一个版本
  1. “Dune 有哪些有声书版本?它们分别有多长?”
  2. “把我的版本换成最短的那个。”
询问其他任何问题
  1. “我去年读过的书中,哪一本页数最多?”没有专用工具时,客户端会通过 hardcover_find_operations 查询 API,并运行只读的 hardcover_query。
  2. “用 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 权限

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

Hardcover 的 Authorized apps 页面,列出 Hardcover OAuth MCP 的权限范围和会话,并提供撤销访问权限的按钮

报告问题

遇到无法正常运行的情况?请在 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,即可在本机运行完整流程:

  1. 运行 mise run dev。它会在 http://localhost:1337 上通过 workerd 提供 Worker 服务,使用本地 KV 和 Durable Objects,并在代码更改时重新加载。它会在启动时构建静态页面(README.md、PRIVACY.md、TERMS.md、SECURITY.md 和 site/)一次,因此要查看这些内容的更改,需要重启服务。你不需要 Cloudflare 账户。
  2. 在同一台机器上将客户端连接到 http://localhost:1337/mcp,例如运行 claude mcp add --transport http hardcover-local http://localhost:1337/mcp。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。