关于 whoop-mcp
whoop-mcp 是本地只读 MCP 服务,向 MCP 客户端提供 WHOOP v2 健身数据。它通过直接 OAuth 授权并使用本地 SQLite 缓存,可查询、同步和导出记录。
主要功能
- 01读取 WHOOP 个人资料和健身记录
- 02将数据缓存在本地 SQLite
- 03按需或增量同步记录
- 04通过 MCP 资源浏览缓存数据
- 05以 CSV、JSONL 或 Parquet 导出记录
适用场景
- 01查看每日睡眠、恢复和训练数据
- 02无需调用 API 查询缓存记录
- 03跟踪 WHOOP 记录的更新
- 04导出训练数据供外部分析
MCP 相关
向 MCP 客户端提供只读 WHOOP 数据工具,以及缓存记录的 JSON 资源。它直接向 WHOOP 进行身份验证,并将获取的数据保存在本地 SQLite 缓存中。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx whoop-mcpWHOOP_CLIENT_IDClient ID from your WHOOP developer app (https://developer-dashboard.whoop.com/apps/create).WHOOP_CLIENT_SECRET密钥Client secret from your WHOOP developer app. Used for OAuth token refresh.WHOOP_REDIRECT_URIOAuth redirect URI. Defaults to http://localhost:8000/callback — only change if you registered a different URI.WHOOP_LOG_LEVELLog level (DEBUG / INFO / WARNING / ERROR). Default INFO.WHOOP_LOG_FILEPath to the rotating log file. Set to empty string to disable file logging. Default ~/.whoop-mcp-server/logs/whoop-mcp.log.WHOOP_LOG_JSONStructured JSON logs (true) vs human-readable (false). Default true.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
WHOOP MCP Server
一个本地模型上下文协议(MCP)服务,为大模型提供对 WHOOP 健身数据的只读访问。身份验证通过你自己的 WHOOP 开发者应用直接使用 OAuth 完成,过程中不经过任何第三方代理。所有记录都会镜像到本地 SQLite 缓存 ~/.whoop-mcp-server/whoop.db 中,除服务自身向 WHOOP v2 API 发起的已认证调用外,数据绝不会离开你的设备。
当前版本:0.8.5 — 参见 CHANGELOG.md。
尚未达到 1.0 版本。 API 接口(工具名称、响应结构、错误代码)正在趋于稳定,但尚未冻结。在实际使用验证期间,
0.x次版本更新可能包含破坏性变更。补丁版本更新(0.8.x)仅修复错误。待接口在实际使用中稳定运行 2 周以上后,将发布 1.0.0。如果你基于此项目构建,请在 CI 中固定次版本。只想试用一下? 复制 docs/AGENT_INSTALL_PROMPT.md 中的提示词,将其粘贴到 Claude Code / Claude Desktop / Cursor / Windsurf,Agent 就会端到端完成安装。
基于此代码库构建? 请从 AGENTS.md 和 docs/ARCHITECTURE.md 开始阅读——它们介绍了核心约定和一页式系统概览。
目录
- 项目简介
- 安装(通过 uvx 一行命令完成)
- 使用 Agent 安装
- 从源码安装
- 分析技能:whoop-insights
- 快速开始
- 工具目录
- MCP 资源
- 数据模型
- 同步模式
- 事件流
- 导出
- 不支持的功能
- 更新
- 运维
- 安全与隐私
- 开发
- 面向基于此代码库构建的 Agent
- 版本管理
项目简介
WHOOP MCP Server 是一个通过 stdio 使用 MCP 通信的小型 Python 进程。它向任何支持 MCP 的客户端(主要是 Claude Desktop 和 Claude Code)提供 WHOOP v2 数据(个人资料、身体测量、周期、恢复、睡眠、训练)。该服务为只读服务。它使用你自行注册的 OAuth 应用向 WHOOP 进行身份验证,因此令牌不会经过任何第三方服务。获取的 WHOOP 记录会写入本地 SQLite 缓存(权限模式为 0o600),后续读取无需联网且不产生额外请求;缓存文件也绝不会离开你的设备。
安装(通过 uvx 一行命令完成)
# 1. Create a WHOOP developer app (one-time, free, self-serve):
# https://developer-dashboard.whoop.com/apps/create
# Redirect URI: http://localhost:8000/callback
# Scopes: read:profile read:body_measurement read:recovery
# read:cycles read:sleep read:workout offline
# 2. One-shot OAuth — opens browser, catches callback, saves encrypted tokens.
WHOOP_CLIENT_ID="<your client id>" \
WHOOP_CLIENT_SECRET="<your client secret>" \
uvx --from whoop-mcp whoop-mcp-oauth
# 3. Register with Claude Code. The --env flags are required so the
# server can refresh tokens when the 1-hour access token expires.
claude mcp add whoop --scope user \
--env WHOOP_CLIENT_ID="$WHOOP_CLIENT_ID" \
--env WHOOP_CLIENT_SECRET="$WHOOP_CLIENT_SECRET" \
-- uvx --from whoop-mcp whoop-mcp
无需克隆、无需创建 venv、无需使用绝对路径。还没有 uv?安装一次即可:
curl -LsSf https://astral.sh/uv/install.sh | sh(或运行 brew install uv)。
使用 Agent 安装
将 docs/AGENT_INSTALL_PROMPT.md 中的提示词粘贴到任何支持 MCP 的 Agent(Claude Code、Claude Desktop、Cursor、Windsurf、Zed、Aider)。Agent 会替你运行安装流程。
从源代码安装(用于开发)
git clone https://github.com/AshwanthramKL/whoop-mcp.git
cd whoop-mcp
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
.venv/bin/pytest -q # 183 tests, ~6s, all respx-mocked
然后使用 -- /abs/path/to/whoop-mcp/.venv/bin/python /abs/path/to/whoop-mcp/src/whoop_mcp_server.py 注册。
对于 Claude Desktop,将等效条目添加到
~/Library/Application Support/Claude/claude_desktop_config.json(macOS),
将 command 指向虚拟环境中的 Python,并将 args 指向 src/whoop_mcp_server.py。
如果想在干净环境中端到端快速检查安装流程(不包括浏览器 OAuth 流程),
请运行 ./scripts/fresh_install_check.sh。
快速开始
注册服务后,试试以下提示词:
- 同步缓存。“同步我过去 30 天的 WHOOP 数据。”
Claude 会调用
sync_whoop()并报告各资源的数量。 - 查看某一天。“给我昨天的 WHOOP 每日摘要。”
Claude 会调用
get_whoop_daily_summary(date="YYYY-MM-DD"),并显示 合并后的周期 + 恢复 + 主要睡眠 + 训练记录。 - 导出。“将我缓存的所有训练导出到
~/whoop-workouts.csv。” Claude 会调用export_whoop(kind="workouts", format="csv", path="...")。
分析技能:whoop-insights
随仓库附带:skills/whoop-insights。
安装(一条命令):
whoop-mcp-install-skills # writes to ~/.claude/skills/
该命令会从此仓库的 main 分支获取最新技能,并将其放到 Claude Code(以及 Cursor / Windsurf / Zed)会自动发现用户级技能的位置。重启 MCP 客户端会话,然后询问:
“我最近状态如何?运行 whoop-insights 技能。” “生成我的每周 WHOOP 报告。” “我是不是训练过度了?检查过去 30 天的数据。”
该技能会从缓存中提取 30 天的数据,计算个人基准值 (HRV、恢复、睡眠、负荷),基于证据标记异常,进行两项 相关性分析(睡眠→次日恢复、负荷→次日恢复),并可选择生成包含 Chart.js 可视化图表的独立 HTML 仪表板。每项结论都会引用具体日期和具体数值 ——该技能被要求绝不捏造信息。
对于直接在仓库中开发的人员,如果要迭代改进技能本身:
whoop-mcp-install-skills --source ./skills 会从本地
工作树而非 GitHub 安装。
工具目录
共 17 个工具。所有列表工具都接受 ISO-8601 格式的 start / end,并自动分页。
每个读取工具都接受 fresh: bool = False——传入 True 可绕过
缓存并调用 WHOOP API,将响应写入缓存,并返回实时响应。错误会以结构化的 {"error": {...}} 封装形式返回;
工具不会抛出异常。
| 工具 | 功能 | 关键参数 |
|---|---|---|
get_whoop_auth_status | 报告 OAuth 令牌状态。如果其他工具返回 AUTH_FAILED,请先调用此工具。 | — |
get_whoop_profile | 已验证身份的 WHOOP 用户资料(姓名、电子邮件)。 | fresh |
get_whoop_body_measurement | 最新身体测量数据:身高、体重、最大心率。 | fresh |
list_whoop_cycles | 指定时间范围内的生理周期。 | start、end、limit、fresh |
get_whoop_cycle | 按整数 ID 获取一个周期。 | cycle_id、fresh |
get_whoop_cycle_sleep | 获取与指定周期关联的睡眠记录。 | cycle_id、fresh |
get_whoop_cycle_recovery | 获取与指定周期关联的恢复记录。 | cycle_id、fresh |
list_whoop_recoveries | 指定时间范围内的恢复数据(HRV / RHR / 恢复评分)。 | start、end、limit、fresh |
list_whoop_sleeps | 指定时间范围内的睡眠活动,包括小睡。 | start、end、limit、fresh |
get_whoop_sleep | 按 UUID 获取一项睡眠活动。 | sleep_id、fresh |
list_whoop_workouts | 训练记录及各区间时长(秒)。 | start、end、limit、fresh |
get_whoop_workout | 按 UUID 获取一项训练记录。 | workout_id、fresh |
get_whoop_daily_summary | 获取某个 UTC 日期的周期、恢复、主要睡眠和训练汇总。 | date |
sync_whoop | 从 WHOOP API 刷新缓存。默认采用幂等增量同步。 | full、since、resources |
get_whoop_events | 按时间顺序显示缓存资源的“最新动态”。 | since、until、resources、limit |
export_whoop | 将缓存记录导出为 CSV / JSONL / Parquet。 | kind、format、path、start、end、overwrite |
health_check | 综合状态(身份验证、API、缓存、架构)。不会抛出异常。 | live |
错误代码:AUTH_FAILED、RATE_LIMITED、NOT_FOUND、UPSTREAM_ERROR、
VALIDATION_ERROR、CACHE_ERROR、CACHE_EMPTY、FILE_EXISTS、
EXPORT_ERROR、SYNC_ERROR。
MCP 资源
缓存也会作为只读 MCP 资源公开,因此客户端无需调用工具即可浏览日期范围内的数据。
| URI | 内容 |
|---|---|
whoop://db/cycles/{start}/{end} | [start, end) 内的缓存周期(日期格式为 YYYY-MM-DD)。 |
whoop://db/recoveries/{start}/{end} | 缓存的恢复数据。 |
whoop://db/sleeps/{start}/{end} | 缓存的睡眠数据(包括小睡)。 |
whoop://db/workouts/{start}/{end} | 缓存的训练记录。 |
whoop://db/profile | 最新的用户资料快照。 |
whoop://db/body_measurement | 最新的 body_measurement 快照。 |
whoop://db/sync_runs/{limit} | 最近的同步审计记录。 |
whoop://db/events/{since} | 从 since 开始的事件流,until = 当前时间。 |
whoop://db/events/{since}/{until} | 指定时间范围内的事件流。 |
所有资源均返回 application/json。无效输入会返回与工具相同的
{"error": {"code","message"}} 封装形式。
数据模型
响应经过扁平化处理:提取 WHOOP 的 score 封装层,将毫秒转换为秒(*_seconds,保留 1 位小数),将千焦转换为卡路里
(calories,四舍五入为整数),将心率字段重命名为 avg_hr_bpm /
max_hr_bpm,并将睡眠阶段命名为 deep_sleep_seconds、
rem_sleep_seconds、light_sleep_seconds、awake_seconds、
in_bed_seconds。移除原始 user_id、v1_id 和各记录的 created_at。
score_state 约定。 WHOOP 评分并非总是已计算完成。当
score_state != "SCORED"(例如 PENDING_SCORE、UNSCORABLE)时,所有
派生评分字段均为 null,并保留顶层 score_state,以便调用方了解原因。
每种资源提供一条扁平化记录:
// Cycle
{
"id": 123456,
"start": "2026-04-20T04:00:00.000Z",
"end": "2026-04-21T04:00:00.000Z",
"timezone_offset": "+00:00",
"score_state": "SCORED",
"strain": 12.4,
"avg_hr_bpm": 62,
"max_hr_bpm": 168,
"calories": 2810
}
// Recovery
{
"cycle_id": 123456,
"sleep_id": "bb68db7b-...",
"score_state": "SCORED",
"recovery_score": 74,
"resting_heart_rate_bpm": 48,
"hrv_rmssd_ms": 87.3,
"spo2_pct": 97.4,
"skin_temp_c": 33.1,
"user_calibrating": false
}
// Sleep
{
"id": "bb68db7b-...",
"cycle_id": 123456,
"start": "2026-04-20T03:10:00.000Z",
"end": "2026-04-20T10:42:00.000Z",
"nap": false,
"score_state": "SCORED",
"sleep_performance_pct": 88.0,
"in_bed_seconds": 27120.0,
"light_sleep_seconds": 12540.0,
"rem_sleep_seconds": 5280.0,
"deep_sleep_seconds": 6840.0,
"awake_seconds": 1080.0
}
// Workout
{
"id": "a91f...",
"start": "2026-04-20T17:00:00.000Z",
"end": "2026-04-20T17:48:00.000Z",
"sport_name": "Running",
"score_state": "SCORED",
"strain": 9.3,
"avg_hr_bpm": 142,
"max_hr_bpm": 176,
"calories": 511,
"distance_meter": 8030.0,
"zone_durations_seconds": {
"zone_zero": 0.0, "zone_one": 120.0, "zone_two": 900.0,
"zone_three": 1440.0, "zone_four": 420.0, "zone_five": 0.0
}
}
同步模型
- 缓存优先读取。 每个列表/获取工具默认从 SQLite 读取。 如果时间窗口为空,则会透明地触发定向同步并重新读取。
fresh=True会绕过缓存,调用 WHOOP API,将结果写入缓存,并返回实时响应。- 增量同步 使用每种资源的
MAX(updated_at)作为游标。 全新数据库会回退到最近 90 天。sync_whoop(full=True)会为每种资源拉取从 2010-01-01 开始的数据(全新缓存时执行一次即可)。 - 幂等。 如果上游没有新数据,重新运行
sync_whoop不会产生任何操作。结合快照哈希去重(见下文),事件流将保持安静。 - 快照哈希去重。
profile和body_measurement是单例快照。写入前,服务会比较规范化原始负载的 SHA-256 值与已存储的数据块。字节完全相同的负载不会推进updated_at,因此不会生成无关事件。
事件流
get_whoop_events(since, until=None, resources=None, limit=500) 是一个涵盖所有缓存资源的时间顺序事件流——纯缓存读取,不调用 API。时间窗口的两端均为开区间:
updated_at > since AND updated_at < until。严格的 since 边界意味着你可以将返回的游标作为下一个 since 传入,而不会再次看到同一行。
每个事件都包含一条扁平记录:
{"resource": "sleeps",
"id": "bb68db7b-...",
"updated_at": "2026-04-20T14:12:33.123Z",
"record": { "...flat sleep..." }}
响应:
{"status": "success", "count": 17,
"since": "...", "until": "...",
"events": [...],
"next_cursor": null | "<opaque-base64>"}
next_cursor 是对最后一个返回事件的 updated_at|resource|id 进行 Base64 编码后得到的不透明值。将其作为 since 传回即可继续获取。使用完整三元组作为带并列项处理的下界,因此在分页边界处,共享同一 updated_at 的事件不会被跳过。仍支持将普通 ISO-8601 字符串作为 since(兼容 M5)。
也可通过 MCP 资源访问——参见上方的 MCP 资源表格。
导出
export_whoop(kind, format, path, start=None, end=None, overwrite=False)
会将扁平缓存记录写入磁盘。纯数据层操作——不会调用 API。
请先运行 sync_whoop()。
kind:cycles|recoveries|sleeps|workouts|all。"all"会为每种资源写入一个文件(cycles.*、recoveries.*,……) 到指定目录。format:csv(RFC 4180,按字母顺序排序的表头,嵌套值以 JSON 编码)、jsonl(每行一条记录,键已排序)或parquet(pyarrow,snappy)。overwrite:默认为False。如果目标位置已有内容, 则返回FILE_EXISTS。设为True则会直接替换。
即使时间窗口为空,也会生成文件(仅含表头的 CSV/空 JSONL/ 空 Parquet),以便下游工具获得一致的产物。
不支持的内容
明确列出,避免有人白白提交 Issue。
| 请求 | 原因 |
|---|---|
claude.ai(Web 应用) | 我们以 stdio MCP(本地子进程)的形式提供。claude.ai 需要远程 HTTPS MCP。托管部署也会破坏我们的单用户/仅限本地威胁模型。 |
| Claude 移动应用 | 同样受 stdio 限制。 |
| 向 WHOOP 写入数据(记录活动、更新体重等) | 本项目在设计上仅支持读取。要添加写入功能,就必须使用通过逆向工程得出的端点,这些端点不属于 WHOOP 稳定的 v2 API,过于脆弱,也有违反服务条款的风险。如果需要此功能,请参阅 jd1207/whoop-mcp。 |
| 多用户/共享服务 | 一个用户、一个 WHOOP 账户、一台机器。缓存和加密令牌存放在 ~/.whoop-mcp-server/ 下;没有租户模型。 |
| 每个 WHOOP 开发者应用超过 10 名用户 | 在获得应用级审批前,WHOOP 开发者应用的用户上限为 10 名。每位用户都应创建自己的开发者应用——免费且可自行操作。 |
| 推送通知/webhook | 事件流由缓存轮询驱动。如需主动告警,可使用现有的任意调度器,通过 cron 运行 sync_whoop + get_whoop_events。 |
| Python < 3.10 | 代码使用 X | Y 联合类型语法。较旧版本的 Python 无法执行 pip install。 |
| Windows 专用安装路径 | 代码可以运行,但 OAuth 回调(localhost:8000)和路径处理尚未在 Windows 上经过实际测试。目前已测试的平台为 Ubuntu + macOS。 |
更新
MCP 服务不会自动更新。安装时使用的版本就是固定的版本。 如何获取新版本取决于安装方式:
| 安装方式 | 更新方法 |
|---|---|
uvx --from whoop-mcp whoop-mcp | 运行 uvx --refresh --from whoop-mcp whoop-mcp,或运行 uv cache clean whoop-mcp 后重新调用 |
uvx --from whoop-mcp@latest whoop-mcp | 缓存下次未命中时会自动更新(无需手动操作) |
pipx install whoop-mcp | pipx upgrade whoop-mcp |
pip install whoop-mcp | pip install --upgrade whoop-mcp |
| Git 克隆 + venv | git pull && pip install -r requirements.txt |
之后运行 health_check()——其中的 pypi_update_available 组件
会确认 MCP 客户端当前运行的版本,以及是否已发布
更新版本。
破坏性变更政策:项目处于 0.x 阶段时,次版本更新
(0.8.x → 0.9.0)可能包含破坏性变更——相关内容始终会在
CHANGELOG.md 的 ### Changed 部分中说明。补丁版本更新
(0.8.3 → 0.8.5)仅修复 bug。发布 1.0.0 后,
破坏性变更必须提升主版本号。如果无法接受频繁变更,请固定到已知可用的 0.x.y 版本。
运维
- 日志。 始终写入 stderr(结构化 JSON),并写入滚动文件
~/.whoop-mcp-server/logs/whoop-mcp.log(每个文件约 1 MB,保留 5 个备份)。 可通过环境变量覆盖:WHOOP_LOG_LEVEL(默认值INFO)、WHOOP_LOG_FILE(路径;空字符串表示禁用文件处理器)、WHOOP_LOG_JSON(默认值true)。 health_check(live=True)返回一个字典,包含五项组件检查 (auth、api_reachable、cache_readable、cache_writable、schema_version),以及总体判定healthy | degraded | unhealthy。live=False会跳过网络探测。- 令牌刷新。 当访问令牌将在 5 分钟内过期时,会自动使用刷新令牌。异步刷新锁
可防止多个并发请求发现同一令牌过期时同时刷新。如刷新无法恢复,
请重新运行
whoop-mcp-oauth(安装后运行pip install),或.venv/bin/python src/setup_direct_oauth.py(从源码运行)。 - 速率限制。 客户端会遵循 429 响应中的
Retry-After,并 采用指数退避策略重试。超过重试次数后,调用会返回RATE_LIMITED—— 工具不会抛出异常。
安全与隐私
所有操作都在本地运行。OAuth 令牌使用位于
~/.whoop-mcp-server/.encryption_key 的密钥加密后存储在
~/.whoop-mcp-server/tokens.json 中。SQLite 缓存文件以
0o600 模式创建。没有第三方服务——唯一的出站网络
调用直接发送到 api.prod.whoop.com。日志不包含
令牌、刷新令牌、客户端密钥或原始 WHOOP 响应正文。
请参阅 PRIVACY.md,了解服务读取、写入、发送和记录的
完整清单,以及如何删除所有内容
(rm -rf ~/.whoop-mcp-server)。
开发
# Run the full test suite (183 tests).
.venv/bin/pytest -q
# Re-record fixtures (live calls, requires creds in env).
.venv/bin/python tests/record_fixtures.py
# Fresh-install smoke test (clones current HEAD into a tempdir and
# verifies the install path end-to-end, minus the browser OAuth flow).
bash scripts/fresh_install_check.sh
添加新工具。 在 src/whoop_mcp_server.py 中添加实现,并使用
@mcp.tool() 装饰器;如果响应具有新的结构,则在 src/whoop_models.py
中添加 Pydantic 模型;如果资源需要持久化,则在 src/whoop_store.py 中
添加缓存表;并在 tests/ 中添加测试。保留错误封装
(_error_payload / _map_error)——工具绝不抛出异常。
发布流程。 更新 src/__version__.py(唯一真实来源)→
按照 Keep-a-Changelog 格式,在 CHANGELOG.md 顶部
添加新章节 → 确认 whoop_mcp_server.py 中的 SERVER_VERSION
已获取新值(test_version_import 测试可防止版本不一致)→ 更新
pyproject.toml 中的 version → 在 main 上创建标签
vX.Y.Z。
面向基于此仓库构建的 Agent
从这里开始:
- AGENTS.md — 关键约定。文件布局、 错误封装规范、TDD 循环、禁止事项、发布流程。 编辑任何内容前请先阅读。
- docs/ARCHITECTURE.md — 一页式系统 概览图。四层架构图、读写/同步/事件路径、不变量。
- docs/AGENT_INSTALL_PROMPT.md — 最终用户提供给其 Agent 以进行安装的可直接复制粘贴的提示词。
人类贡献者:简要指南见 CONTRIBUTING.md。
测试套件约需 6 秒运行(.venv/bin/pytest -q);所有 HTTP
调用都由 respx 模拟,因此你可以离线迭代。
版本管理
当前版本:0.8.5(见 src/__version__.py)。语义化
版本控制。完整历史记录:CHANGELOG.md。
致谢
由 RomanEvstigneev/whoop-mcp-server
(v0.1.x)分叉而来。从 v0.2.0 起进行了大幅重写,改用直接 WHOOP
OAuth(无第三方代理)、WHOOP v2 API、经 Pydantic 扁平化的
响应、本地 SQLite 缓存与增量同步、缓存优先读取、
事件流、导出(CSV/JSONL/Parquet)、health_check
工具、结构化 JSON 日志,以及 190 多项测试(截至 0.8.5 为 190 项)。采用 MIT 许可——两条版权声明均见
LICENSE。
mcp-name: io.github.AshwanthramKL/whoop-mcp
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。