MCP server for querying Apple Health export data. Imports your Apple Health export into a DuckDB database and exposes it through an MCP server (Streamable HTTP or stdio), making your health data queryable by AI assistants.
Why
neiltron/apple-health-mcp is a great project, but it depends on Simple Health Export CSV to pre-process the data. I couldn't get that exporter to work for longer time ranges, so I wrote this to work directly with Apple's raw export data — and do it much faster in Rust.
Setup
Prerequisites
- Rust toolchain (1.70+)
- An Apple Health data export (exported from the Health app on your iPhone)
Build & Install
cargo build --release cp target/release/apple-health-mcp /usr/local/bin/
Export your Apple Health data
- Open the Health app on your iPhone or iPad
- Tap your profile picture in the upper right corner
- Tap Export All Health Data (note: this can be several gigabytes of data)
- Copy the resulting zip file to the machine you'll run the import on
- Extract the zip — the extracted folder is what you pass to
--export-dirbelow
The export directory should contain export.xml and optionally electrocardiograms/ and workout-routes/ subdirectories.
Import
apple-health-mcp import --export-dir /path/to/apple_health_export --db ./health.duckdb
This parses the XML export, ECG recordings, and GPX workout routes into a local DuckDB database. Re-running import on the same database is safe — records are deduplicated by content hash.
Serve
The server supports two transport modes: HTTP (Streamable HTTP, the default) and stdio (stdin/stdout, for clients like Claude Desktop that spawn the server as a subprocess).
HTTP (default):
apple-health-mcp serve --db ./health.duckdb --port 8080
The MCP endpoint will be available at http://127.0.0.1:8080/mcp.
stdio:
apple-health-mcp serve --db ./health.duckdb --transport stdio
The server reads JSON-RPC messages from stdin and writes responses to stdout. This is typically invoked by the MCP client directly (see Claude Desktop config below).
MCP Tools
| Tool | Description |
|---|---|
list_record_types |
List all health record types with counts and date ranges |
query_records |
Query records by type, date range, and source |
get_record_statistics |
Aggregated stats (avg/min/max/sum) by day/week/month/year |
list_workouts |
List workouts with optional filtering |
get_workout_details |
Full workout details including events, statistics, and route availability |
get_workout_route |
GPS route data for a workout |
get_activity_summaries |
Daily activity ring data (energy, exercise, stand hours with goals) |
list_ecg_readings |
List ECG recordings with dates and classifications |
get_ecg_data |
Full ECG waveform with voltage samples |
list_data_sources |
Devices and apps that contributed data |
get_import_history |
History of data imports |
run_custom_query |
Run arbitrary read-only SQL (SELECT/WITH) against the database |
Client Configuration
For HTTP-based clients, make sure the server is running before connecting. Stdio-based clients (Claude Desktop) launch the server automatically.
Claude Code
claude mcp add apple-health --transport streamable-http http://127.0.0.1:8080/mcp
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"apple-health": {
"command": "apple-health-mcp",
"args": ["serve", "--db", "/path/to/health.duckdb", "--transport", "stdio"]
}
}
}Cursor
Add to .cursor/mcp.json in your project or ~/.cursor/mcp.json globally:
{
"mcpServers": {
"apple-health": {
"type": "streamable-http",
"url": "http://127.0.0.1:8080/mcp"
}
}
}Windsurf
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"apple-health": {
"type": "streamable-http",
"url": "http://127.0.0.1:8080/mcp"
}
}
}