Skip to main content
Glama
maangy

WHOOP MCP Server

by maangy
README.md
# WHOOP MCP Server

A [Model Context Protocol](https://modelcontextprotocol.io) server that gives Claude access to your WHOOP health data via the [WHOOP Developer API](https://developer.whoop.com/) (API **v2**).

## Tools

| Tool | Description |
|---|---|
| `authenticate` | Start the OAuth 2.0 flow — call this once to connect your WHOOP account |
| `get_recovery` | Latest recovery score, HRV, resting heart rate, SpO2, skin temperature |
| `get_sleep` | Sleep duration, efficiency, stage breakdown, disturbances, respiratory rate |
| `get_workouts` | Recent workouts with strain, sport type, HR zones, calories |
| `get_cycles` | Physiological cycles (days) with strain and recovery summary |
| `get_body_measurements` | Height, weight, and max heart rate |
| `get_profile` | Basic profile (name, email) |

**Parameters:** the data tools (`get_recovery`, `get_sleep`, `get_workouts`, `get_cycles`) accept optional filters:

- `limit` — number of records to return (default 1 for recovery/sleep, 5 for workouts/cycles; max 25)
- `start_date` / `end_date` — ISO 8601 timestamps, e.g. `2024-01-01T00:00:00.000Z`
- `include_naps` — `get_sleep` only; include nap records (default `false`)

`get_body_measurements` and `get_profile` take no parameters.

## Prerequisites

- Node.js 18 or later
- A WHOOP Developer account and OAuth app

## Setup

### 1. Create a WHOOP Developer App

1. Go to [https://developer.whoop.com/](https://developer.whoop.com/) and sign in.
2. Create a new application.
3. Add `http://localhost:8080/callback` as a **Redirect URI** (or use a custom port — just keep it consistent with `WHOOP_REDIRECT_URI`).
4. Enable the following **scopes** on the app — the server requests all of them, and data tools will return empty or fail if any are missing:
   - `offline` (required — grants the refresh token so you only authenticate once)
   - `read:recovery`
   - `read:sleep`
   - `read:workout`
   - `read:cycles`
   - `read:body_measurement`
   - `read:profile`
5. Copy your **Client ID** and **Client Secret**.

### 2. Install and build

```bash
git clone <this-repo>
cd whoop-mcp
npm install
npm run build
```

### 3. Configure environment variables

```bash
cp .env.example .env
```

Edit `.env`:

```
WHOOP_CLIENT_ID=your_client_id_here
WHOOP_CLIENT_SECRET=your_client_secret_here
WHOOP_REDIRECT_URI=http://localhost:8080/callback
```

> **Security note:** `.env` is never committed. Tokens are stored in `~/.whoop-mcp-tokens.json` with `600` permissions (owner read/write only).

### 4. Add to Claude's MCP configuration

#### Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json`)

```json
{
  "mcpServers": {
    "whoop": {
      "command": "node",
      "args": ["/absolute/path/to/whoop-mcp/dist/index.js"],
      "env": {
        "WHOOP_CLIENT_ID": "your_client_id_here",
        "WHOOP_CLIENT_SECRET": "your_client_secret_here",
        "WHOOP_REDIRECT_URI": "http://localhost:8080/callback"
      }
    }
  }
}
```

> You can either set the env vars here **or** rely on a `.env` file in the project root (loaded by `dotenv`).

#### Claude Code (`.claude/settings.json` or via `claude mcp add`)

```bash
claude mcp add whoop node /absolute/path/to/whoop-mcp/dist/index.js \
  -e WHOOP_CLIENT_ID=your_client_id \
  -e WHOOP_CLIENT_SECRET=your_client_secret \
  -e WHOOP_REDIRECT_URI=http://localhost:8080/callback
```

Or manually in `.claude/settings.json`:

```json
{
  "mcpServers": {
    "whoop": {
      "command": "node",
      "args": ["/absolute/path/to/whoop-mcp/dist/index.js"],
      "env": {
        "WHOOP_CLIENT_ID": "...",
        "WHOOP_CLIENT_SECRET": "...",
        "WHOOP_REDIRECT_URI": "http://localhost:8080/callback"
      }
    }
  }
}
```

### 5. Authenticate

Once the server is running in Claude, call the `authenticate` tool:

> **You:** Use the `authenticate` tool to connect my WHOOP account.

Claude will display an authorization URL. Open it in your browser, approve access, and the tokens will be saved automatically to `~/.whoop-mcp-tokens.json`.

Tokens refresh automatically — you only need to authenticate once.

## Example prompts

```
What was my recovery score this morning?
Show me my last 7 days of sleep data.
How has my HRV trended over the past month?
What workouts did I do this week and what was my strain?
What are my body measurements on WHOOP?
```

## Token storage

- Tokens are stored in `~/.whoop-mcp-tokens.json` (or the path in `WHOOP_TOKEN_FILE`).
- The file is created with `0600` permissions so only your user can read it.
- Access tokens are refreshed automatically 60 seconds before expiry using the stored refresh token.

## Development

```bash
# Compile TypeScript in watch mode
npm run dev

# Run directly (after building)
npm start
```

## Troubleshooting

| Problem | Fix |
|---|---|
| `Missing required environment variable` | Ensure `WHOOP_CLIENT_ID` and `WHOOP_CLIENT_SECRET` are set in `.env` or the MCP config `env` block |
| `Not authenticated` | Call the `authenticate` tool and complete the browser flow |
| Port 8080 already in use | Change `WHOOP_REDIRECT_URI` to use a different port (e.g. `http://localhost:9090/callback`) and update your WHOOP app's redirect URI list |
| Token refresh fails | Delete `~/.whoop-mcp-tokens.json` and re-authenticate |

TDQS

A4.1/5.0

Scored across 7 tools

Disambiguation5/5

Each tool targets a distinct data domain: authentication, recovery, sleep, workouts, cycles, body measurements, and profile. There is no meaningful overlap between these resource types, and the descriptions make the boundary between similar health metrics clear.

Naming Consistency5/5

The data tools all follow a clean get_<resource> naming convention, making the tool surface highly predictable. authenticate is the only exception, but it is clearly a distinct action verb appropriate for the OAuth flow.

Tool Count5/5

Seven tools is well-scoped for a read-only health data integration. Each tool represents a meaningful endpoint or data category, with no redundant or filler tools.

Completeness5/5

The server covers the main WHOOP data domains: recovery, sleep, workouts, daily cycles, body measurements, and user profile, plus the required authentication step. For a read-only personal health API, this is a complete and usable surface with no obvious dead ends.

Maintenance

ActivityInactive
ResponsivenessNo issues