
Whoop Mcp
io.github.AshwanthramKL由 GitHub 账号 AshwanthramKL 发布v0.8.5更新于 Oct 24, 2026
Read-only WHOOP v2 data for MCP clients, with local SQLite cache and CSV/JSONL/Parquet exports.
概览
本地运行的 WHOOP 只读 MCP 服务器,让助手读取恢复、睡眠、周期与训练数据并导出。
- 可以做什么
- 查询个人资料、身体测量、周期、恢复、睡眠与训练记录,并获取单日汇总摘要。
- 适用场景
- 当你想让 AI 助手读取并分析自己的 WHOOP 生理与健身数据(恢复、睡眠、周期、训练)时使用。适合在 Claude Desktop、Claude Code 等本地 MCP 客户端中做每日摘要、趋势查看或导出数据。
- 运行要求
- 需本地 Python 3.10 以上与 uv(以 uvx 运行)。需自行在 WHOOP 开发者后台创建应用,并设置环境变量 WHOOP_CLIENT_ID 与 WHOOP_CLIENT_SECRET;首次需完成一次浏览器 OAuth 授权。需能连接 WHOOP API。
安装
在 SourceWeft 中
- 打开 控制台中的 Whoop Mcp,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
WHOOP MCP Server
[CI] [PyPI] [Python 3.10+] [License: MIT] [MCP] [Tests]
A local Model Context Protocol (MCP) server that gives an LLM read-only
access to your WHOOP fitness data. Authentication is direct OAuth against
your own WHOOP developer app — there is no third-party proxy in the path.
All records are mirrored into a local SQLite cache at
~/.whoop-mcp-server/whoop.db, and no data ever leaves your machine
except for the authenticated calls the server itself makes to the WHOOP
v2 API.
Current version: 0.8.5 — see CHANGELOG.md.
Pre-1.0 status. The API surface (tool names, response shapes, error codes) is stabilizing but not frozen. Breaking changes may land in
0.xminor bumps during dogfooding. Patch bumps (0.8.x) are bugfix-only. 1.0.0 will be cut when the surface has been stable for 2+ weeks of real use. Pin the minor version in CI if you're building on top of this.
Just want to try it? Copy the prompt in docs/AGENT_INSTALL_PROMPT.md, paste it into Claude Code / Claude Desktop / Cursor / Windsurf, and your agent will do the install end-to-end.
Building on this repo? Start with AGENTS.md and docs/ARCHITECTURE.md — they're the load-bearing conventions and one-page system map.
Table of contents
- What this is
- Install (one line via uvx)
- Install with your agent
- Install from source
- Analysis skill: whoop-insights
- Quick start
- Tool catalog
- MCP resources
- Data model
- Sync model
- Event feed
- Exports
- What's not supported
- Updating
- Operations
- Security and privacy
- Development
- For agents building on this repo
- Versioning
What this is
The WHOOP MCP Server is a small Python process that speaks MCP over stdio.
It exposes WHOOP v2 data (profile, body measurement, cycles, recoveries,
sleeps, workouts) to any MCP-capable client — primarily Claude Desktop and
Claude Code. The server is read-only. It authenticates with WHOOP using an
OAuth app you register yourself, so your tokens never travel through a
third-party server. The WHOOP records you fetch are written to a local
SQLite cache (mode 0o600) so subsequent reads are free and offline, and
the cache file never leaves your machine.
Install (one line via uvx)
No clone, no venv, no absolute paths. Don't have uv? Install it once:
curl -LsSf https://astral.sh/uv/install.sh | sh (or brew install uv).
Install with your agent
Paste the prompt in docs/AGENT_INSTALL_PROMPT.md into any MCP-aware agent (Claude Code, Claude Desktop, Cursor, Windsurf, Zed, Aider). The agent will run the install for you.
Install from source (for development)
Then register with -- /abs/path/to/whoop-mcp/.venv/bin/python /abs/path/to/whoop-mcp/src/whoop_mcp_server.py.
For Claude Desktop, add the equivalent entry to
~/Library/Application Support/Claude/claude_desktop_config.json (macOS),
pointing command at the venv Python and args at src/whoop_mcp_server.py.
Run ./scripts/fresh_install_check.sh if you want a clean-env smoke
of the install path end-to-end (minus the browser OAuth flow).
Quick start
Once the server is registered, try these prompts:
- Sync the cache. "Sync my WHOOP data from the last 30 days."
Claude calls
sync_whoop()and reports per-resource counts. - Inspect a day. "Give me yesterday's WHOOP daily summary."
Claude calls
get_whoop_daily_summary(date="YYYY-MM-DD")and shows a joined cycle + recovery + primary sleep + workouts record. - Export. "Export all my cached workouts to
~/whoop-workouts.csv." Claude callsexport_whoop(kind="workouts", format="csv", path="...").
Analysis skill: whoop-insights
Bundled with the repo: skills/whoop-insights.
Install (one command):
That fetches the latest skill from this repo's main branch and drops
it where Claude Code (and Cursor / Windsurf / Zed) auto-discovers
user-scope skills. Restart your MCP client session and ask:
"How am I doing? Run the whoop-insights skill." "Generate my weekly WHOOP report." "Am I overtraining? Check the last 30 days."
The skill pulls 30 days from the cache, computes personal baselines (HRV, recovery, sleep, strain), flags anomalies with evidence, runs two correlations (sleep→next-day-recovery, strain→next-day-recovery), and optionally generates a self-contained HTML dashboard with Chart.js visualizations. Every claim cites a specific date and a specific number — the skill is instructed never to fabricate.
For repo-native developers iterating on the skill itself:
whoop-mcp-install-skills --source ./skills installs from your local
working tree instead of GitHub.
Tool catalog
17 tools. All list tools accept start / end as ISO-8601 and auto-paginate.
Every read tool takes fresh: bool = False — pass True to bypass the
cache and hit the WHOOP API, write-through to cache, and return the live
response. Errors are returned as a structured {"error": {...}} envelope;
tools never raise.
Error codes: AUTH_FAILED, RATE_LIMITED, NOT_FOUND, UPSTREAM_ERROR,
VALIDATION_ERROR, CACHE_ERROR, CACHE_EMPTY, FILE_EXISTS,
EXPORT_ERROR, SYNC_ERROR.
MCP resources
The cache is also exposed as read-only MCP resources, so the client can browse date slices without invoking a tool.
All resources return application/json. Bad inputs return the same
{"error": {"code","message"}} envelope used by tools.
Data model
Responses are flattened: the WHOOP score wrapper is lifted, milliseconds
become seconds (*_seconds, 1 decimal), kilojoules become calories
(calories, rounded int), heart-rate keys are renamed to avg_hr_bpm /
max_hr_bpm, and sleep stages are named deep_sleep_seconds,
rem_sleep_seconds, light_sleep_seconds, awake_seconds,
in_bed_seconds. Raw user_id, v1_id, and per-record created_at are
dropped.
score_state convention. WHOOP scores are not always computed. When
score_state != "SCORED" (e.g. PENDING_SCORE, UNSCORABLE) every
derived score field is null and the top-level score_state is preserved
so callers know why.
One flattened record per resource:
Sync model
- Cache-first reads. Every list/get tool reads from SQLite by default. An empty window transparently triggers a targeted sync and re-reads.
fresh=Truebypasses the cache, hits the WHOOP API, write-throughs the result into the cache, and returns the live response.- Incremental sync uses
MAX(updated_at)per resource as the cursor. A fresh DB falls back to the last 90 days.sync_whoop(full=True)pulls from 2010-01-01 for every resource (do this once on a brand-new cache). - Idempotent. Re-running
sync_whoopwith no new upstream data is a no-op. Combined with snapshot hash dedupe (below), this means the event feed stays quiet. - Snapshot hash dedupe.
profileandbody_measurementare singleton snapshots. Before writing, the server compares SHA-256 of the canonical raw payload against the stored blob. Byte-identical payloads do not advanceupdated_at, so no spurious events are generated.
Event feed
get_whoop_events(since, until=None, resources=None, limit=500) is a
chronological feed across all cached resources — pure cache read, no API
calls. The window is exclusive on both ends:
updated_at > since AND updated_at < until. The strict since bound
means you can feed a returned cursor back in as the next since without
re-seeing a row.
Each event wraps a flat record:
Response:
next_cursor is an opaque base64 encoding of
updated_at|resource|id for the last returned event. Pass it back as
since to continue. The full triple is used as a tie-broken lower bound,
so events sharing an updated_at are never skipped at a pagination
boundary. Plain ISO-8601 strings as since still work (M5 compat).
Also exposed as MCP resources — see the MCP resources table above.
Exports
export_whoop(kind, format, path, start=None, end=None, overwrite=False)
writes flat cached records to disk. Pure data layer — never hits the API.
Run sync_whoop() first.
kind:cycles|recoveries|sleeps|workouts|all."all"writes one file per resource (cycles.*,recoveries.*, …) into the given directory.format:csv(RFC 4180, alphabetically sorted header, nested values JSON-encoded),jsonl(one record per line, sorted keys), orparquet(pyarrow, snappy).overwrite: defaultFalse. If the destination has content, returnsFILE_EXISTS.Truereplaces silently.
An empty window still yields a file (header-only CSV / empty JSONL / empty Parquet) so downstream tooling sees a consistent artifact.
What's not supported
Spelled out so nobody wastes an issue.
Updating
MCP servers don't auto-update. When you installed is when you pinned. How to pick up a new release depends on how you installed:
Run health_check() afterwards — its pypi_update_available component
will confirm the version your MCP client is now running and whether a
newer one is published.
Breaking-change policy: while the project is 0.x, minor bumps
(0.8.x → 0.9.0) may include breaking changes — always called out in
the ### Changed section of CHANGELOG.md. Patch
bumps (0.8.3 → 0.8.5) are bugfix-only. Once we cut 1.0.0,
breaking changes require a major bump. Pin to a known-good 0.x.y if
you can't absorb churn.
Operations
- Logs. Stderr (always, structured JSON) plus a rotating file at
~/.whoop-mcp-server/logs/whoop-mcp.log(~1 MB per file, 5 backups). Env overrides:WHOOP_LOG_LEVEL(defaultINFO),WHOOP_LOG_FILE(path; empty string disables the file handler),WHOOP_LOG_JSON(defaulttrue). health_check(live=True)returns a dict with five component checks (auth,api_reachable,cache_readable,cache_writable,schema_version) plus an overall verdicthealthy | degraded | unhealthy.live=Falseskips the network probe.- Token refresh. Refresh tokens are used automatically when the
access token is within 5 minutes of expiry. An async refresh lock
prevents stampedes when multiple in-flight requests discover the same
expired token. If refresh fails beyond recovery, re-run
whoop-mcp-oauth(afterpip install) or.venv/bin/python src/setup_direct_oauth.py(from source). - Rate limiting. The client respects
Retry-Afteron 429s and retries with exponential backoff. After the retry budget, the call surfaces asRATE_LIMITED— tools never raise.
Security and privacy
Everything runs locally. OAuth tokens are encrypted at rest in
~/.whoop-mcp-server/tokens.json with a key at
~/.whoop-mcp-server/.encryption_key. The SQLite cache file is created
with mode 0o600. No third-party services — the only outbound network
calls are directly to api.prod.whoop.com. Logs do not include
tokens, refresh tokens, the client secret, or raw WHOOP response bodies.
See PRIVACY.md for the complete inventory of what the
server reads, writes, sends, and logs; and how to delete everything
(rm -rf ~/.whoop-mcp-server).
Development
Adding a new tool. Add the implementation under src/whoop_mcp_server.py
with an @mcp.tool() decorator, a Pydantic model in src/whoop_models.py
if the response has a new shape, a cache table in src/whoop_store.py if
the resource is persisted, and tests in tests/. Keep the error envelope
(_error_payload / _map_error) — tools never raise.
Release flow. Bump src/__version__.py (single source of truth) →
add a new top section to CHANGELOG.md in
Keep-a-Changelog format → verify SERVER_VERSION in
whoop_mcp_server.py picks up the new value (the test_version_import
test prevents drift) → update version in pyproject.toml → tag
vX.Y.Z on main.
For agents building on this repo
Start here:
- AGENTS.md — load-bearing conventions. File layout, error-envelope discipline, TDD loop, what-not-to-do, release flow. Read before editing anything.
- docs/ARCHITECTURE.md — one-page system map. Four-layer diagram, read/write/sync/event paths, invariants.
- docs/AGENT_INSTALL_PROMPT.md — the copy-pasteable prompt end users give their agent to install.
Human contributors: CONTRIBUTING.md has the short
version. The test suite runs in ~6s (.venv/bin/pytest -q); every HTTP
call is respx-mocked so you can iterate offline.
Versioning
Current version: 0.8.5 (see src/__version__.py). Semantic
versioning. Full history: CHANGELOG.md.
Credits
Forked from RomanEvstigneev/whoop-mcp-server
(v0.1.x). Substantially rewritten starting at v0.2.0 to use direct WHOOP
OAuth (no third-party proxy), the WHOOP v2 API, Pydantic-flattened
responses, a local SQLite cache with incremental sync, cache-first
reads, an event feed, exports (CSV/JSONL/Parquet), a health_check
tool, structured JSON logging, and 190+ tests (190 as of 0.8.5). Licensed MIT — see
LICENSE for both copyright lines.
mcp-name: io.github.AshwanthramKL/whoop-mcp
来源:README.md,提交 a34d3eb
工具
0版本历史
1- v0.8.5最新Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分