The server has 6 well-named tools with explicit schemas and descriptions present in src/index.ts. Tool names follow verb_noun convention (get_today, get_recovery_trends, sync_data, get_auth_url). Descriptions are present and reasonably specific (avg ~120 chars, baseline 194 chars). However, several parameter descriptions are sparse or missing detail. Input schemas are properly typed with JSON Schema. Major gaps: (1) No documented output schemas, responses are formatted as markdown text rather than structured objects; (2) No parameter descriptions for most numeric parameters (e.g., 'days' parameter lacks guidance on what happens at boundary values); (3) Error handling is minimal, tools return plain text errors instead of actionable recovery guidance; (4) No tool annotations (readOnlyHint, destructiveHint, idempotentHint); (5) Response formatting as text rather than structured JSON limits downstream tool composition. The server is functional but misses LLM-optimization patterns for chainability and structured reasoning.
Get the Whoop authorization URL to connect your account.
Get recovery score trends over time, including HRV and resting heart rate patterns.
Get detailed sleep analysis including duration, stages, efficiency, and sleep debt.
Get training strain history and workout data.
Get today's Whoop data including recovery score, last night's sleep, and current strain.
Manually trigger a data sync from Whoop.
No documented output schemas. Tools return markdown-formatted text instead of structured JSON objects. This prevents downstream tools from consuming results and forces LLMs to parse unstructured text, increasing hallucination risk and reducing composability.
Parameter 'days' (common to 3 tools) lacks meaningful description. Current text 'Number of days to analyze (default: 14, max: 90)' does not explain what happens at boundaries (e.g., does days=1 return only today? does days=0 return nothing?) or how data is aggregated. LLMs cannot reason about valid ranges without this context.
Error responses are plain text ('Not authenticated with Whoop...', 'No data available...') instead of actionable recovery guides. Errors should categorize as retryable vs. user-fixable and suggest next steps. Current approach forces LLM to infer recovery path.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 66 | 2026-07-28+ | v2 |
No tool annotations. 'sync_data' is destructive (triggers API sync, state mutation) but lacks destructiveHint. 'get_*' tools are read-only but lack readOnlyHint. These hints are required by modern MCP clients to guide tool selection and UI presentation.
'sync_data' with 'full' parameter defaults to false, which is safe, but the tool description does not clarify what incremental sync means vs. full sync. Does incremental skip days already cached? Does it risk data staleness? LLM cannot reason about when to use full=true.
Token/secret management is handled server-side (tokens stored in SQLite), which is correct, but the 'get_auth_url' tool does not document the OAuth flow clearly. LLM does not know: (1) when to call this, (2) how to complete the callback, (3) whether manual intervention is required.