Skip to main content
Glama

whoop-mcp

Python License: MIT storage: Postgres 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

whoop_auth_url

none

Returns the OAuth authorization URL to open in a browser.

whoop_connect

code

Exchanges the OAuth code for tokens, stores them, returns the connected user.

whoop_sync

days=7, full=false

Pulls data from WHOOP into Postgres. Returns per-collection counts and errors.

whoop_status

none

Per-collection sync health: last sync, watermark, row count, last error.

whoop_overview

days=7

Latest recovery and vitals vs. 30-day baseline, last night's sleep, recent workouts and strain.

whoop_recovery

days=7, limit=50

Recent recovery scores, resting HR, HRV, SpO2, skin temperature.

whoop_sleep

days=7, limit=50

Recent sleeps and naps with stage breakdown, need, performance, efficiency.

whoop_workouts

days=14, limit=50

Recent workouts with strain, HR, energy, distance, and zone minutes.

whoop_cycles

days=7, limit=50

Recent physiological cycles (WHOOP days) with day strain and HR.

whoop_baseline

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-mcp

Or run it without installing:

uvx whoop-postgres-mcp --help

You 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 stdio

The 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

WHOOP_CLIENT_ID

yes

Client ID of your WHOOP developer app.

WHOOP_CLIENT_SECRET

yes

Client secret of your WHOOP developer app.

WHOOP_REDIRECT_URI

yes

Redirect URI, exactly as registered on the app. Any URL works; the server does not listen on it. You copy the code from the address bar.

WHOOP_DB_URL

yes

Postgres DSN, e.g. postgresql://user:pass@host:5432/db. Tokens and data live here.

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-mcp

Claude 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:

  1. always re-fetches the last days days, which catches late re-scores;

  2. tracks a per-collection watermark (newest_updated_at in whoop_sync_state). If the last sync is older than days, the window is stretched back to the watermark minus a two-day lookback so a gap never leaves a hole;

  3. upserts every record on its natural key (id, or cycle_id for recovery), so overlapping windows are harmless and re-running is safe;

  4. records per-collection errors in whoop_sync_state and 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 treat WHOOP_DB_URL as a secret.

  • Read tools never reach the network. Only whoop_connect and whoop_sync talk 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 plus offline for refresh tokens. It cannot modify anything in your WHOOP account.

  • To revoke access, delete the row from whoop_tokens and 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 tests

The 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-alpine

Project 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 tests

License

MIT. See LICENSE.

Available Tools

10 tools
whoop_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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYesThe `code` query parameter from the OAuth redirect URL.

TDQS

A4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoHow many days back to include cycles.
limitNoMaximum number of records to return.

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoWindow for the recent workouts and cycles sections.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoHow many days back to include recoveries.
limitNoMaximum number of records to return.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoHow many days back to include sleeps.
limitNoMaximum number of records to return.

TDQS

A4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoDays of recent history to re-fetch.
fullNoBackfill everything instead of an incremental window.

TDQS

A3.7/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNoHow many days back to include workouts.
limitNoMaximum number of records to return.

TDQS

A3.9/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

  1. 10 tool updatesv0.1.0
    • First observedwhoop_auth_url
    • First observedwhoop_baseline
    • First observedwhoop_connect
    • First observedwhoop_cycles
    • First observedwhoop_overview
    • First observedwhoop_recovery
    • First observedwhoop_sleep
    • First observedwhoop_status
    • First observedwhoop_sync
    • First observedwhoop_workouts

TDQS

A4.1/5.0

Scored across 10 tools

Disambiguation4/5

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.

Naming Consistency5/5

Every tool uses the same whoop_<noun> snake_case prefix with no mixing of conventions. The pattern is predictable and readable throughout.

Tool Count5/5

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.

Completeness4/5

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

Related MCP Servers

  • A
    license
    B
    quality
    A
    maintenance
    Downloads 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.
    48
    149
    AGPL 3.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    A 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 npm
    MIT