Skip to main content
Glama
README.md
# WHOOP MCP Server

An MCP (Model Context Protocol) server that lets Claude query your personal WHOOP health data —
recovery, sleep, strain, workouts, and profile — via WHOOP's official OAuth 2.0 REST API (v2).

Each person who uses this runs their own copy against their own WHOOP account: you register your
own free developer app with WHOOP, and your tokens/credentials stay in local files on your machine
(gitignored, and written with restrictive permissions) — they're never sent anywhere except
directly between your machine and WHOOP's API.

That said, the *health data* these tools return is a different story: once a tool call happens,
its result is returned to whatever MCP client/model you're using (e.g. Claude), so it's subject to
that service's own privacy and data-handling policies from that point on. Only the credentials and
tokens are guaranteed to stay local — the recovery scores, sleep data, etc. you ask about
necessarily become visible to the model answering your question.

```bash
git clone https://github.com/vaibhavgoel63-arch/Whoop-MCP.git
cd Whoop-MCP
```

## 1. Get WHOOP API credentials

1. Go to the [WHOOP Developer Dashboard](https://developer-dashboard.whoop.com) and sign in.
2. Create (or open) an app.
3. Under the app's API settings, set the **Redirect URI** to exactly:
   ```
   http://localhost:8080/callback
   ```
4. Copy the **Client ID** and **Client Secret** — you'll paste these into `.env` in step 3 below.

## 2. Prerequisites

- **Node.js 18+** (needed for the built-in `fetch` API). Check with `node --version`.

## 3. Install and configure

```bash
npm install
cp .env.example .env
```

Open `.env` and **paste in your Client ID and Client Secret** from step 1:

```
WHOOP_CLIENT_ID=your-client-id-here
WHOOP_CLIENT_SECRET=your-client-secret-here
WHOOP_REDIRECT_URI=http://localhost:8080/callback
```

> ⚠️ **You must manually fill in `WHOOP_CLIENT_ID` and `WHOOP_CLIENT_SECRET`** — the server will
> refuse to start any OAuth flow until these are set.

## 4. Build and log in (one-time)

```bash
npm run build
npm run login
```

This will:
1. Start a temporary local server on `http://localhost:8080`.
2. Open your browser to WHOOP's consent screen (requesting recovery, sleep, cycle, workout,
   profile, body-measurement, and offline/refresh scopes).
3. After you approve, WHOOP redirects back to `localhost:8080/callback` with an authorization code.
4. The script exchanges that code for an access + refresh token and saves them to `token.json`
   (gitignored) in the project root.

You only need to do this once. The MCP server automatically refreshes the access token using the
refresh token when it expires (WHOOP access tokens last about 1 hour). If your refresh token is
ever revoked or expires, just re-run `npm run login`.

## 5. Connect to Claude Desktop

Open your Claude Desktop config file:

- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Linux**: `~/.config/Claude/claude_desktop_config.json`

> Note: if you installed Claude Desktop from the Microsoft Store, the file above may just be a
> stub — the app actually reads
> `%LOCALAPPDATA%\Packages\<Claude package folder>\LocalCache\Roaming\Claude\claude_desktop_config.json`.
> If tools don't show up after following the steps below, check there.

Add a `whoop` entry under `mcpServers`. **Replace the path below with the absolute path to this
project's `dist/server.js`** on your machine (find it with `pwd` on macOS/Linux or `cd` on Windows
from inside the project folder):

```json
{
  "mcpServers": {
    "whoop": {
      "command": "node",
      "args": ["/absolute/path/to/whoop-mcp/dist/server.js"]
    }
  }
}
```

> ⚠️ **You must manually fill in this absolute path** to wherever you cloned this repo. Use forward
> slashes even on Windows (e.g. `C:/Users/you/whoop-mcp/dist/server.js`) — they work fine inside
> this JSON file.

Then **fully restart Claude Desktop** (quit from the system tray, not just close the window).

## 6. Test it

1. In Claude Desktop, click the tools/hammer icon in the chat box and confirm you see `whoop` with
   6 tools listed: `get_recovery`, `get_sleep`, `get_strain`, `get_workouts`, `get_profile`,
   `get_readiness_context`.
