关于 whoop-mcp
whoop-mcp 是一个 MCP 服务,通过 Whoop 的私有 iOS API 提供对 Whoop 健身数据的读写访问。它面向希望在 AI 客户端中查询和记录 Whoop 数据的用户。
主要功能
- 01通过 MCP 提供 48 个工具
- 02读取全部指标数据
- 03支持部分写入操作
- 04基于 Cognito 的自动令牌刷新
适用场景
- 01在 AI 客户端中查询 Whoop 健身数据
- 02记录训练或日志条目
- 03分析个人指标的历史变化
MCP 相关
whoop-mcp 作为 MCP 服务运行,向 MCP 客户端暴露 Whoop 数据相关的工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @briangaoo/whoop-mcpWHOOP_IOS_BEARER_TOKEN密钥Whoop Cognito access token. Obtain via `whoop-mcp auth` from the repo, which prompts for your Whoop email + password + SMS MFA code, then writes both tokens to a local .env. Auto-refreshes every ~24h.WHOOP_COGNITO_REFRESH_TOKEN密钥Whoop Cognito refresh token (~30 day lifetime). Obtained alongside the bearer token from `whoop-mcp auth`. When this expires, run `whoop-mcp auth` to get a fresh pair.WHOOP_EMAILYour Whoop account email. Used only by `whoop-mcp auth` — the running server reads tokens, not credentials.WHOOP_USER_IDYour numeric Whoop user ID. Optional — used by whoop_profile and whoop_leaderboard. Avoids one redundant bootstrap call per session if set.WHOOP_TIMEZONEIANA timezone (e.g., America/Los_Angeles) for response timestamps. Optional — if unset, the server auto-detects from your Whoop profile's timezone_offset field (refreshed hourly).本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Totem 让 Claude(或任何兼容 MCP 的 AI)能够完整读取和写入你的可穿戴设备数据。目前支持 Whoop——通过 Whoop 的私有 iOS API 获取每项指标。
▶ 2 分钟演示——完整的 totem cloud 流程:安装 → Whoop 登录 → Fly 部署 → Claude 连接器 → 首次查询。
55 个工具、结构化且经 zod 验证的输出、内置目录(372 项运动、308 项行为、203 项运动项目、311 个端点)、写入安全机制、自动刷新 Cognito 令牌、有界内存读取缓存。使用 TypeScript 6、Node 24,共有 278 项测试。
**Totem 正在成为通用可穿戴设备桥接工具。**Whoop 是首个适配器——每项指标都已完整接入。Fitbit、Apple Watch 和 Garmin 的适配器正在开发中(欢迎贡献)。MCP 和投影层与设备无关;适配器只需将数据源映射到相同的共享架构,因此以下内容适用于你佩戴的任何设备。
注意:此工具通过 Whoop 的私有 iOS API(而非公开 OAuth API)运行。这不符合 Whoop 服务条款的许可范围——如果你想在安装前了解详情,请参阅 常见问题。
目录
其他根目录文档:TOOLS.md(完整的工具参考) · WHOOP.md(完整的 API 参考) · CHANGELOG.md · CONTRIBUTING.md · SECURITY.md · LICENSE
快速开始
前置条件: Node 24+ 和 Whoop 账户(任意会员等级)。
git clone https://github.com/thebriangao/totem.git
cd totem && npm install && npx tsc && npm link
这会将 totem 添加到你的 PATH 中(一次性运行 npx tsc 会构建它;此后每个工作流都是 totem 命令——没有 npm run 脚本)。现在运行一条引导式命令——从头到尾处理 Whoop 登录(包括短信验证)、设置,以及连接 Claude。选择你想要的运行方式:
★ 推荐 — totem cloud
将服务部署到主机,并连接到 Web、桌面和移动端上的 Claude,在你账户的所有设备间同步。一条命令即可完成以下步骤:
- Whoop 登录 — 输入电子邮箱和密码;如果账户启用了 MFA,还需输入短信验证码。令牌会保存在本地并推送到主机。
- 选择主机 — Fly(自动化且经过测试)、Railway、Google Cloud Run,或你自己的服务器(提供 Docker 操作引导)。
- 密钥 — 生成
MCP_AUTH_TOKEN,并让你设置连接器密码。 - 部署 + 验证 — 设置环境变量、执行部署,并确认
/health和 OAuth 端点均已上线。 - 连接 — 打印可直接粘贴的配置,适用于 claude.ai、ChatGPT、Claude Code(远程)、以及 Cursor / Windsurf / 任意 HTTP MCP 客户端(OAuth 连接器提供 URL + 密码,其余连接器提供 bearer token 配置块),并打开 claude.ai 的连接器页面。
totem cloud
仅本地 — totem local
通过 stdio 在这台机器上运行服务——无需托管,仅限此设备。按顺序完成 Whoop 登录 → 构建 → 接入你选择的客户端:Claude Desktop、Claude Code、Cursor、VS Code(Copilot)、Gemini CLI、Codex CLI 或 Windsurf——它会自动将正确的配置写入正确路径(或为其他 MCP 客户端打印通用配置块)。重启客户端即可使用。
totem local
保持服务运行
Whoop 令牌大约每 30 天过期一次。令牌过期后,重新运行同一条命令即可——它会重新登录,并且(如果你已部署)将新令牌推送到服务器:
totem auth
如果账户未启用短信 MFA,则不会有提示;如果已启用,则会提示输入验证码。新令牌会自动推送到你的部署。
检查是否正常运行
向 Claude 提问:“我今天的 Whoop 状况如何?”——你应该会收到结构化的恢复、睡眠和负荷数据。
想手动完成所有配置?这些引导式命令只是自动执行了
totemCLI、远程托管和配置中记录的步骤。遇到问题?请参阅故障排除。
为什么要做这个项目
Whoop 提供两种 API:
- 公开开发者 API
developer.whoop.com使用 OAuth2,只读,并在 6 个作用域下提供 13 个端点。你可以获取恢复分数、睡眠阶段总量、训练负荷、身体测量数据(3 个字段),以及每个周期的 HRV/RHR。不包括日记、Strength Trainer、Whoop Coach、睡眠结构图、压力监测、趋势、写入操作,除此之外什么都没有。数字型sport_id已于 2025-09-01 移除。 - 私有 iOS API 是 Whoop 应用实际使用的 API——位于 AWS Cognito 之后的
api.prod.whoop.com。它涵盖 47 个微服务中的 311 种不同操作,包括上述 API 所缺少的一切。
此 MCP 封装了 iOS API 的功能。
iOS API 相比公共 OAuth API 的额外功能
| 功能 | 工具 |
|---|---|
| HRV / RHR / 呼吸 / VO2 / 体重时间序列(25 项指标 × 最多 4 个时间窗口) | whoop_trend |
| 睡眠结构图(各阶段睡眠时间线)+ 完整阶段明细(毫秒 + 百分比)+ 睡眠期间心率 | whoop_sleep |
| 力量训练 — 每组训练、每次锻炼、完整的 372 项运动目录、个人纪录 | whoop_lift_*(8 个工具) |
| 308 种行为的日志 + 行为影响分析 | whoop_journal*(5 个工具) |
| 压力监测器(当天时间线) | whoop_stress, whoop_live_stress |
| Whoop Coach AI 聊天 | whoop_coach_ask |
| 智能闹钟(读取 + 4 种写入模式) | whoop_smart_alarm* |
| 心率区间(读取 + 配置最大心率 / 5 个自定义区间) | whoop_hr_zones* |
| 时间窗口对比、睡眠教练、日历网格、表现评估 | whoop_compare, whoop_sleep_need, whoop_calendar, whoop_performance_assessment |
| 实时心率 / 活动状态 / 实时压力 | whoop_live_*(3 个工具) |
| 社区排行榜、隐藏指标、女性健康(周期 / 症状 / MCI) | whoop_leaderboard, whoop_hidden_metric, whoop_cycle* |
| 15 个写入工具 — 记录锻炼、日志条目、编辑个人资料、配置智能闹钟、编辑睡眠时间 | 多种工具 |
如果恢复情况 + 睡眠总量 + 锻炼列表就够用了,请使用公共 OAuth API。如果表格中的任何一项让你感兴趣,就需要使用这个 API。iOS API 是通过 mitmproxy 发现的 — 完整方法见 WHOOP.md。
功能说明
MCP 以本地 Node 进程的形式运行。它通过标准输入输出(或远程部署时通过 HTTP)使用 Model Context Protocol 通信,在启动时注册 55 个工具,并等待已连接的 MCP 客户端发起工具调用。
调用工具时:
- 通过缓存的 Cognito 访问令牌进行身份验证(令牌过期时自动刷新)
- 向
api.prod.whoop.com发送 HTTP 请求 - 遍历响应,提取扁平化的领域对象(投影步骤)
- 根据 zod 架构验证投影后的对象(捕获 Whoop API 的变化)
- 将结构化 JSON 返回给 MCP 客户端
写入操作遵循相同流程,另外还有一个预览关卡:每个写入工具默认 confirm: false,并返回将要发送的内容预览。Claude 必须显式地以 confirm: true 再次调用,才能真正执行操作。
完整的工具说明请参阅55 个工具。
架构
Claude Desktop / Code ──stdio──▶ src/server.ts ──▶ 49 tool handlers
│
┌──────────────────┼──────────────────┐
▼ ▼ ▼
schemas (zod) projections (raw→flat) whoop/client
│
▼ HTTPS
api.prod.whoop.com
每个工具的三个层
每个工具都由架构 + 投影 + 处理程序组成:
src/schemas/<tool>.ts— zod 架构,即 Claude 能看到的契约。运行时用于在返回前验证投影的输出。src/projections/<tool>.ts— 纯函数,将 Whoop 的原始 BFF 响应转换为扁平化对象。所有“Whoop 把数据放在别处,而不是你预期的位置”的知识都集中在这里。使用捕获的样本进行测试。src/tools/v2/<tool>.ts— 约 25–100 行。注册工具、解析输入参数、调用客户端、运行投影、使用 zod 验证并返回结果。
工具文件中几乎没有逻辑。逻辑都在投影中 — 这让代码库很容易测试(投影是纯转换,可使用 tests/fixtures/*.json 中的样本进行测试,无需访问网络)。
处理结构变化
当 Whoop 更改响应结构时,投影会生成意外数据,zod 的 .parse() 会失败,MCP 随即抛出 WhoopProjectionError,而不会悄悄向 Claude 返回格式错误的数据。修复方法:使用 whoop_raw + whoop_endpoints 捕获新的结构,更新投影和样本,然后发布。
近期示例: 2026 年 5 月,Whoop 将恢复和压力深入分析从
GRAPHING_CARD磁贴(通过content.title键入,例如"RECOVERY")迁移为SCORE_GAUGE+CONTRIBUTORS_TILE项目,并使用稳定的content.id键(RECOVERY_SCORE_GAUGE、CONTRIBUTORS_TILE_HRV)。其他深入分析仍使用旧的卡片结构。借助这些备用工具,调试迁移变得轻而易举。
55 个工具
简要概览。**每个工具的完整参考(输入格式 · 源端点 · 输出格式 · 说明)→ TOOLS.md。**标有 ⚠️ 的工具会执行写入(默认 confirm: false,优先预览)。标有 ⚡ 的工具会精简或聚合读取,将多个源调用合并为一次低令牌用量的响应;whoop_weekly_plan 是 ⚡ 实验性工具(其端点格式尚未通过实时账户验证)。
| 分组 | 工具 |
|---|---|
| 快照与个人资料(6) | whoop_today · whoop_day · whoop_daily_brief ⚡ · whoop_weekly_plan ⚡ · whoop_profile · whoop_calendar |
| 深入分析(3) | whoop_recovery · whoop_sleep · whoop_strain |
| 趋势(3) | whoop_trend · whoop_trend_pack ⚡ · whoop_compare |
| 压力 + 睡眠指导(2) | whoop_stress · whoop_sleep_need |
| 实时数据(4) | whoop_live_hr · whoop_live_state · whoop_live_stress · whoop_activity_now ⚡ |
| 活动(5) | whoop_workouts · whoop_workout · whoop_sports_catalog · whoop_activity_create ⚠️ · whoop_activity_delete ⚠️ |
| 力量训练读取(7) | whoop_lift_prs · whoop_lift_exercise · whoop_lift_progression · whoop_lift_history · whoop_lift_overview ⚡ · whoop_lift_library · whoop_lift_catalog |
| 力量训练写入(3) | whoop_lift_log ⚠️ · whoop_lift_template_save ⚠️ · whoop_lift_custom_exercise ⚠️ |
| 日志(5) | whoop_journal · whoop_journal_catalog · whoop_behavior_impact · whoop_journal_log ⚠️ · whoop_journal_autopop ⚠️ |
| 女性健康(3) | whoop_cycle · whoop_cycle_log ⚠️ · whoop_symptom_log ⚠️ |
| 指导 + 表现(2) | whoop_coach_ask ⚠️ · whoop_performance_assessment |
| 智能闹钟(2) | whoop_smart_alarm · whoop_smart_alarm_set ⚠️ |
| 社交(2) | whoop_leaderboard · whoop_communities |
| 设置(5) | whoop_hr_zones · whoop_preferences ⚡ · whoop_hr_zones_set ⚠️ · whoop_profile_update ⚠️ · whoop_hidden_metric ⚠️ |
| 备用通道(2) | whoop_raw · whoop_endpoints |
总计:55 个(38 个读取 + 15 个写入 + 2 个备用通道)。各工具的输入参数、源端点和输出格式,参见 TOOLS.md。
身份验证
Whoop 的 iOS 应用使用通过 Whoop 自有代理(/auth-service/v3/whoop/)路由的 AWS Cognito。代理会在服务器端填入 ClientId + SECRET_HASH,无需提取 IPA。
初始化一次(电子邮件 + 密码 + 短信 MFA 验证码,若账户已启用)→ 令牌写入 .env。之后无需手动操作:访问令牌会通过刷新令牌每 24 小时自动刷新;刷新令牌的有效期约为 30 天。单飞刷新锁可防止多个并发工具调用同时发现令牌过期时引发的刷新风暴。
身份验证请求会模拟 iOS AWS Swift SDK(代理会对 Node 风格的 User-Agent 返回 403);数据请求则会携带 WHOOP iOS 应用自身的身份标头(user-agent: iOS、x-whoop-* 设备标头组和每次安装独有的标识符),使流量看起来像来自合法应用,而非显得异常——完整标头组和相关说明见 WHOOP.md → 数据请求标头。
错误类别(src/whoop/errors.ts):
| 错误 | 情况 | 行为 |
|---|---|---|
WhoopAuthExpiredError | Whoop 返回 401 | TokenManager 会在下次调用时刷新令牌 |
WhoopApiError | 返回带响应正文的 4xx | 将错误说明传递给调用方 |
WhoopServerError | 5xx | 暂时性错误——重试 |
WhoopProjectionError | 投影输出未通过 zod 解析 | Whoop 已更改数据格式——修复投影 |
刷新令牌的有效期到期(约 30 天)后,重新运行 totem auth。它会自动检测本地或已部署环境;如果是已部署环境,还会将新令牌推送到该环境。需要新的短信验证码(若账户启用了 MFA),并开始新的 30 天有效期。
写入安全机制
每个写入工具默认使用 confirm: false。首次调用会返回将要执行操作的预览。Claude 必须明确地使用 confirm: true 再次调用,才能发送实际请求。若没有这道关卡,Claude 幻觉出“记录我的锻炼”之类的内容,就可能在你的账户中创建无效活动。
预览结构(位于 src/whoop/write_safety.ts):
{
"preview": true,
"will_execute": {
"method": "POST",
"path": "/weightlifting-service/v2/weightlifting-workout/activity",
"body_summary": {
"exercise_count": 3, "set_count": 12,
"exercise_list": [{"name": "BENCHPRESS_BARBELL", "set_count": 5}, ...]
}
},
"set_confirm_true_to_run": true
}
Claude 会将预览内容读给你听;你确认后,Claude 使用 confirm: true 再次调用,实际 POST 请求才会发送。每个写入工具的输出 schema 都是 withPreview(ReceiptSchema) 判别联合类型——要么是预览,要么是回执,不会两者兼有。
内置目录
四个数据集在构建时编译进 MCP(不会在运行时获取):
| 目录 | 条目数 | 目录工具 | 用途 |
|---|---|---|---|
behaviors.ts | 308 | whoop_journal_catalog | 验证日志行为 |
exercises.ts | 372 | whoop_lift_catalog | 力量训练器练习 |
sports.ts | 203 | whoop_sports_catalog | sport_id ↔ 名称 |
endpoints.ts | 311 | whoop_endpoints | 搜索 API 路径 |
本地查询,不占用提示词空间:目录工具是在本地搜索,不产生网络请求,因此完整的 372 项练习、308 项行为和 203 项运动列表不会进入系统提示词(约节省 14k 个 token)。接收 ID 的写入工具(whoop_activity_create、whoop_lift_log、whoop_journal_log、……)会在发送请求前,使用这些内置数据集验证 ID 或完全匹配的目录名称;遇到未知值时会返回可执行的错误信息。(截至 1.4.4 版本,曾有一个要求“必须先调用目录”的会话级关卡;现已移除,改用这种一致的本地验证方式。)
配置
环境变量
| 变量 | 必需 | 说明 |
|---|---|---|
WHOOP_EMAIL | 是 | 你的 Whoop 登录邮箱 |
WHOOP_PASSWORD | 是(仅用于引导设置) | 你的 Whoop 登录密码(仅在引导设置期间使用) |
WHOOP_IOS_BEARER_TOKEN | 是 | Cognito 访问令牌(24h,自动刷新) |
WHOOP_COGNITO_REFRESH_TOKEN | 是 | Cognito 刷新令牌(约 30d) |
WHOOP_USER_ID | 否 | 你的 Whoop 用户 ID——供 whoop_profile、whoop_leaderboard 使用。可避免每个会话都进行一次引导设置调用。 |
WHOOP_TIMEZONE | 否 | IANA 时区(例如,America/Los_Angeles)。若未设置,会从你的 Whoop 个人资料中自动检测,并每小时刷新一次。显式设置即可覆盖自动检测值。 |
WHOOP_INSTALLATION_ID | 否(自动) | 每次安装对应的设备标识符,随 x-whoop-installation-identifier 发送。首次运行时生成一次并写入 .env——不要手动设置。 |
WHOOP_TOKEN_STORE | 否 | envfile(默认值——将刷新的令牌写回 .env)或 memory(用于只读文件系统;约每 30d 重新进行一次引导设置)。 |
Claude Desktop 配置
{
"mcpServers": {
"whoop": {
"command": "/opt/homebrew/bin/node",
"args": ["/absolute/path/to/totem/dist/server.js"]
}
}
}
MCP 会从仓库根目录(相对于 server.js)加载 .env。请使用绝对路径——Claude Desktop 不会继承 shell 的 PATH。
远程托管
MCP 也支持 HTTP——部署一次,即可在多台设备上使用。相同的 55 个工具、相同的自动刷新机制,并通过 URL 上的 bearer token 进行访问控制。
# 1. Local bootstrap (Cognito needs an interactive MFA prompt)
totem auth
# 2. Build + deploy via the shipped Dockerfile (Fly/Railway/Render/VPS — all work)
docker build -t totem .
# 3. Run with env: WHOOP_EMAIL, WHOOP_IOS_BEARER_TOKEN, WHOOP_COGNITO_REFRESH_TOKEN,
# MCP_TRANSPORT=http, MCP_AUTH_TOKEN=$(openssl rand -hex 32)
部署到 Hugging Face Spaces(免费托管)
Hugging Face Spaces 提供免费的 Docker 托管——这是 Fly 或 Railway 的零成本替代方案。若要将其作为自定义连接器连接到 claude.ai 网页版和 Claude 移动端,需要 Claude Pro 方案,但服务器本身可在 HuggingFace 上免费运行。
注意: HuggingFace Spaces 仅通过 7860 端口转发所有外部流量,但此仓库的 Dockerfile 默认使用
3000。服务器会从环境变量读取PORT,因此只需将PORT=7860设置为 Space 变量(见下方第 2 步)——无需修改 Dockerfile,服务器便会监听正确的端口。
分步说明
1. 创建新的 Space
- 前往 huggingface.co/new-space
- 选择 Docker 作为 Space SDK
- 将可见性设为 Public——HuggingFace Spaces 必须设为公开,Claude 的连接器才能访问
/mcp端点 2. 通过 Space 设置界面添加密钥
在你的 Space 中,前往 Settings → Variables and Secrets,添加以下内容。令牌值应作为 Secrets 添加(会隐藏,不会显示在日志中);PORT 和 PUBLIC_URL 不敏感,可以作为普通 Variables 添加:
| 密钥名称 | 值的获取方式 |
|---|---|
WHOOP_EMAIL | 你的 Whoop 账户邮箱 |
WHOOP_IOS_BEARER_TOKEN | 在本地计算机上运行 totem auth 获取(写入 .env) |
WHOOP_COGNITO_REFRESH_TOKEN | 在本地计算机上运行 totem auth 获取(写入 .env) |
WHOOP_USER_ID | 运行 totem auth 后从 .env 获取 |
MCP_AUTH_TOKEN | 使用 openssl rand -hex 32 生成(如果你运行过部署流程,也可以复用 .env.deploy 中的值) |
AUTH_PASSWORD | 添加 Claude 连接器时需要输入一次的密码 |
PUBLIC_URL | 你的 Space 公共 URL,例如:https://<your-hf-username>-<your-space-name>.hf.space |
PORT | 7860 — HuggingFace 要求的端口。未设置时,容器会监听 3000,无法访问。 |
提示: 运行
totem auth后,可从本地.env获取WHOOP_*令牌值。MCP_AUTH_TOKEN需要你自行生成(openssl rand -hex 32)。
3. 将代码推送到 Space
克隆此仓库,将 HuggingFace Space 添加为远程仓库,然后推送:
git clone https://github.com/thebriangao/totem
cd totem
# Add your HuggingFace Space as a remote
git remote add hf https://huggingface.co/spaces/<your-hf-username>/<your-space-name>
# Push the main branch
git push hf main
HuggingFace 会自动构建并运行 Docker 容器。查看 Space 中的 Logs 标签页,确认容器已启动且 /health 返回 200。
4. 连接到 Claude
Space 运行后,前往 claude.ai → Settings → Connectors → Add custom connector:
- MCP 服务 URL:
https://<your-hf-username>-<your-space-name>.hf.space/mcp - Claude 会打开 OAuth 流程 — 输入你在 Space 密钥中设置的
AUTH_PASSWORD
MCP_AUTH_TOKEN在内部用作 bearer token 和 JWT 签名密钥。不要在 Claude 的连接器界面中输入它 — 该界面使用的是 OAuthAUTH_PASSWORD流程。
5. 令牌过期时重新认证(约 30 天)
Whoop 的 Cognito 令牌大约每 30 天过期一次。在本地计算机上重新运行 totem auth,然后在 Space 的 Secrets 界面中更新 WHOOP_IOS_BEARER_TOKEN 和 WHOOP_COGNITO_REFRESH_TOKEN。Space 会自动重启并使用新令牌。
Claude Desktop 不原生支持远程 MCP — 通过 mcp-remote 使用 stdio 桥接:
{ "mcpServers": { "whoop": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://your-app.fly.dev/mcp",
"--header", "Authorization:Bearer your-mcp-auth-token"]
}}}
Claude Code 原生支持远程 MCP:claude mcp add whoop --url ... --header ...。
claude.ai 网页版 + Claude 移动应用 无法使用 bearer token — 它们的自定义连接器界面仅支持 OAuth。服务包含 OAuth 2.1 + PKCE 授权服务,正是为此设计。设置两个额外的环境变量即可启用:
AUTH_PASSWORD=<a password you'll type once when adding the connector>
PUBLIC_URL=https://your-app.fly.dev # your server's public origin (the OAuth issuer)
然后在 Claude 中:前往 Settings → Connectors → Add custom connector,粘贴 https://your-app.fly.dev/mcp,Claude 会引导你完成 OAuth 流程。它会弹出一个小型密码页面(由你的服务提供)— 输入 AUTH_PASSWORD,批准即可。之后,连接器会同步到所有登录了你 Claude 账户的设备(网页、桌面、移动设备)。密码门禁意味着即使陌生人发现了你的 URL,也无法在没有密码的情况下连接。MCP_AUTH_TOKEN 还兼作 JWT 签名密钥;将 AUTH_PASSWORD 留空即可禁用此方式。
以上所有操作都可通过 totem cloud 自动完成 — 这里的手动步骤仅供参考或手动操作时使用。
Cognito 过期时(约 30 天):在 Mac 上运行 totem auth。如果你的账户没有短信 MFA,认证会静默完成;如果有,则会提示输入验证码。它会自动检测你的部署并将新令牌推送到对应平台(Fly/Railway/Cloud Run/自定义平台),并在约 10 秒内重启。需要在装有仓库和平台 CLI 的计算机上操作。
安全性:Bearer 令牌和 OAuth 路径都会保护 /mcp。使用随机值生成令牌(openssl rand -hex 32),仅使用 HTTPS,切勿提交令牌;如果令牌泄露,请进行轮换。OAuth 访问令牌和刷新令牌是无状态的签名 JWT(重启后仍然有效);授权码为一次性使用,有效期为 60 秒;强制使用 PKCE S256。/health 是唯一无需身份验证的路径。
totem CLI
totem 是所有操作的唯一入口——没有 npm run 脚本。它可以从任意目录运行(会解析自身的安装路径),因此在 ~/Desktop 中运行 totem deploy,效果与运行 cd totem && fly deploy 相同。
# One-time, after cloning:
npm install && npx tsc && npm link # the only npm steps; `npx tsc` does the first build
totem # banner + full command list
按组划分的命令:
| 分组 | 命令 |
|---|---|
| 开始使用 | cloud ★(引导式服务端部署和 Claude 连接)· local(引导式本地设置) |
| 设置 | auth(登录并保存令牌——令牌过期时可重新运行以重新进行身份验证;自动检测本地还是已部署环境,并将新令牌推送到你的部署) |
| 已部署 | deploy · update(交互式版本选择器和自动更新)· logs · status · ping |
| 本地开发 | start [--http] · dev · dev:http · build · test · typecheck |
| 检查 | info · tools · config <stdio|http> |
| 帮助 | help · version(以及 --help、-v 别名) |
大多数人只需要两个开始使用命令,以及 auth(令牌过期时用于重新进行身份验证)。其他命令面向高级用户——例如,totem ping(“我的部署还在运行吗”)、totem logs、totem start(可直接替代 node dist/server.js)等。
保持最新——totem update。 这是一个交互式更新工具。运行后会显示版本选择器,按时间从新到旧列出所有版本,并从 GitHub Releases 获取发布日期和说明。默认选择最新版本;如果选择更早的版本,它会提醒你将落后哪些版本(你随时可以再次运行以升级)。选择后,工具会通过引导式动画构建来应用更改——通过 git 安装的版本会将 main 快进(或检出固定标签)、重新安装依赖并重新构建;通过 npm 安装的版本会重新安装所选版本——然后重新部署到现有主机,并对 /health 执行健康检查。需要保持工作区干净(不会覆盖本地修改);如果部署失败,线上服务不会受到影响。
成功更新到最新版本后,工具会提供自动更新选项。启用后,后台任务(macOS 上使用 launchd,Linux 上使用 cron)会每 6 小时检查一次新版本,并以相同方式应用更新——拉取、构建、重新部署、健康检查——日志写入 .totem-autoupdate.log。由于没有向你的设备推送更新的通道,因此这是一种定时轮询,而非即时更新。你可以随时直接切换此选项:
totem update # interactive: pick a version, then optionally enable auto-update
totem update --auto on # turn auto-update on (and pull the newest now)
totem update --auto off # turn it off
totem update --check # non-interactive: print installed-vs-latest + auto state
版本信息来自已有的托管来源——通过 git 安装的版本来自 git 标签和 GitHub Releases,全局安装的版本来自 npm registry——因此无需额外维护。自动更新为选择加入,仅会更新到已发布版本(每次发布都经过 CI 门控),绝不会更新到前沿的 main。
隐私 + 安全
- **凭据保存在你设备上的
.env中。**邮箱、密码、访问令牌、刷新令牌——绝不会离开你的文件系统。Claude 无法读取它们(除非你接入文件系统 MCP,否则它无法访问文件系统)。 - **所有出站流量都仅通过 HTTPS 发送至
api.prod.whoop.com。**没有遥测、分析或第三方服务器。该 MCP 是开源的——每一行涉及你数据的代码都可供审查。 - 写入安全性:所有写入工具默认将
confirm: false。预览内容包含将要发送的数据。执行任何更改前,你都能在聊天中查看。若要进一步加强安全性,请从src/tools/register.ts中移除特定写入工具,或启用 Claude Desktop 的“始终要求批准”设置。 - 在 1.2.3 版本中强化了安全性:令牌文件以
0600权限写入,登录后会从.env中清除你的账户密码,OAuth 令牌会绑定受众,并使用从MCP_AUTH_TOKEN派生的密钥签名,HTTP 服务器会发送防点击劫持和 CSP 标头,连接器密码验证设有全局暴力破解上限,部署密钥通过 stdin 推送(而非 argv)。详情请参阅SECURITY.md和CHANGELOG.md。
故障排除
“AUTH FAIL: Cognito InitiateAuth failed (400)”
邮箱或密码错误。请仔细检查
.env。
totem auth / totem cloud 在“Authenticating with Whoop…”后似乎卡住,或者正确的密码返回 401
你的密码几乎肯定包含
#。在 1.5.1 之前,.env中的值写入时没有加引号,而#会开始注释,因此#hunter2读回时会变成空字符串,abc#def则会变成abc。现已修复:写入值时会加引号,密码提示现在以原始模式绘制,因此不会再自行擦除。如果你有由旧版本写入的现有.env,其中的密码行仍未加引号——只需重新运行totem auth,并在提示时输入密码(系统会正确重写),或者手动加上引号:WHOOP_PASSWORD='#hunter2'。
“AUTH FAIL: Cognito MFA challenge missing Session token”
InitiateAuth 响应格式异常(较少见)。请重新运行
totem auth——Cognito 偶尔会丢失会话。
“MFA verification did not return tokens”
你输入的短信验证码错误(或已超时)。验证码约 3 分钟后过期。
每次调用后都出现“WhoopAuthExpiredError”
你的刷新令牌已过期(距上次登录超过 30 天)。请重新运行
totem auth——它会让你重新登录、在本地保存令牌,并且(如果你已部署)自动检测主机并一步将新令牌推送到主机。如果你的账户启用了 MFA,手机会收到新的短信验证码,请在终端中输入。
“WhoopServerError: 502” / “503” / “504”
Whoop 的服务器出现问题。请在 30 秒后重试。
Claude 提示它看不到任何 whoop 工具
检查
claude_desktop_config.json中的路径是否为绝对路径。完全重启 Claude Desktop(退出后重新打开)。 检查 MCP 服务能否无错误运行:totem dev——它应静默启动并等待 stdin 输入。
“WhoopApiError: 422 on /profile-service/v1/profile”
你的
whoop_profile_update请求体字段过少。请发送大多数字段(gender 仅可为 {MALE,FEMALE,NON_BINARY} 之一,birthday 格式为 YYYY-MM-DD 或 ISO datetime,country 使用 ISO-2)。如果country=US,还需发送state——否则 Whoop 会返回 400"AdminDivision (state) must be set for US"。
“Whoop API error 409 on /weightlifting-service/v2/weightlifting-workout/activity”
时间范围与现有锻炼记录冲突。请使用其他时间范围。
“WhoopProjectionError for whoop_X”
Whoop 更改了响应结构。请捕获新的响应(例如通过
whoop_raw),检查并更新投影。
git pull 后测试失败
拉取操作可能更新了捕获的固定数据。请再次运行
totem test,查看发生了哪些变化。如果需要更新投影,这就是要做的工作。
totem build(或 npx tsc)因“Top-level await is currently not supported with the 'cjs' output format”失败
你使用的是旧版 Node。请升级到 Node 24+。
“Error: ENOENT: no such file or directory, open '.env'”
在仓库根目录(或运行
dist/server.js的目录——MCP 会相对于入口文件加载.env)创建.env。
“Cannot find module '@modelcontextprotocol/sdk/server/mcp.js'”
请运行
npm install。
“AbortError: This operation was aborted”
向 Whoop API 发送的请求耗时超过 30 秒。可能是 Whoop 响应缓慢,也可能是你的网络较慢。请重试。
与其他方案的比较
| 方案 | 优点 | 缺点 |
|---|---|---|
| 此 MCP | 完整的 iOS API 表面(共 55 项:38 个读取接口 + 15 个写入接口 + 2 个备用接口),支持写入,输出结构化,自动刷新,写入安全防护,有限的读取缓存 | Whoop 不支持(具体含义请参阅 常见问题);通过逆向工程实现(Whoop 随时可能破坏其兼容性);需要本地安装 |
| Whoop 的公共 OAuth API | 官方支持,6 个 webhook 事件,权限范围可控 | 只有 13 个端点;仅支持读取;没有日记、力量、压力、教练、智能闹钟、趋势或睡眠阶段图;数字 sport_id 已于 2025-09-01 移除;存在 429 错误 |
| 基于 HealthKit 的抓取工具 | 完全绕过 Whoop;使用 Apple 的数据同步 | 无法获取 Whoop 专属数据(恢复分数、日记、教练);需要 iOS 设备参与 |
| 直接使用 mitmproxy 捕获 | 查看所有内容 | 需手动操作,无法编程,不便扩展 |
| Whoop iOS 应用 + 截图 → Claude | 无需编写代码即可使用 | 操作繁琐、速度慢、不支持写入 |
目前,此 MCP 是唯一能以编程方式写入 Whoop 数据的方案。
常见问题
问:Whoop 支持此方案吗?
答:不支持。此 MCP 通过 Whoop 的私有 iOS API 工作,这并非其面向第三方工具的公共接口。Whoop 的条款保留了对发现使用不受支持的集成方式的账户采取行动的权利——实际而言,这意味着暂停 API 访问权限或终止会员资格。作者已连续数周大量使用此 MCP,且流量模式看起来与正常应用使用情况相似,但这并无保证。如果丢失 Whoop 账户会给你带来麻烦,请勿使用。
问:为什么不改用 Whoop 的公共 OAuth API?
答:它只有 13 个端点,且全部仅支持读取;没有日记、力量、压力、教练、智能闹钟,也没有趋势数据(每天只有一个恢复分数)。Whoop 还在 2025-09-01 后移除了数字 sport_id(现在只提供 sport_name 字符串)。如果你只需要恢复分数、睡眠阶段总计和锻炼列表,OAuth API 就是合适的选择。
问:此方案适用于 Whoop 4.0 和 5.0 腕带吗?
答:适用——API 不关心你使用哪款腕带,只关心你的账户。
问:Whoop 6.0 呢?
答:它发布且 iOS 应用更新后,api 版本可能会从 7 升至 8。可能需要更新 MCP 的 constants.ts。最坏的情况是投影出错,到时修复即可。
问:我能在服务端、云端或常开设备上运行吗?
答:当然可以。MCP 不在乎运行位置。只需确保重启后 .env 文件仍然存在。
问:我能和朋友共享此 MCP 吗?
答:每位用户都需要使用自己的 Whoop 凭据配置 .env 文件。请勿共享令牌。
问:除了 stdio,还有 HTTP 传输方式吗?
答:有——设置 MCP_TRANSPORT=http,即可通过流式 HTTP 暴露 MCP,并由 bearer-token + OAuth 2.1 门控保护(自 v1.1.0 起支持)。请参阅远程托管。对于本地 Claude Desktop / Claude Code,stdio 仍是默认方式。
问:此方案支持 Claude 的 Computer Use API 吗?
答:此方案兼容 MCP——任何支持 MCP 的工具都能与其通信。
问:为什么使用 TypeScript,而不是 Python?
答:MCP SDK 在 TypeScript 中最成熟。此外,Whoop 的 API 响应嵌套层级很深——对于这类数据结构的校验工作,zod 确实是最好的校验库。
问:为什么必须使用 Node 24?
答:此方案使用了 import.meta.dirname(在 20.11 中新增)、现代 fetch、原生 ESM 和 AbortController。Node 18 可能可用;Node 16 则不行。
问:这花了多长时间?
答:v1 花了约 3 周的晚间和周末时间,之后又用了一周重写为 v2,加入了完善的投影和写入安全防护机制。
问:你会维护此项目吗?
答:尽力而为。欢迎提交 PR。
免责声明
- 与 Whoop 无关联。 “WHOOP” 是 WHOOP, Inc. 的商标。这是社区构建的工具,会与 Whoop 未公开发布的接口交互。实际影响请参阅 常见问题。
- 不提供担保,请自行决定是否使用。 API 接口是通过逆向工程得来的——Whoop 可以随时更改响应结构。zod 模式会将接口变更报告为
WhoopProjectionError,而不是让数据在无提示的情况下出错。 - 请遵守速率限制。 正常使用时,每秒请求数应为个位数。请不要触发后端警报,导致所有 MCP 用户都被封禁。
- 请勿分享令牌。 你的
.env属于你自己。不要提交它,也不要粘贴到任何地方。
致谢
- WHOOP,打造了值得通过逆向工程探索的健身平台
- Anthropic,提供了 MCP 和 Claude
- mitmproxy,让我们得以进行探索
- TypeScript + zod 社区,让严格验证也变得轻松
- 多年来记录 Whoop 私有 API 部分信息的各位 API 使用者和博主
本项目是开源项目,遵循 LICENSE 中的条款。欢迎贡献。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。