Samsung Health Analytics MCP
# Samsung Health Analytics MCP
<p align="center">
<img src="docs/banner.png" alt="Pixel art of a person at a retro computer, with health data flowing from their smartwatch into a dashboard of charts" width="480">
</p>
Ask Claude about your Samsung Health data. Get the trends the Samsung Health app does not show you.
The Samsung Health app shows you today and this week. Your export holds months of data, but nothing in the app answers questions like these:
- How has my sleep changed month by month this year?
- Did my habits change after I moved, changed jobs or started training?
- When in the day do I actually move?
- What happens to my sleep and heart rate when I travel?
This repo loads your export into a local DuckDB database and gives Claude an MCP server to query it. Claude builds a one-page dashboard artifact first, then answers your questions.
## What you get
- **Month-by-month trends** for steps, active time, sleep, sleep score, deep sleep, sleep interruptions, sleeping heart rate and HRV.
- **Any two periods side by side** (before/after a move, a new job, a training block), with effect sizes, so small noise is not reported as change.
- **Trips detected automatically** from the timezone your phone reported. No location data needed. Each trip is compared with the 30 home days before it, and travel days are left out of the comparisons.
- **A 24-hour movement clock** showing when in the day you walk.
- **A dashboard artifact** with three actions for the next 30 days, written by Claude from your numbers.
## How it works
```
Samsung Health app
| Settings > Download personal data
v
export.zip ---> data/ (gitignored, stays on your machine)
|
v
+------ dev container ------+
| ingest -> health.duckdb |
| MCP server (stdio) |
+---------------------------+
^ docker exec (.mcp.json)
|
Claude Code
| 1. ingest_export
| 2. health-dashboard skill -> artifact
v 3. your questions
```
Only aggregates (averages, counts, comparisons) reach the conversation. The raw export never leaves your machine, and the server opens the database read-only for queries.
## Quick start
You need [Docker](https://www.docker.com/) and [Claude Code](https://claude.com/claude-code).
1. Export your data: Samsung Health app > profile > Settings > **Download personal data**. Copy the folder or zip to your computer.
2. Clone and open Claude Code in the repo:
```sh
git clone https://github.com/mo-debugs/samsung-health-analytics-mcp
cd samsung-health-analytics-mcp
claude
```
3. Say: **"Set up the health MCP."** Claude builds the dev container (a few minutes the first time) and asks you to reconnect the server with `/mcp`.
4. Say: **"My export is at ~/Downloads/<your export>.zip."** Claude copies it into `data/`, loads it and asks what you want to compare.
5. Claude builds your dashboard. Then ask anything:
- "Compare March with April."
- "Which month did I sleep best, and what was different?"
- "Show my unusual days for resting heart rate."
- "How did my last trip affect my sleep?"
Refresh monthly: download a new export and say "Here is my new export, refresh my dashboard."
### Without Docker
Install it as a Claude Code plugin instead (needs [uv](https://docs.astral.sh/uv/)). Data is then stored in `~/.samsung-health/`.
```
/plugin install samsung-health-analytics --marketplace mo-debugs/samsung-health-analytics-mcp
```
## MCP tools
| Tool | What it does |
|---|---|
| `ingest_export` | Load an export zip or folder (replaces the previous load) |
| `set_periods` | Save the two periods to compare |
| `overview` | Date range and data coverage per metric |
| `monthly_trends` | Monthly averages with month-over-month change |
| `compare_periods` | Two periods side by side, saved or ad hoc date ranges |
| `trips` | Trips from timezone changes, and the travel effect |
| `hourly_profile`, `weekday_profile` | When you move, by hour and weekday |
| `sleep_timing` | Bedtime, wake time, split nights, consistency |
| `rolling_baseline` | Days that were unusual for you (z-score vs your last 28 days) |
| `detect_locations` | Timeline of timezone runs, to spot moves |
| `workouts` | Exercise sessions by month and type |
| `schema`, `run_sql` | Read-only SQL for anything else |
| `dashboard_payload`, `render_dashboard` | Data for the report, and the rendered HTML |
## Notes and limits
- **Steps** use Samsung's merged daily total (phone and watch combined), so they are not double counted.
- **Travel detection:** a day counts as away when its timezone covers less than 35% of the surrounding 90 days. Daylight saving and permanent moves are handled. A trip longer than about a month starts to look like a move, so its first days may be counted as home.
- **Timezone is not location.** Two countries in the same timezone look the same. Claude asks you to name your trips.
- Samsung changes its export format between app versions. The ingester reads columns by name and skips files it cannot find. If something breaks, open an issue with the file name (never your data).
- This is wellness data, not medical advice.
## Development
```sh
uv sync
uv run pytest # pipeline test on a synthetic export
uv run shealth-ingest path/to/export.zip # CLI ingest
uv run shealth-dashboard --story story.json # render the dashboard without Claude
```
## Credits
Created by [Mohammed Sarfarazuddin](https://www.linkedin.com/in/mohammedsarfarazuddin). If you use or build on this work, please credit it with a link back to this repository.
Feel free to connect on [LinkedIn](https://www.linkedin.com/in/mohammedsarfarazuddin). Based in Riyadh? Feel free to reach out! I am on my quest to explore the best coffee place in Riyadh :)
## License
[MIT](LICENSE)
TDQS
Scored across 16 tools
Each tool targets a distinct analysis surface (trends, periods, trips, sleep, workouts, SQL). There is mild overlap between overview and dashboard_payload (both summarize the dataset), and between trips and detect_locations (both derive travel), but descriptions make the split between summary/payload and analysis/raw-timeline reasonably clear.
All names are snake_case and readable, but the convention is mixed: several are verb_noun (ingest_export, set_periods, render_dashboard, compare_periods, run_sql) while others are bare nouns (overview, trips, workouts, schema, sleep_timing). The inconsistency is minor but visible across 16 tools.
16 tools is just over the comfortable band but justified by a genuinely broad analytics domain (ingestion, overview, trends, profiles, comparisons, travel, SQL escape hatch, dashboard). No single tool looks trivially redundant, though the overview/dashboard_payload pair could likely merge.
Coverage is strong: ingestion, schema inspection, raw SQL, period definition, trends, comparisons, profiles, sleep, baselines, trips, workouts, and dashboard output. Minor gaps exist around exporting analysis results or persistent saved analyses, but agents can work around them via run_sql.