whoop-postgres-mcp
Uses PostgreSQL as the storage backend for synced WHOOP data, creating a documented schema and allowing MCP query tools to read recovery, sleep, workout, cycle, and baseline data directly from the database.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@whoop-postgres-mcpcompare my HRV this week to my 30-day baseline"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
whoop-mcp
An MCP server that syncs your WHOOP data into Postgres and lets AI agents query it.
WHOOP's public API is rate-limited, cursor-paginated, and returns one record at a time. That is fine for a sync job and terrible for an agent that wants to answer "how does my HRV this week compare to my baseline?". So this server splits the job in two:
a sync path that pulls cycles, recovery, sleep, workouts, and body measurements from the WHOOP API into a documented Postgres schema, keeping the raw JSON of every record alongside the typed columns;
a query path of MCP tools that read Postgres only. They are fast, never hit WHOOP's rate limits, and keep working offline once data is synced.
Your data lands in a database you own, in a schema you can read with any SQL client, and nothing leaves your machine except calls to WHOOP itself.
Python 3.12+ · MIT · stdio MCP server + CLI · Postgres storage
Contents
Related MCP server: WHOOP MCP Server
Tools
Two write-side tools talk to the WHOOP API; everything else reads Postgres only.
Tool | Args | What it does |
| none | Returns the OAuth authorization URL to open in a browser. |
|
| Exchanges the OAuth code for tokens, stores them, returns the connected user. |
|
| Pulls data from WHOOP into Postgres. Returns per-collection counts and errors. |
| none | Per-collection sync health: last sync, watermark, row count, last error. |
|
| Latest recovery and vitals vs. 30-day baseline, last night's sleep, recent workouts and strain. |
|
| Recent recovery scores, resting HR, HRV, SpO2, skin temperature. |
|
| Recent sleeps and naps with stage breakdown, need, performance, efficiency. |
|
| Recent workouts with strain, HR, energy, distance, and zone minutes. |
|
| Recent physiological cycles (WHOOP days) with day strain and HR. |
| none | 30-day mean and standard deviation per vital. |
days is capped at 365 and limit at 200. All tools return JSON text.
Install
uv tool install whoop-postgres-mcp # or: pipx install whoop-postgres-mcpOr run it without installing:
uvx whoop-postgres-mcp --helpYou also need a Postgres database (any recent version; 14+ is fine) and a WHOOP developer app. docs/SETUP.md walks through both.
Quickstart
export WHOOP_CLIENT_ID=...
export WHOOP_CLIENT_SECRET=...
export WHOOP_REDIRECT_URI=http://localhost:8765/callback
export WHOOP_DB_URL=postgresql://whoop:whoop@localhost:5432/whoop
whoop-mcp init-db # create the `whoop` schema (idempotent)
whoop-mcp auth-url # print the URL to visit; approve access in a browser
whoop-mcp connect <code> # paste the `code` from the redirect URL
whoop-mcp sync --all # first backfill; later runs: whoop-mcp sync --days 7
whoop-mcp # serve MCP over stdioThe same flow is available as MCP tools (whoop_auth_url, whoop_connect,
whoop_sync) so an agent can drive the whole setup.
Configuration
All configuration is by environment variable. The server validates every variable at startup and exits with a message naming each missing one.
Variable | Required | Meaning |
| yes | Client ID of your WHOOP developer app. |
| yes | Client secret of your WHOOP developer app. |
| yes | Redirect URI, exactly as registered on the app. Any URL works; the server does not listen on it. You copy the |
| yes | Postgres DSN, e.g. |
Register with an MCP client
Claude Code:
claude mcp add whoop -e WHOOP_CLIENT_ID=... -e WHOOP_CLIENT_SECRET=... \
-e WHOOP_REDIRECT_URI=http://localhost:8765/callback \
-e WHOOP_DB_URL=postgresql://whoop:whoop@localhost:5432/whoop \
-- uvx whoop-postgres-mcpClaude Desktop (claude_desktop_config.json) or any client that takes a
stdio command:
{
"mcpServers": {
"whoop": {
"command": "uvx",
"args": ["whoop-postgres-mcp"],
"env": {
"WHOOP_CLIENT_ID": "...",
"WHOOP_CLIENT_SECRET": "...",
"WHOOP_REDIRECT_URI": "http://localhost:8765/callback",
"WHOOP_DB_URL": "postgresql://whoop:whoop@localhost:5432/whoop"
}
}
}
}How sync works
WHOOP's collection endpoints filter on when a record occurred, not when it
was last modified, and records change after creation (a sleep is created as
PENDING_SCORE and scored later). The sync therefore:
always re-fetches the last
daysdays, which catches late re-scores;tracks a per-collection watermark (
newest_updated_atinwhoop_sync_state). If the last sync is older thandays, the window is stretched back to the watermark minus a two-day lookback so a gap never leaves a hole;upserts every record on its natural key (
id, orcycle_idfor recovery), so overlapping windows are harmless and re-running is safe;records per-collection errors in
whoop_sync_stateand carries on with the other collections rather than aborting the run.
full=true (or whoop-mcp sync --all) drops the lower bound and walks the
account's entire history. Body measurements are a single current record and are
refreshed on every sync.
Token refresh is proactive (five minutes before expiry) and serialized through
a Postgres advisory lock, so the MCP server and a cron-driven whoop-mcp sync
can share one token row without racing.
The full data model is documented in docs/SCHEMA.md.
Security model
Database access is token access. OAuth tokens are stored in plaintext in
whoop.whoop_tokens. Anyone who can read that table can call the WHOOP API as you until the refresh token is revoked. Restrict database grants accordingly and treatWHOOP_DB_URLas a secret.Read tools never reach the network. Only
whoop_connectandwhoop_synctalk to WHOOP. Everything else is a SQL query against your database.Nothing is written outside Postgres. No files, no caches, no telemetry.
Scopes are read-only. The app requests
read:*scopes plusofflinefor refresh tokens. It cannot modify anything in your WHOOP account.To revoke access, delete the row from
whoop_tokensand remove the app from your WHOOP account settings.
Development
git clone https://github.com/cunicopia-dev/whoop-mcp
cd whoop-mcp
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
ruff check .
mypy src
pytest # pure-logic tests
WHOOP_TEST_DB_URL=postgresql://whoop:whoop@localhost:5432/whoop pytest # + live DB testsThe live tests apply the schema and truncate every table in the target database before each test. Point them at a scratch database.
A throwaway Postgres for local testing:
docker run -d --rm --name whoop-pg -e POSTGRES_USER=whoop -e POSTGRES_PASSWORD=whoop \
-e POSTGRES_DB=whoop -p 5432:5432 postgres:16-alpineProject layout
src/whoop_mcp/
config.py environment variables, validated at startup
auth.py OAuth2 flow, token persistence, locked refresh
client.py httpx client: pagination, backoff, Retry-After
schema.sql the Postgres DDL (applied by `whoop-mcp init-db`)
db.py connection + schema helpers
sync.py incremental sync with per-collection watermarks
queries.py read-side SQL behind the MCP tools
server.py MCP server over stdio + CLI entry point
docs/
SETUP.md WHOOP app registration, OAuth walkthrough, DB init, first sync
SCHEMA.md column-by-column data model
tests/ config, schema, client, auth, sync, and stdio protocol testsLicense
MIT. See LICENSE.
Available Tools
10 toolswhoop_auth_urlA
Start connecting a WHOOP account: returns the OAuth authorization URL for the user to open in a browser. After approving, the browser lands on the redirect URI with a code parameter to pass to whoop_connect.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does so reasonably: it discloses that the output is a URL for browser use, that approval results in a redirect carrying a `code`, and where that code goes next. It does not mention URL expiry, required prior auth, or state handling, which leaves some operational gaps.
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 tightly written sentences with the action and return value front-loaded, followed by the handoff instruction. No filler or redundancy.
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 zero-parameter, no-annotation tool with no output schema, the description supplies everything needed: what it returns, how the user interacts with it, and which tool consumes the resulting code. 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?
The tool takes no parameters, so there is nothing for the description to disambiguate; the baseline for zero-param tools is 4. Schema coverage is 100% and the description correctly implies no user input is required.
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 and resource ('returns the OAuth authorization URL') and scopes it to starting a WHOOP connection. It clearly differentiates from the sibling whoop_connect, which it positions as the next step rather than the same action.
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?
Explains when to use it (to start connecting an account) and explicitly routes the agent to the follow-up tool whoop_connect after the user approves. It lacks an explicit 'do not use this if already connected' exclusion, so it falls just short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoop_baselineA
30-day mean and standard deviation per vital: recovery score, resting HR, HRV, SpO2, skin temperature, sleep hours, sleep performance, day strain. Reads the local database only; run whoop_sync first to refresh.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and discloses key traits: read-only local database access and a sync prerequisite. It stops short of detailing error behavior or output format beyond the metric list, but for a zero-parameter aggregate tool this is reasonably transparent.
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 tightly written sentences with the computation front-loaded and the prerequisite second. Every sentence earns its place; no filler.
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 no-parameter, no-output-schema tool, the description explains what is computed and lists the metrics, giving the agent enough to understand the return. The sync precondition covers the main operational dependency, though exact timezone or freshness details are omitted.
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?
Zero parameters, and schema description coverage is 100% (empty schema); per rubric, a zero-parameter tool starts at 4. The description adds no parameter semantics because none exist, which 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?
States a specific computation (30-day mean and standard deviation) across named vitals, so the agent knows exactly what resource is produced. The scope is clear, though it does not explicitly contrast itself with sibling tools like whoop_recovery or whoop_sleep.
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?
Provides a precondition ('run whoop_sync first to refresh') and notes local-only reads, which helps operational timing. However, it does not say when to choose this aggregate over sibling tools or what question it answers (e.g., comparing current metrics to baseline).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoop_connectA
Finish connecting: exchange the OAuth code from the redirect URL for tokens, store them in Postgres, and return the connected user's summary.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | The `code` query parameter from the OAuth redirect URL. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden. It does disclose a meaningful side effect (tokens are stored in Postgres) and the return (connected user's summary), which is more than most. However, it says nothing about failure modes, code single-use/idempotency, token scope or expiry, or permission requirements.
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, front-loaded with the action ('Finish connecting') and packed with the essential sequence of effects. No filler, nothing redundant.
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 one-parameter connection-finalization tool with no output schema, the description covers the input source, the side effect, and the return value. It falls slightly short on describing what 'the connected user's summary' actually contains and on error/retry 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% and the schema already defines code as 'the `code` query parameter from the OAuth redirect URL,' which is exactly what the description repeats. Baseline 3 is appropriate since the description adds no syntax or format detail beyond the schema.
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 precise verb+resource chain: exchange the OAuth code for tokens, persist them in Postgres, and return the user summary. 'Finish connecting' makes it clearly the completion step of the flow, which cleanly separates it from sibling whoop_auth_url (which starts the flow).
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?
'Finish connecting' plus 'the OAuth code from the redirect URL' establishes the required context: this is the second call in the flow, made after the user authorizes and is redirected. It does not explicitly name whoop_auth_url as the prerequisite or state exclusions, 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.
whoop_cyclesA
Recent physiological cycles (WHOOP days): day strain, energy, average and max heart rate, newest first. Reads the local database only; run whoop_sync first to refresh.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | How many days back to include cycles. | |
| limit | No | Maximum number of records to return. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose meaningful behavior: the data source is the local DB (not a live API call), newest-first ordering, and the sync prerequisite. It does not discuss pagination or truncation at the limit, which would be useful for a list tool returning up to 200 records.
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, front-loaded with the resource and ordering, then the storage/prerequisite constraint. Nothing is wasted.
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?
No output schema exists, and the description compensates by enumerating the returned fields (day strain, energy, avg/max heart rate). For a two-parameter local read tool this is nearly complete; only pagination behavior is left unstated.
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 'days' and 'limit' are already documented with defaults and bounds. The description adds no semantics beyond the schema for either parameter; 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?
States a specific resource ('Recent physiological cycles (WHOOP days)') with the fields it returns and the sort order, so an agent can distinguish it from whoop_recovery, whoop_sleep, and whoop_workouts. It does not explicitly name a sibling it is not, which keeps it just below 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?
Gives clear operational context: it reads the local database only and requires whoop_sync first to refresh. That is a real prerequisite an agent must honor. It stops short of stating exclusions or naming alternatives for related data (recovery, sleep).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoop_overviewA
One-call snapshot: latest recovery and vitals compared with the 30-day baseline (delta and z-score), last night's sleep, and recent workouts and daily strain. Reads the local database only; run whoop_sync first to refresh.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Window for the recent workouts and cycles sections. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full behavioral burden, and it does well: it discloses that the tool reads the local database only (no network/live fetch) and that data can be stale without whoop_sync. It omits return shape and whether the 30-day baseline needs prior data to exist, hence not 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?
Two tight sentences with zero filler: the content list is front-loaded, and the operational caveat (local DB, sync first) is placed after. 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?
For a multi-section aggregate tool with no output schema, the description enumerates the returned sections and the sync prerequisite, which is enough for correct invocation. It could clarify what happens with insufficient history for the 30-day baseline, but no critical gap remains.
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 as the window for workouts/cycles. The description's phrasing 'recent workouts' loosely echoes it but adds no format, bounds, or default detail beyond the schema. 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?
States a specific action (one-call snapshot) and enumerates the exact contents: recovery/vitals vs 30-day baseline, sleep, workouts, strain. It is clearly distinguishable from the granular siblings (whoop_recovery, whoop_sleep, whoop_workouts), which each return one slice of what this aggregates.
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 an explicit prerequisite (run whoop_sync first to refresh) and implies the aggregate use case via 'one-call snapshot'. It does not explicitly say to prefer this over the individual sibling calls, but the framing makes the alternative clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoop_recoveryA
Recent recovery records: score (0-100), resting HR, HRV, SpO2, skin temperature, newest first. Reads the local database only; run whoop_sync first to refresh.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | How many days back to include recoveries. | |
| limit | No | Maximum number of records to return. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral load, and it does disclose the key trait: this reads only the local database rather than hitting the API, and requires whoop_sync to be fresh. It omits what happens when the DB is empty/unsynced or any error/edge behavior, but the source-of-truth disclosure is the meaningful part.
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 tight clauses with no filler: the output shape and ordering come first, the data-source caveat second. Every phrase adds 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?
No output schema exists, so the description correctly compensates by listing the returned fields and ordering. The sync prerequisite covers freshness. Minor gap: no mention of what an empty or unsynced database yields, but for a simple two-param read tool this is close to 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 'days' and 'limit' are already documented with ranges and defaults in the schema. The description adds no additional semantics for either parameter, 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 states a specific resource (recovery records) and enumerates the returned fields (score, resting HR, HRV, SpO2, skin temperature) plus ordering (newest first). That field list cleanly separates it from siblings like whoop_sleep and whoop_workouts without needing to open any schema.
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?
It gives an explicit precondition and routing hint: 'Reads the local database only; run whoop_sync first to refresh.' That tells the agent when the data source is valid and which sibling to run beforehand. It stops short of naming alternatives or exclusions, so it is a strong 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoop_sleepA
Recent sleeps including naps: stage durations, sleep need, respiratory rate, performance and efficiency, newest first. Reads the local database only; run whoop_sync first to refresh.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | How many days back to include sleeps. | |
| limit | No | Maximum number of records to return. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does disclose non-obvious traits: the tool reads only a local cache, samples are ordered newest-first, and naps are included. It omits any note on pagination behavior or what happens when the local DB is empty, which keeps it 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?
Two tight sentences: the first front-loads what is returned and in what order, the second front-loads the data-source constraint and the required action. No filler.
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?
There is no output schema, so the description correctly compensates by enumerating the payload fields and ordering. Combined with the sync prerequisite and local-only data source, an agent has enough to call it correctly, though pagination/empty-result behavior is unaddressed.
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 the schema already fully documents both 'days' and 'limit' with defaults and bounds. The description adds no syntax, unit, or interaction detail beyond that, 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 the resource (sleeps, including naps) and enumerates the returned metrics — stage durations, sleep need, respiratory rate, performance, efficiency — with an explicit ordering (newest first). This clearly separates it from siblings like whoop_recovery and whoop_workouts, though it never uses an explicit verb such as 'list' or 'return'.
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 prerequisite: 'Reads the local database only; run whoop_sync first to refresh.' It tells the agent when the data may be stale and what to call. It does not, however, contrast with sibling retrieval tools such as whoop_overview, so the routing guidance is incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoop_statusA
Sync health: connected user, and per collection the last sync time, watermark, row count, and last error. Reads the local database only; run whoop_sync first to refresh.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses the critical behavioral trait that it reads local DB only and requires whoop_sync to refresh, which prevents stale-data misuse. It doesn't cover auth requirements or response format, but the key operational caveat is present.
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 tight sentences — the first enumerates outputs, the second gives the operational caveat. Front-loaded and waste-free.
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 zero-param diagnostic reader with no output schema, the description covers what is returned and the prerequisite to refresh. It is nearly complete; only auth or rate-limit behavior is unstated, but those are minor for a local read.
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?
Zero parameters, so the baseline is 4. The description correctly implies no inputs are needed by describing purely output-oriented behavior.
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?
Specific verb and resource: it reports sync health. It names exactly what is reported (connected user, last sync time, watermark, row count, last error per collection), making it clearly distinct from sync-action siblings like whoop_sync and from data siblings like whoop_recovery.
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?
Explicitly states it reads the local database only and instructs to run whoop_sync first to refresh — a clear usage condition. It doesn't name when not to use it, but the local-only constraint effectively excludes live-data expectations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoop_syncA
Pull data from the WHOOP API into Postgres. Incremental by default (last days days plus anything since the last sync); set full=true to backfill the account's entire history. Returns per-collection counts and errors.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Days of recent history to re-fetch. | |
| full | No | Backfill everything instead of an incremental window. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose useful behavior: incremental-by-default semantics and that per-collection counts and errors are returned. It omits whether the Postgres write is an upsert or destructive, how long a full backfill takes, and rate-limit behavior against the WHOOP API. Auth prerequisites are arguably covered by the sibling whoop_connect/whoop_auth_url tools, which softens the gap.
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, front-loaded with the core action and destination, then the mode behavior and return shape. Every clause carries information; nothing is wasted.
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 two-parameter tool with no output schema, the description covers the action, the default mode, the override, and the return shape. It would be complete except for the mutation semantics of the Postgres write and any execution-time expectations.
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 the baseline is 3, but the description adds meaning beyond the schema by explaining what 'incremental' actually means ('last days days plus anything since the last sync') and that full=true backfills the entire account history. That interaction between the two parameters is not derivable from the schema alone.
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 and resource with a destination: 'Pull data from the WHOOP API into Postgres'. This contrasts implicitly with the query-shaped siblings (whoop_recovery, whoop_sleep, whoop_cycles), which presumably read stored data, but the description never explicitly draws that line.
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?
It gives clear mode-selection guidance (incremental by default, full=true to backfill), which is genuinely useful. However, it offers no guidance on when to call sync versus the sibling tools (whoop_status, whoop_overview), nor any prerequisite such as needing an authenticated connection first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoop_workoutsA
Recent workouts: sport, duration, strain, heart rate, energy, distance, and minutes per heart-rate zone, newest first. Reads the local database only; run whoop_sync first to refresh.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | How many days back to include workouts. | |
| limit | No | Maximum number of records to return. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the full behavioral burden. It discloses that it reads the local database only and requires whoop_sync for fresh data, but omits authentication requirements, rate limits, and any explicit read-only or non-destructive statement.
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, zero waste. The key data fields and ordering are front-loaded, and the operational note about the local database and sync is efficiently appended.
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?
No output schema exists, so the description rightly enumerates the returned fields and ordering. It also provides the important prerequisite about syncing first, making it sufficiently complete for a simple read tool.
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 the schema fully documents the days and limit parameters. The description adds no additional meaning about these parameters, so the baseline of 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 states a specific resource (workouts) and the exact data fields returned, plus the ordering (newest first). It is clearly distinguishable from sibling tools like whoop_sleep or whoop_recovery without needing schema inspection.
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?
It provides a prerequisite to use whoop_sync first to refresh, which implies when stale data is a concern. However, it gives no explicit when-to-use guidance relative to alternative tools such as whoop_cycles or whoop_overview.
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
v0.1.0- First observed
whoop_auth_url - First observed
whoop_baseline - First observed
whoop_connect - First observed
whoop_cycles - First observed
whoop_overview - First observed
whoop_recovery - First observed
whoop_sleep - First observed
whoop_status - First observed
whoop_sync - First observed
whoop_workouts
TDQS
Scored across 10 tools
Each tool targets a distinct data type (recovery, sleep, workouts, cycles) or action (auth, connect, sync, status), so boundaries are mostly clear. whoop_overview aggregates recovery/sleep/workouts/strain and thus overlaps with the individual read tools and whoop_baseline, but its 'one-call snapshot' description mostly disambiguates it.
Every tool uses the same whoop_<noun> snake_case prefix with no mixing of conventions. The pattern is predictable and readable throughout.
Ten tools is a well-scoped set: two auth tools, one sync, one status, one baseline, and six read tools. Each earns its place with no obvious redundancy.
The surface covers the full lifecycle: OAuth connect, sync, sync health, and reads across recovery, sleep, workouts, cycles, baseline, and overview. Minor gaps like token revocation/disconnect or delete operations are absent but not blocking for the read-oriented purpose.
Related MCP Connectors
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.
- SomviaOAuthapp.somvia
Private Apple Health metrics and workout detail for ChatGPT, Claude, and any MCP client.
Agent-native notes, tasks, dev-docs, vaults, sync & handoffs. MCP + OpenAPI dual surface.
Related MCP Servers
- AlicenseBqualityAmaintenanceDownloads all your Garmin health and fitness data into a local SQLite database and exposes 45 MCP tools for AI analysis, enabling assistants to query sleep, training load, HRV, and more.48149AGPL 3.0
- AlicenseAqualityDmaintenanceEnables querying WHOOP biometric data (recovery, strain, sleep, workouts, heart rate) from any MCP-compatible AI client, supporting remote and direct modes.16458 npmMIT
- AlicenseAqualityBmaintenancePrivacy-first, unofficial WHOOP MCP server for AI health, sleep, recovery, and performance agents.30138 npm13MIT
- AlicenseNot gradedqualityAmaintenanceA multi-user MCP server that exposes WHOOP fitness data (recovery, sleep, workouts, cycles, profile, body measurements) to AI clients. Each user connects their own WHOOP account via OAuth and only sees their own data, which is fetched live on every tool call.14 npmMIT