Self-hosted health analytics server for Polar devices with MCP integration for sleep, recovery, activity, and exercise data analysis
Polar Flow Server has well-structured tool definitions with comprehensive descriptions and proper parameter typing. All 10 tools have clear, domain-specific docstrings (avg ~180 chars) explaining what data is returned and when to use each tool. Parameters are typed with min/max constraints (e.g., days 1-365). However, output schemas are not explicitly documented in the source code, tool responses are inferred from service layer returns. Error handling guidance is minimal; tools lack recovery hints for common failure modes (e.g., 'insufficient history' for analytics). Tool composition is sound (each does one thing), but some tools like get_exercises have minimal descriptions ('Get exercise records with detailed metrics') compared to peers like get_health_insights.
Get daily activity summaries, most recent day first. Each record has steps, active and total calories (kcal), distance (km), active minutes, and Polar's activity score (0-100, how much of the daily activity goal was reached). Useful for spotting sedentary streaks or unusually big days when explaining recovery or sleep changes.
Get the user's personal health baselines (rolling averages).
Get continuous biosensing data: heart rate, HRV, SpO2, temperature.
Get exercise records with detailed metrics, most recent first.
Get a complete health and recovery assessment for the user. This is the best first call for any "how am I doing?" question. Returns current metrics (HRV in ms, sleep score 0-100, resting heart rate in bpm) compared against the user's own personal baselines, detected patterns (sleep-HRV correlation, overtraining risk, HRV/sleep trends), anomalies (metrics outside the user's normal bounds), plain-language observations, and actionable suggestions with confidence scores. The `status` field reports how much history the analytics have to work with: features unlock at 7 days (baselines), 21 days (patterns and anomalies), and 30 days (full baselines). Early in a user's history most sections will be empty - that is expected, not an error.
Output schemas not documented. Tools return dict[str, Any] with no explicit field definitions visible in source. LLMs cannot plan downstream calls or extract specific fields without trial-and-error.
Minimal descriptions on 4 tools (get_exercises, get_biosensing, get_baselines, get_patterns). Descriptions under 60 chars lack context for when to call them vs similar tools. E.g., 'Get exercise records with detailed metrics' does not explain what 'detailed' means or when to prefer this over get_activity.
No error recovery guidance. Tools lack descriptions of failure modes (e.g., 'insufficient history for analytics', 'sync in progress', 'invalid user_id'). LLMs cannot self-correct or suggest next steps on failure.
Inferred effective spec: 2025-06-18+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 60 | 2025-06-18+ | v2 |
Get detected patterns in the user's health data.
Get recovery data: nightly recharge (ANS/HRV) and cardio load. `nightly_recharge` measures overnight autonomic nervous system recovery: ANS charge from -10 (very poor) to +10 (excellent) with a status label, overnight HRV average (ms), breathing rate, and heart rate. `cardio_load` measures training strain vs tolerance: a load ratio above ~1.3 means training load is rising faster than the body is adapting (overreaching risk); below ~0.8 means detraining. Use alongside get_sleep to judge readiness to train; both lists are most recent day first.
Get nightly sleep records, most recent night first. Each record has the sleep date, sleep score (0-100, Polar's overall quality rating), hours asleep split by stage (light/deep/REM), overnight averages for HRV (ms), heart rate (bpm), breathing rate (breaths/min), and skin temperature deviation (deg C), plus sleep start/end times. Nights with no recorded sleep are simply absent - gaps in the dates mean the watch wasn't worn, not zero sleep.
Get the status of the last sync operation.
Manually trigger a data sync from Polar AccessLink.
No pagination or result limits documented. Tools like get_exercises and get_biosensing may return large datasets (30 days of continuous HR data = thousands of points). No limit parameter or guidance on expected response size.
trigger_sync is a write operation but lacks confirmation/dry-run pattern. Agents may trigger syncs unintentionally. No idempotency guarantee documented.