# Quantified Self MCP
[](https://github.com/Thecimal/quantified-self-mcp/actions)
[](https://github.com/Thecimal/quantified-self-mcp/actions/workflows/codeql.yml)
[](https://pypi.org/project/quantified-self-mcp/)
[](https://pypi.org/project/quantified-self-mcp/)
[](https://github.com/Thecimal/quantified-self-mcp/blob/main/LICENSE)
[](https://github.com/astral-sh/ruff)
[](https://github.com/pre-commit/pre-commit)
[](https://m8ven.ai/mcp/thecimal-quantified-self-mcp-v6tlvp)
[](https://glama.ai/mcp/servers/Thecimal/quantified-self-mcp)
> **Your health data. Your AI. Your machine.**
>
> A local-first MCP server that gives AI agents access to your personal health data โ with **privacy, provenance, and evidence built in**.
ยท **[Documentation](docs/)**
---
## What is it?
Quantified Self MCP gives an AI agent a **local, structured interface to your own health history**.
Instead of another health dashboard, you can ask your AI questions like:
```text
Why did my HRV change recently?
How has my sleep changed over the last 30 days?
What happened to my resting heart rate after my workouts increased?
What patterns do you see across my recent health data?
Which metrics changed the most this month?
```
The AI retrieves the relevant data through MCP and analyzes it.
> **The goal isn't another health dashboard.**
>
> **It's a trustworthy interface between your health history and your AI.**
---
## Why is it different?
### ๐ Local-first
Your health database runs locally in SQLite.
You control where your data goes.
You can use a completely local AI stack:
```text
Health Data
โ
Local SQLite
โ
Quantified Self MCP
โ
MCP Agent
โ
Local LLM
```
Cloud models are also supported. In that configuration, the MCP database remains local, but data returned by MCP tools may be sent to the model provider.
### ๐ค AI-native
Built specifically for **MCP-compatible AI agents**, rather than another standalone health application.
### ๐ Evidence & provenance
Analytics can be traced back to the underlying health data and its provenance.
The goal is not simply:
```text
HRV โ 24%
```
but understanding:
```text
What data produced this result?
Where did it come from?
What period was analyzed?
How strong is the evidence, and how strongly may it be claimed?
```
Concretely, every trend, baseline, anomaly, comparison, correlation, recent change, and explained metric carries a `claim` alongside its numbers โ not just descriptive coverage, but an explicit, machine-checkable statement of how strongly the result may be reported:
```text
Analysis result
โ
claim: ClaimEvidence
โโโ evidence โ what data was actually observed (coverage, gaps, freshness)
โโโ profile โ how much evaluative evidence exists, per dimension
โ (sample, temporal, missingness, ...)
โโโ decision โ what claim strength is justified: insufficient,
suggestive, detectable_not_meaningful, or supported โ
plus the specific caveats that must be stated
```
`evidence` is descriptive: it reports the coverage a result rests on (how many days were logged, how large any gaps are, how fresh the data is). `profile` evaluates that coverage along several independent dimensions rather than collapsing it into one number. `decision` is the authoritative output: the only field that says how strongly the result may actually be claimed, and it is derived exclusively from the assessed dimensions in `profile` โ never from a raw coverage number by itself. Composite results (like explaining a metric change, which combines a headline claim, a trend claim, and any correlations) roll their component decisions up into a single `overall_decision`, which is never stronger than the weakest component.
**Without evidence:**
> Your HRV decreased 24% over the last 30 days.
**With evidence:**
> Your HRV decreased 24% over the last 30 days โ but HRV was only logged on 71% of those days, so treat this trend cautiously rather than as a settled pattern.
The second answer is what `calculate_metric_trend` (and every other analytics tool) is designed to make possible: the tool returns the 24% figure *and* a `claim.decision` alongside it (e.g. `tier: "suggestive"`, with `must_state` naming the specific gaps and low-coverage days behind that tier), and each tool's own description tells the calling model to report that tier and those caveats rather than stating the number as if it came from a complete series.
### ๐ Longitudinal
Analyze health history across days, weeks, months, and years:
- trends
- baselines
- anomalies
- period comparisons
- correlations
- recent changes
- metric explanations
### ๐ฅ Import existing data
Bring your existing health history into the local database.
Supported imports include:
- CSV
- Apple Health exports
- WHOOP Developer API JSON (v2)
See the [import documentation](docs/importing.md).
---
## What can your AI do?
### Read
- Health metrics
- Metric history
- Raw measurements
- Workout sessions
- Data provenance
### Analyze
- Baselines
- Trends
- Anomalies
- Period comparisons
- Correlations
### Explain
- Recent changes
- Metric changes
- Supporting evidence
- Data provenance
The MCP currently exposes **20 tools** across data access, measurements, workouts, analytics, personal intelligence, and data freshness (`get_data_status`, `get_import_status`).
See the [tool reference](docs/tools.md) for the complete list.
---
## Supported data
Currently supported metrics include:
- ๐ Steps
- ๐ด Sleep
- โค๏ธ Heart rate
- โค๏ธ Resting heart rate
- ๐ HRV
- โ๏ธ Weight
- ๐๏ธ Workout minutes
- ๐ Mood
- ๐ง Water
The data model is extensible, so you can keep only the metrics you actually use.
---
## Quick start
### Install
```bash
pip install quantified-self-mcp
```
### Import your data
CSV:
```bash
quantified-self-init-db your-health-data.csv
```
Apple Health:
```bash
quantified-self-init-db export.xml
```
Android Health Connect:
```bash
quantified-self-init-db health_connect_export.zip
```
WHOOP Developer API (v2) JSON:
```bash
quantified-self-init-db whoop.json --source whoop
```
### Verify your setup (optional)
Run the built-in diagnostic tool to check Python, dependencies, and database readiness:
```bash
quantified-self-doctor
```
### Back up and restore your data
Do not back up by copying `health.db`: the database runs in WAL mode, so recent changes can still be in
`health.db-wal`, and a copy of `health.db` alone can be empty or out of date. Use the backup command, which
takes a consistent snapshot even while your MCP client is running:
```bash
quantified-self-backup create ~/backups/health-2026-10-21.db
```
It never overwrites an existing backup. To restore (close your MCP client first), run:
```bash
quantified-self-backup restore ~/backups/health-2026-10-21.db
```
The backup is checked before anything is touched (it must pass SQLite's integrity check, be a health database,
and not come from a newer release). Your current database is moved aside as `health.db.pre-restore-