Open-source WHOOP MCP servers, compared
A survey of what's on GitHub, what each approach gets right, and where a hosted server differs. We're biased — we sell one — so this page sticks to facts you can verify.
Credit where it's due. The open-source WHOOP MCP servers did the hard early work: mapping WHOOP's v2 endpoints, discovering that state must be at least 8 characters, that client credentials go in the request body rather than Basic auth, and that you must re-send scope=offline on every refresh. Those findings are in FitnessPeak too.
The three shapes you'll find
Local stdio servers
The most common. Your MCP client spawns a Node or Python process, talks JSON-RPC over stdin/stdout, and the process reads tokens from a file in your home directory. Simple, private, and completely tied to one machine.
Self-hosted HTTP servers
Less common. Same code, wrapped in a web server you deploy somewhere. Solves the "laptop is closed" problem and creates a new one: now you're running a public HTTPS endpoint that holds health tokens, and securing that is your job.
Hosted services
FitnessPeak. At the time of writing we're not aware of another hosted WHOOP MCP service — which is either an opportunity or a warning, depending on your temperament.
What differs in practice
| Local stdio | Self-hosted HTTP | FitnessPeak | |
|---|---|---|---|
| Setup time | 30–60 min | 1–3 hours | ~2 min |
| Your own WHOOP dev app | Yes | Yes | No |
| Runs 24/7 | No | Yes | Yes |
| Browser-based clients | No | Yes | Yes |
| Mobile assistants | No | Yes | Yes |
| You operate a public endpoint | No | Yes | No |
| Token encryption at rest | File perms 0600 | Your choice | AES-256-GCM |
| Alerted on a broken connection | No | If you build it | Yes |
| Tools you can edit | Yes | Yes | No |
| Ongoing cost | Free | Server hosting | $39/yr |
Self-hosted HTTP deserves a note: once you deploy a public endpoint holding WHOOP tokens, you inherit TLS, auth, patching and backups. That's the same job we do — which is roughly the argument for paying someone to do it.
What we did differently
- Multi-tenant token refresh. A single-user server can keep one refresh promise in a module variable. Ours serialises per account, because WHOOP rotates the refresh token on every use and two concurrent tool calls would otherwise race and invalidate each other.
- Gating as tool results, not protocol errors. When something isn't connected, the model gets a readable sentence telling the user what to click. A JSON-RPC error code never reaches the model in most clients.
- Period summaries in the markdown. Each table ends with the averages, so the model doesn't have to add up seven rows of HRV to answer “is it trending up”.
- A status tool.
fitnesspeak_statusexists so an assistant that hits “not connected” can find out what is available instead of guessing.
If you'd rather self-host
Search GitHub for whoop mcp. Look for a project that requests the offline scope, re-sends scope=offline on refresh, guards every score field as optional, and follows next_token pagination. Those four things separate a server that works from one that works for a week.
Or skip all of it
14-day free trial. Card required so there's no second signup at the end; cancel before day 14 and you're charged nothing.