whoop-mcp
WHOOP MCP Server (read-only)
Ask Claude, Cursor, VS Code or any MCP client about your WHOOP recovery, HRV, sleep, strain and workouts, without giving it any way to change your data.
"How did I sleep last night, and why is my recovery only 41% today?" "Compare my HRV and resting heart rate over the last 30 days." "How many runs did I do this month, and what was my average strain?" "Do I recover worse after days with strain above 15?"
(Run the one-time auth step before or after installing.)
Why this server
Read-only, enforced. It requests only WHOOP's
read:*scopes. The HTTP client can only sendGET, a test fails the build otherwise, and every tool carriesreadOnlyHint: true.Answers whole questions in one call.
get_daily_overviewreturns a day's recovery, sleep, naps, strain and workouts together.get_trendsreturns averages, ranges and recovery zones over up to 90 days.Model-friendly output. It returns compact JSON with hours, km, kcal and local times instead of milliseconds and kilojoules, which saves tokens and avoids conversion mistakes. Pass
raw: truefor WHOOP's original objects.Your tokens stay on your machine. Your own WHOOP developer app, a
0600token file, and safe handling of WHOOP's rotating refresh tokens. No third-party servers.Current API. It's built on the WHOOP Developer API v2.
Tested. Unit, MCP integration, end-to-end and packaging tests run on Linux, macOS and Windows with Node 20, 22 and 24.
Related MCP server: whoop-ai-mcp
Quick start
You need Node.js 20.11+ and a WHOOP membership.
1. Create a WHOOP developer app (2 minutes)
Open the WHOOP Developer Dashboard and create a team if prompted.
Scopes: select all the
read:*scopes (recovery, cycles, workout, sleep, profile, body measurement).Redirect URI:
http://localhost:8787/callback
Copy the Client ID and Client Secret.
2. Connect your WHOOP account
npx -y @oryanomer/whoop-mcp authPaste your Client ID and Client Secret when asked. The secret isn't echoed, so it stays out of your screen and shell history. Your browser then opens WHOOP's consent page. When you approve, the tokens are saved to ~/.config/whoop-mcp/tokens.json and refreshed automatically from then on.
(For scripts, you can set WHOOP_CLIENT_ID and WHOOP_CLIENT_SECRET in the environment instead of answering the prompts.)
3. Add it to your MCP client
claude mcp add whoop --scope user -- npx -y @oryanomer/whoop-mcpOne click: download whoop-mcp-<version>.mcpb from the latest release and double-click it (or drag it onto Claude Desktop's Settings → Extensions page).
Or by hand: open Settings → Developer → Edit Config, and add:
{
"mcpServers": {
"whoop": {
"command": "npx",
"args": ["-y", "@oryanomer/whoop-mcp"]
}
}
}Restart Claude Desktop. On Windows, if the server doesn't start, use "command": "cmd" and "args": ["/c", "npx", "-y", "@oryanomer/whoop-mcp"].
Click the Install in Cursor button above, or add this to ~/.cursor/mcp.json:
{
"mcpServers": {
"whoop": {
"command": "npx",
"args": ["-y", "@oryanomer/whoop-mcp"]
}
}
}Click the Install in VS Code button above, or add this to .vscode/mcp.json (or your user mcp.json):
{
"servers": {
"whoop": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@oryanomer/whoop-mcp"]
}
}
}Add this to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"whoop": {
"command": "npx",
"args": ["-y", "@oryanomer/whoop-mcp"]
}
}
}Add this to ~/.codex/config.toml:
[mcp_servers.whoop]
command = "npx"
args = ["-y", "@oryanomer/whoop-mcp"]Run auth on the host first (step 2), then mount the token directory:
docker build -t whoop-mcp https://github.com/oryanomer1/whoop-mcp.git
docker run -i --rm -v ~/.config/whoop-mcp:/home/node/.config/whoop-mcp whoop-mcpUse the docker run command as the stdio command in your MCP client.
Run npx -y @oryanomer/whoop-mcp as a stdio server. No environment variables are needed: the client ID and secret are stored with your tokens during auth.
Then ask: "Give me my WHOOP overview for today."
Tools
Tool | What it returns |
| One day's recovery, sleep, naps, strain, calories and workouts (defaults to today) |
| Day-by-day table plus avg/min/max for recovery, HRV, resting HR, strain, sleep and more, over 1–90 days |
| Name, email, height, weight, max heart rate |
| Physiological days: strain, calories, average/max heart rate, steps |
| Recovery %, HRV (RMSSD), resting heart rate, SpO2, skin temperature |
| Sleep performance, efficiency, consistency, stages, disturbances, respiratory rate, sleep need |
| Sport, duration, strain, heart rate, calories, distance, time in heart-rate zones (filterable by sport) |
List tools accept start / end (YYYY-MM-DD or ISO date-time), a days shortcut, limit (up to 200, with automatic pagination) and next_token. See the tool reference for every parameter and example outputs.
Configuration
Variable | Default | Purpose |
| from token file | Your app's client ID ( |
| from token file | Your app's client secret ( |
|
| Must exactly match a redirect URI registered on your app |
|
| Where credentials are stored. Must be absolute ( |
whoop-mcp Start the MCP server on stdio (what your MCP client runs)
whoop-mcp auth Connect your WHOOP account (opens your browser)
whoop-mcp status Check the stored connection
whoop-mcp logout Delete the locally stored tokens
whoop-mcp --versionAll commands run via npx -y @oryanomer/whoop-mcp <command>, or install globally with npm install -g @oryanomer/whoop-mcp.
Privacy and security
Read the full Privacy Policy. In short:
whoop-mcp talks only to
api.prod.whoop.com. There is no telemetry and no intermediary server.Tokens and your client secret live in one file that only your user can read (
0600). They are never logged or returned by tools.Your MCP client sends tool results to its language model. Health data you ask about is shared with that model provider under its terms, so use a client and provider you trust.
To disconnect, run
whoop-mcp logoutto delete the local tokens. To revoke access completely, delete the app or rotate its secret in the WHOOP Developer Dashboard.
The full threat model is in SECURITY.md. Please report vulnerabilities privately through GitHub security advisories.
How authentication works
WHOOP access tokens last one hour. whoop-mcp refreshes them about a minute before they expire, and again if WHOOP returns a 401.
WHOOP issues a new refresh token on every refresh and rejects concurrent refreshes. whoop-mcp refreshes one request at a time, takes a lock file so several clients on one machine (e.g. Claude Desktop and Claude Code) never refresh at once, and writes new tokens atomically. If a write fails, the new tokens stay in memory, so a full disk can't log you out.
Rate limits (429), WHOOP server errors, timeouts (30s per request) and network errors are retried with backoff, honouring
Retry-After. Cancelling a request in your client stops its WHOOP calls.
Troubleshooting
Symptom | Fix |
WHOOP's sign-in page shows | Your browser has too many |
WHOOP shows an error about the redirect URI | The redirect URI on your WHOOP app must match |
| Register another URI on your app (e.g. |
Tool error | Run the |
Tool error | Run |
Tool error | Enable all |
Values missing, | WHOOP hasn't finished scoring that sleep, recovery or workout. Ask again later. |
The server doesn't appear in the client | Run |
Check the connection at any time:
npx -y @oryanomer/whoop-mcp statusUninstall
npx -y @oryanomer/whoop-mcp logoutThen remove the whoop entry from your MCP client's config, and delete the app in the WHOOP Developer Dashboard if you no longer need it.
Contributing
Issues and pull requests are welcome; see CONTRIBUTING.md. The one hard rule: whoop-mcp stays read-only. Release notes are in CHANGELOG.md.
Privacy policy
See PRIVACY.md.
Disclaimer
This is an unofficial project, not affiliated with or endorsed by WHOOP, Inc. "WHOOP" is a trademark of WHOOP, Inc. Nothing here is medical advice.
License
MIT © Oryan Omer
Available Tools
10 toolsget_cycleGet cycleBRead-onlyIdempotent
One physiological cycle by id, together with its recovery and main sleep.
| Name | Required | Description | Default |
|---|---|---|---|
| raw | No | Return WHOOP's raw API objects instead of compact summaries with friendly units. | |
| cycle_id | Yes | Cycle id (from list_cycles or get_daily_overview). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, open-world, non-destructive, so safety is covered. The description adds the genuinely useful fact that the response bundles related recovery and main sleep data, but says nothing about the raw flag's effect or behavior for a missing/invalid id.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with no filler; the resource and the id scoping are front-loaded before the bundled-data note.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully signals that recovery and main sleep come back alongside the cycle. Annotations carry the safety profile, so the only real gap is error behavior on an unknown id.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented, including where cycle_id comes from and what raw does. The description adds no additional parameter meaning, making the baseline 3 correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific resource (physiological cycle), the retrieval scope (one, by id), and the payload composition (recovery + main sleep). That distinguishes it from list_cycles and get_sleep/get_recovery without naming them explicitly, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No statement of when to use this versus list_cycles, get_daily_overview, list_recoveries, or get_sleep. The only routing hint ('from list_cycles or get_daily_overview') lives in the cycle_id schema field, not the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_daily_overviewDaily overviewARead-onlyIdempotent
Everything for one WHOOP day: recovery (score, HRV, resting HR, SpO2, skin temp), last night's sleep, naps, day strain and calories, and workouts. Omit date for the current/latest day.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Day to show (YYYY-MM-DD), i.e. the day you woke up on. Defaults to the latest day. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds value beyond that by enumerating the returned content (HRV, resting HR, SpO2, skin temp, naps, strain) — important since there is no output schema — but says nothing about auth, rate limits, or missing-data behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no waste, and the core purpose (full day aggregate) is front-loaded ahead of the parameter hint. Every clause earns its place by naming a returned data domain.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-optional-parameter, read-only aggregate tool with no output schema, the description supplies exactly what the agent needs: what comes back and how to default the date. Nothing required to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents the YYYY-MM-DD format and the default-to-latest behavior, so the description's date note is largely redundant with structured data. Baseline 3 is appropriate when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb+resource (aggregated 'everything for one WHOOP day') and enumerates the exact domains returned: recovery, sleep, naps, strain/calories, workouts. This makes it clearly distinguishable from siblings like list_recoveries, list_sleeps, and get_workout, which each cover only one domain.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete usage rule for the single parameter ('Omit date for the current/latest day'), which is the main decision an agent must make. It implies when to use this over the per-domain listers but never names an alternative tool explicitly, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_profileGet WHOOP profileARead-onlyIdempotent
The user's WHOOP profile (name, email) and body measurements (height, weight, max heart rate).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered structurally. The description still adds real value by disclosing what the call returns (profile identity fields plus body measurements), which matters because no output schema exists. It does not mention auth scope or whether values can be stale, so it falls short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; the returned data is the first and only thing stated. Nothing is wasted and nothing needs reordering.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With zero parameters and no output schema, the description's main job is to convey what comes back, and it does so by listing the identity and body-measurement fields. It is complete enough to call correctly, with only minor omissions around data freshness and auth scope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4 and there is no argument surface the description needs to explain. Nothing in the description misrepresents or over-promises on inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the specific resource (the user's WHOOP profile) and enumerates its contents (name, email, height, weight, max heart rate), so an agent can immediately tell this apart from the cycle/sleep/recovery/workout siblings. The retrieval verb comes from the name and title rather than the description text itself, which keeps it just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: because every sibling covers a different resource (daily overview, trends, cycles, sleeps, workouts), an agent can infer this is the tool for static account/body data. There is no explicit when-to-use, no prerequisites, and no named alternative or exclusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_sleepGet sleepCRead-onlyIdempotent
One sleep or nap by id.
| Name | Required | Description | Default |
|---|---|---|---|
| raw | No | Return WHOOP's raw API objects instead of compact summaries with friendly units. | |
| sleep_id | Yes | Sleep id (UUID). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is fully covered by structured data. The description adds nothing on top of that—no note on what the compact vs raw response contains or any auth/rate context—so it earns little credit beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single six-word sentence with zero waste and the key noun-verb information front-loaded. It is efficient, though arguably terse to the point of under-specification for a tool with two parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complexity is low and the schema plus annotations carry most of the load, but with no output schema the description could still say what a sleep record contains or how compact versus raw output differs. Given the rich annotations and full schema coverage, a 3 is adequate but not complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both the UUID sleep_id and the raw flag are fully documented in the schema itself (including that raw returns WHOOP's unprocessed objects). The description adds no parameter meaning beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"One sleep or nap by id" states the resource (sleep/nap record) and that retrieval is by a single identifier, implying a point-fetch. However, the phrasing is minimal and never explicitly distinguishes this from the sibling list_sleeps, so the agent must infer the singular-vs-list split from the word "One".
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no stated when-to-use guidance, no mention of when to prefer list_sleeps instead, and no prerequisites. The "by id" fragment hints that an identifier is required, but no alternative is named or contrasted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_trendsTrendsBRead-onlyIdempotent
Day-by-day table and averages (avg/min/max) over the last N days for recovery, HRV, resting HR, strain, calories, sleep hours and sleep performance, plus recovery zone counts and workouts per day.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | How many days to look back (1-90). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds useful context about what is returned (day-by-day table plus avg/min/max aggregates), which goes beyond the annotations, but says nothing about pagination, auth, or data freshness.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single dense sentence that front-loads the return shape and enumerates metrics without padding. Efficient, though the enumeration is long and could be grouped more tightly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of explaining return values and does so thoroughly (table + averages + zone counts + workouts/day). The remaining gap is the absence of usage guidance relative to the many sibling tools, which an agent would need when choosing among them.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single 'days' parameter is fully documented in the schema (1-90, default 7). The description only alludes to it via 'the last N days', adding no syntax or semantics beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (get trends) and enumerates the metrics returned (recovery, HRV, resting HR, strain, calories, sleep hours, sleep performance, zone counts, workouts/day). It's clear what the tool produces, but it never distinguishes itself from siblings like get_daily_overview or list_recoveries, which could plausibly cover overlapping data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no indication of when this aggregate view is preferable to the per-entity siblings (list_recoveries, list_sleeps, get_workout), and no exclusions. The agent must infer usage purely from the output description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_workoutGet workoutCRead-onlyIdempotent
One workout by id.
| Name | Required | Description | Default |
|---|---|---|---|
| raw | No | Return WHOOP's raw API objects instead of compact summaries with friendly units. | |
| workout_id | Yes | Workout id (UUID). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld, and non-destructive behavior. The description adds no behavioral context beyond annotations, such as error behavior for missing IDs or the effect of the raw parameter on returned data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely short, with no wasted words, but it is a fragment that under-specifies rather than concisely covering necessary context. It is front-loaded but lacks structure for an agent needing more than a label.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple retrieval tool with rich schema and annotations, the description is minimally adequate but omits useful context about raw versus compact output and return shape. Since there is no output schema, some return-value context would be expected, and it is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so workout_id and raw are fully documented in the schema. The description only repeats 'by id' and does not add meaning beyond the schema, which meets the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the resource (workout), scope (one), and selection key (id), making the purpose clear enough to distinguish from list-style siblings. It lacks an explicit verb and does not name alternatives like list_workouts, but the intent is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus list_workouts or other siblings. The description implies retrieval by known ID but does not state prerequisites or when to prefer it over discovery tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_cyclesList cycles (day strain)ARead-onlyIdempotent
Physiological cycles (WHOOP days) with day strain, calories, average/max heart rate and steps, most recent first.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Upper bound: a date (YYYY-MM-DD) includes that whole day; a date-time is exclusive. Defaults to now. | |
| raw | No | Return WHOOP's raw API objects instead of compact summaries with friendly units. | |
| days | No | Shortcut for start: look back this many days from now. Ignored when start is set. | |
| limit | No | Maximum number of records to return. | |
| start | No | Inclusive lower bound: a date (YYYY-MM-DD, local midnight) or ISO 8601 date-time. | |
| next_token | No | Pass the next_token from a previous call to get the following records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is covered. The description adds genuinely new behavior beyond that: results are returned 'most recent first', which the agent cannot learn from the schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence naming the resource first, then the returned fields, then the ordering. Every clause earns its place with no filler or restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only paginated list tool with no output schema, the description usefully enumerates the returned fields and the sort order, and the schema fully documents filtering and pagination. Only the absence of sibling routing and any explicit usage framing keeps it short of complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for all six parameters, including the date-bound semantics, days shortcut, limit and next_token pagination, so the schema carries the parameter burden. The description adds nothing parameter-specific, which is the expected baseline of 3 here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (list) and resource (physiological cycles / WHOOP days) and enumerates the payload fields (day strain, calories, HR, steps). This clearly separates it from get_cycle (singular), but it never explicitly distinguishes itself from the other list_* siblings such as list_recoveries or list_sleeps.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the reader infers you call this to page through recent daily cycles, and the schema's next_token/limit/days fields reinforce that. There is no explicit when-to-use statement, no prerequisite, and no pointer to an alternative tool for a narrower query.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_recoveriesList recoveriesARead-onlyIdempotent
Daily recovery scores with HRV (RMSSD), resting heart rate, SpO2 and skin temperature, most recent first.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Upper bound: a date (YYYY-MM-DD) includes that whole day; a date-time is exclusive. Defaults to now. | |
| raw | No | Return WHOOP's raw API objects instead of compact summaries with friendly units. | |
| days | No | Shortcut for start: look back this many days from now. Ignored when start is set. | |
| limit | No | Maximum number of records to return. | |
| start | No | Inclusive lower bound: a date (YYYY-MM-DD, local midnight) or ISO 8601 date-time. | |
| next_token | No | Pass the next_token from a previous call to get the following records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (read-only, idempotent, non-destructive). The description adds ordering and metric scope, but says nothing about pagination behavior (next_token) or raw-vs-summary output, though those are documented in the schema descriptions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that carries the metric list and ordering with zero waste. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete enough for a read-only list tool: what it returns, in what order, and the metrics. Missing only explicit tie to the raw/summary and pagination behaviors, which the schema covers. No output schema, but the description enumerates the fields, so return shape is sufficiently implied.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameter meaning is already fully documented in the schema (start/end/days/limit/next_token/raw). The description adds no parameter details beyond the schema baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific resource (daily recovery scores), enumerates the exact metrics returned (HRV/RMSSD, RHR, SpO2, skin temp), and states sort order. Clearly distinguished from siblings like list_cycles, list_sleeps, list_workouts, which return different resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the resource list and 'most recent first' ordering, but there is no explicit when-to-use vs alternatives such as get_daily_overview or get_trends, and no note on when to prefer one over the other.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sleepsList sleepsARead-onlyIdempotent
Sleeps and naps with performance, efficiency, consistency, stage breakdown (light/deep/REM/awake), disturbances, respiratory rate and sleep need, most recent first.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Upper bound: a date (YYYY-MM-DD) includes that whole day; a date-time is exclusive. Defaults to now. | |
| raw | No | Return WHOOP's raw API objects instead of compact summaries with friendly units. | |
| days | No | Shortcut for start: look back this many days from now. Ignored when start is set. | |
| limit | No | Maximum number of records to return. | |
| start | No | Inclusive lower bound: a date (YYYY-MM-DD, local midnight) or ISO 8601 date-time. | |
| next_token | No | Pass the next_token from a previous call to get the following records. | |
| include_naps | No | Set false to return only main sleeps. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the read-only, idempotent, non-destructive profile, and the description adds real context beyond them: the exact metrics returned (performance, efficiency, stage breakdown, disturbances, respiratory rate, sleep need) and the sort order. It still omits pagination/truncation behavior, which matters for a list tool with a limit and next_token.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence naming the resource first, then what it returns, with zero filler or hedging. The metric enumeration is dense but each item is substantive, so nothing meaningful could be cut without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully compensates by listing the returned fields, and the default-inclusion of naps is implied by mentioning both sleeps and naps. What is missing is any statement about paging or result-size behavior for a 7-parameter, optional-everything list endpoint.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so dates, days, limit, raw, next_token and include_naps are all documented in the schema itself. The description adds no parameter-level detail (e.g. how 'raw' affects the field list it enumerates), so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource ('sleeps and naps') and enumerates the specific metrics returned, which cleanly separates it from siblings like list_recoveries and list_cycles. It does not explicitly name those siblings or state a list-verb, so an agent still infers 'list all sleeps in a window' rather than being told directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of when to prefer get_sleep for a single record, and no guidance on paging through large result sets. The only usage-adjacent signal is the ordering note ('most recent first'), which is behavioral rather than a usage rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_workoutsList workoutsBRead-onlyIdempotent
Workouts with sport, duration, strain, heart rate, calories, distance, altitude gain and time in each heart-rate zone, most recent first.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Upper bound: a date (YYYY-MM-DD) includes that whole day; a date-time is exclusive. Defaults to now. | |
| raw | No | Return WHOOP's raw API objects instead of compact summaries with friendly units. | |
| days | No | Shortcut for start: look back this many days from now. Ignored when start is set. | |
| limit | No | Maximum number of records to return. | |
| sport | No | Only return workouts whose sport name contains this text (case-insensitive), e.g. "running". Applied to the fetched records, so raise limit or widen the range to search further back. | |
| start | No | Inclusive lower bound: a date (YYYY-MM-DD, local midnight) or ISO 8601 date-time. | |
| next_token | No | Pass the next_token from a previous call to get the following records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, idempotentHint, non-destructive and openWorld, so the safety profile is covered. The description adds the useful default sort order, but says nothing about pagination (next_token exists) or how limit/start/days interact, which are the behaviors an agent most needs to reason about.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, tightly packed sentence with the resource and ordering front-loaded and no wasted words. It is a noun phrase rather than a full sentence, but that costs nothing in clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the field enumeration (sport, duration, strain, heart rate, calories, distance, altitude, HR-zone time) usefully describes the return shape. Combined with 100% schema coverage on inputs, the only real gap is pagination and filter-interaction behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all seven parameters are already documented in the schema, including the subtle interaction where sport filtering is applied post-fetch. The description adds no parameter-level detail beyond that baseline, so a 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (workouts), enumerates the fields returned, and states the ordering (most recent first), so an agent knows exactly what a call produces. It stops short of explicitly distinguishing this list tool from the singular sibling get_workout, leaving that to the tool name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus get_workout for a single record, nor any statement of exclusions or prerequisites. The fields listed describe output, not usage context, so the agent gets no routing help.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
10 tool updates
v1.0.2- First observed
get_cycle - First observed
get_daily_overview - First observed
get_profile - First observed
get_sleep - First observed
get_trends - First observed
get_workout - First observed
list_cycles - First observed
list_recoveries - First observed
list_sleeps - First observed
list_workouts
TDQS
Scored across 10 tools
Tools are mostly distinct: get_daily_overview aggregates one day, get_trends aggregates N days, list_* tools retrieve by data type, and get_* tools retrieve by id. There is slight overlap between get_daily_overview and combining list_cycles/list_recoveries/list_sleeps/list_workouts, but descriptions clarify intended use.
Consistent verb_noun pattern throughout: get_profile, get_daily_overview, get_trends, list_cycles, get_cycle, list_recoveries, list_workouts, list_sleeps, get_sleep, get_workout. Singular/plural differences follow entity conventions predictably.
10 tools is well-scoped for a WHOOP data server, covering profile, daily overview, trends, cycles, recoveries, sleeps, and workouts without bloat. Each tool earns its place.
Core WHOOP domain coverage is strong: profile, daily snapshot, trends, cycles, recoveries, sleeps, and workouts are represented. Minor gaps exist, such as no direct get_recovery by id or journal/behavior data, but agents can work around these via get_cycle or list_recoveries.
Maintenance
Related MCP Connectors
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.
Your WHOOP data in the assistant, read-only: recovery, sleep, strain, workouts, cycles and body meas
- SomviaOAuthapp.somvia
Apple Health training load, recovery, HRV and workout detail for Claude, ChatGPT and any MCP client.
Garmin data in Claude & ChatGPT via the Garmin Health API. OAuth sign-in, no password sharing.
Related MCP Servers
- AlicenseAqualityCmaintenanceConnects WHOOP fitness tracker data to AI assistants like Claude and ChatGPT, enabling natural language queries about recovery, sleep, strain, and trends.24111 PyPI2MIT
- FlicenseNot gradedqualityAmaintenanceEnables read-only access to your WHOOP recovery, sleep, HRV, strain, workout and body-measurement data from Claude Desktop, Claude Code, Codex or GitHub Copilot, so you can ask natural-language questions about today's status, personal baselines, trends, period comparisons and sleep debt.12 npm-
- FlicenseNot gradedqualityAmaintenanceEnables AI assistants to read a user's WHOOP recovery, sleep, HRV, strain, and workout history through a local, read-only server with tools for today's status, personal baselines, sleep debt, trends, and period comparisons. It supports Claude Desktop, Claude Code, Codex, and GitHub Copilot, letting users ask natural-language questions about their health data without exporting it themselves.12 npm-
- FlicenseNot gradedqualityAmaintenanceEnables users to query their own WHOOP recovery, sleep, HRV, strain and workout history in natural language through read-only tools, baselines and period comparisons inside Claude, Codex and GitHub Copilot.12 npm-