2. Try these prompts:
   - "How was my recovery this week?"
   - "Should I train hard today?"
   - "How did I sleep the last 3 nights?"
   - "Show me my workouts from the last 7 days."
   - "What's my current strain and how does it compare to yesterday?"
   - "What was my average strain in March 2026?" (historical range, not just "last N days")
3. Spot-check one result (e.g. today's recovery score) against the WHOOP app to confirm the numbers
   match.

## Tools reference

| Tool | Description |
|---|---|
| `get_recovery(days \| start+end)` | Recovery score, HRV, resting heart rate, SpO2, skin temp, `score_state` (SCORED/PENDING_SCORE/UNSCORABLE — non-scored records are included with null metrics, not dropped), `user_calibrating` — plus an averages summary |
| `get_sleep(days \| start+end)` | Sleep performance %, efficiency %, stage breakdown (light/deep/REM), `sleep_onset` (full ISO timestamp of when sleep began, not just the date), `score_state` — plus an averages summary |
| `get_strain(days \| start+end)` | Daily strain, average/max heart rate, calories per day, `score_state` — plus an averages/totals summary |
| `get_workouts(days \| start+end)` | Logged workouts with sport, duration, strain, heart rate, calories, `score_state` — plus a summary |
| `get_profile()` | Name, email, height, weight, max heart rate |
| `get_readiness_context()` | Today's recovery, last 3 nights of sleep, last 3 days of strain — raw signals only, no verdict. Deliberately doesn't try to tell you whether to train; it can't see context like soreness, illness, or injury, so that synthesis is left to whoever's using this data |

The four range-based tools accept either `days` (rolling window, e.g. `days=7` for the last week) or
an explicit `start`/`end` date pair (`YYYY-MM-DD`, end exclusive) for querying a specific historical
period, e.g. `start="2026-03-01", end="2026-04-01"` for all of March 2026. Each returns a `summary`
object (averages/totals) alongside the individual daily/nightly `records`.

## Troubleshooting

- **"No WHOOP tokens found"** — run `npm run login`.
- **401 / token errors after working before** — the server auto-refreshes access tokens; if you see
  a refresh failure, your refresh token was likely revoked (e.g. you removed app access in WHOOP
  settings). Re-run `npm run login`.
- **403 Forbidden** — your token is missing a scope. Scopes are fixed at login time, so re-run
  `npm run login` to get a fresh token with the full scope set.
- **429 Too Many Requests** — you've hit WHOOP's rate limit (100 requests/minute, 10,000/day). Wait
  and try again.
- **Tools don't show up in Claude Desktop** — double-check the absolute path in
  `claude_desktop_config.json`, that you ran `npm run build` (the config points at `dist/server.js`,
  not `src/server.ts`), and that you fully restarted Claude Desktop.

## Project structure

```
src/
  auth.ts        # OAuth constants, token load/save, refresh logic
  login.ts        # One-time login script (npm run login)
  whoopClient.ts  # Authenticated WHOOP API client + response normalizers
  server.ts       # MCP server exposing the 6 tools
.env.example      # Template for WHOOP_CLIENT_ID / WHOOP_CLIENT_SECRET / WHOOP_REDIRECT_URI
```

`.env` (credentials) and `token.json` (access/refresh tokens) are both gitignored — never commit
either file.

TDQS

A4.3/5.0

Scored across 6 tools

Disambiguation5/5

Each tool addresses a distinct WHOOP domain (recovery, sleep, strain, workouts, profile, training recommendation) with no overlap. The descriptions clearly differentiate the data each returns, making it easy for an agent to select the correct tool for a given question.

Naming Consistency4/5

All tool names follow a consistent 'get_' prefix with a noun representing the data type (recovery, sleep, strain, etc.). This is predictable and clear. The only minor deviation is the slightly longer 'get_training_recommendation' compared to the others, but it still fits the pattern.

Tool Count5/5

With 6 tools, the set is well-scoped for a WHOOP fitness tracker integration. Each tool represents a core data category a user would query, and there are no extraneous or missing tools that would make the surface too large or too small for the domain.

Completeness4/5

The tools cover the most common queries about WHOOP data: recovery, sleep, strain, workouts, profile, and training recommendations. A minor gap is the lack of tools to query cycle/physiological data, meal logging, or team features, but the core personal health metrics are well represented.

Maintenance

ActivityMaintained
ResponsivenessNo issues