| name | apple-health-mcp-server |
| description | MCP server for querying Apple Health data with natural language using DuckDB, Elasticsearch, or ClickHouse backends |
| triggers | ["how do I set up Apple Health MCP server","query my Apple Health data with natural language","analyze Apple Health XML export","configure apple health mcp with DuckDB","search health records using MCP","import Apple Health data into database","build health data analysis with MCP","troubleshoot Apple Health MCP connection"] |
Apple Health MCP Server Skill
Skill by ara.so — MCP Skills collection.
Overview
Apple Health MCP Server is a Model Context Protocol (MCP) server built with FastMCP that enables natural language querying of Apple Health data. It parses Apple Health XML exports and loads them into DuckDB, Elasticsearch, or ClickHouse for efficient querying. The server exposes MCP tools that allow LLMs to analyze health records, generate statistics, and identify trends without requiring SQL knowledge.
Key capabilities:
- Parse and import Apple Health XML exports
- Natural language queries over health data
- Multiple backend support (DuckDB, Elasticsearch, ClickHouse)
- Structured data analysis and trend detection
- Docker-ready deployment
Installation
Prerequisites
- Python 3.10+
- Apple Health export XML file
- MCP-compatible client (Claude Desktop, Cursor, etc.)
Setup Steps
- Clone the repository:
git clone https://github.com/the-momentum/apple-health-mcp-server.git
cd apple-health-mcp-server
- Install dependencies:
pip install -e .
- Configure environment variables:
Create a .env file:
APPLE_HEALTH_EXPORT_PATH=/path/to/apple_health_export/export.xml
STORAGE_BACKEND=duckdb
DUCKDB_PATH=./data/health.db
LOG_LEVEL=INFO
- Import your Apple Health data:
python -m apple_health_mcp_server.import_data
MCP Client Configuration
Add to your MCP client configuration (e.g., Claude Desktop claude_desktop_config.json):
{
"mcpServers": {
"apple-health": {
"command": "python",
"args": ["-m", "apple_health_mcp_server"],
"env": {
"APPLE_HEALTH_EXPORT_PATH": "/path/to/export.xml",
"STORAGE_BACKEND": "duckdb",
"DUCKDB_PATH": "./data/health.db"
}
}
}
}
Docker Installation
docker build -t apple-health-mcp-server .
docker run -v /path/to/export.xml:/data/export.xml \
-v ./data:/app/data \
-e APPLE_HEALTH_EXPORT_PATH=/data/export.xml \
-e STORAGE_BACKEND=duckdb \
-e DUCKDB_PATH=/app/data/health.db \
apple-health-mcp-server
Available MCP Tools
The server exposes the following MCP tools:
1. analyze_structure
Analyzes the structure and available data types in your Apple Health export.
{
"name": "analyze_structure",
"arguments": {}
}
2. search_records
Search health records using flexible filters.
{
"name": "search_records",
"arguments": {
"record_type": "HKQuantityTypeIdentifierStepCount",
"start_date": "2024-01-01",
"end_date": "2024-01-31",
"limit": 100,
"source_name": "iPhone"
}
}
Parameters:
record_type: Apple Health record type identifier
start_date: ISO format date (YYYY-MM-DD)
end_date: ISO format date (YYYY-MM-DD)
limit: Maximum records to return (default: 100)
source_name: Filter by data source device/app
unit: Filter by measurement unit
3. get_records_by_type
Extract all records of a specific type.
{
"name": "get_records_by_type",
"arguments": {
"record_type": "HKQuantityTypeIdentifierHeartRate",
"limit": 500
}
}
4. generate_statistics
Generate statistical summaries for a specific metric.
{
"name": "generate_statistics",
"arguments": {
"record_type": "HKQuantityTypeIdentifierDistanceWalkingRunning",
"start_date": "2024-06-01",
"end_date": "2024-06-30",
"aggregation": "daily"
}
}
Aggregation options: daily, weekly, monthly
5. analyze_trends
Identify trends and patterns in health data.
{
"name": "analyze_trends",
"arguments": {
"record_type": "HKQuantityTypeIdentifierStepCount",
"time_period": "last_30_days",
"trend_type": "moving_average"
}
}
Common Usage Patterns
Pattern 1: Initial Data Exploration
analyze_structure()
search_records(
record_type="HKQuantityTypeIdentifierStepCount",
start_date="2024-01-01",
end_date="2024-12-31"
)
Pattern 2: Monthly Activity Summary
generate_statistics(
record_type="HKQuantityTypeIdentifierStepCount",
start_date="2024-06-01",
end_date="2024-06-30",
aggregation="daily"
)
search_records(
record_type="HKWorkoutTypeIdentifier",
start_date="2024-06-01",
end_date="2024-06-30"
)
Pattern 3: Heart Rate Analysis
get_records_by_type(
record_type="HKQuantityTypeIdentifierHeartRate",
limit=1000
)
analyze_trends(
record_type="HKQuantityTypeIdentifierHeartRate",
time_period="last_90_days",
trend_type="moving_average"
)
Python API Usage
While primarily an MCP server, you can use the underlying modules directly:
from apple_health_mcp_server.parser import AppleHealthParser
from apple_health_mcp_server.storage.duckdb import DuckDBStorage
parser = AppleHealthParser("/path/to/export.xml")
records = parser.parse()
storage = DuckDBStorage("./health.db")
storage.import_records(records)
results = storage.query(
record_type="HKQuantityTypeIdentifierStepCount",
start_date="2024-01-01",
end_date="2024-12-31"
)
Custom Query Execution
from apple_health_mcp_server.storage.duckdb import DuckDBStorage
storage = DuckDBStorage("./health.db")
sql = """
SELECT
DATE(start_date) as date,
SUM(CAST(value AS DOUBLE)) as total_steps
FROM health_records
WHERE type = 'HKQuantityTypeIdentifierStepCount'
AND start_date >= '2024-01-01'
GROUP BY DATE(start_date)
ORDER BY date
"""
results = storage.execute_query(sql)
Common Health Record Types
Key Apple Health record type identifiers:
- Activity:
HKQuantityTypeIdentifierStepCount, HKQuantityTypeIdentifierDistanceWalkingRunning
- Heart:
HKQuantityTypeIdentifierHeartRate, HKQuantityTypeIdentifierRestingHeartRate
- Sleep:
HKCategoryTypeIdentifierSleepAnalysis
- Workouts:
HKWorkoutTypeIdentifier
- Body:
HKQuantityTypeIdentifierBodyMass, HKQuantityTypeIdentifierHeight
- Vitals:
HKQuantityTypeIdentifierBloodPressureSystolic, HKQuantityTypeIdentifierOxygenSaturation
Configuration Options
Storage Backends
DuckDB (default - local file):
STORAGE_BACKEND=duckdb
DUCKDB_PATH=./data/health.db
Elasticsearch (scalable search):
STORAGE_BACKEND=elasticsearch
ELASTICSEARCH_URL=http://localhost:9200
ELASTICSEARCH_INDEX=health_records
ELASTICSEARCH_API_KEY=${ELASTICSEARCH_API_KEY}
ClickHouse (analytics):
STORAGE_BACKEND=clickhouse
CLICKHOUSE_HOST=localhost
CLICKHOUSE_PORT=9000
CLICKHOUSE_DATABASE=health
CLICKHOUSE_USER=${CLICKHOUSE_USER}
CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD}
Performance Tuning
IMPORT_BATCH_SIZE=10000
DEFAULT_QUERY_LIMIT=100
MAX_QUERY_LIMIT=10000
DB_POOL_SIZE=5
Troubleshooting
Issue: Import fails with "File not found"
Solution: Verify the XML path and ensure the export is unzipped:
ls -lh "$APPLE_HEALTH_EXPORT_PATH"
unzip export.zip -d ./export
export APPLE_HEALTH_EXPORT_PATH=./export/apple_health_export/export.xml
Issue: MCP server not connecting
Solution: Check MCP client logs and verify configuration:
python -m apple_health_mcp_server
env | grep APPLE_HEALTH
cat ~/.config/Claude/claude_desktop_config.json | jq .
Issue: Slow queries on large datasets
Solution: Switch to Elasticsearch or ClickHouse for better performance:
STORAGE_BACKEND=clickhouse
STORAGE_BACKEND=elasticsearch
CREATE INDEX idx_type_date ON health_records(type, start_date);
Issue: Memory errors during import
Solution: Reduce batch size and use streaming:
IMPORT_BATCH_SIZE=5000
docker run --memory=2g apple-health-mcp-server
Issue: Missing data after import
Solution: Verify XML structure and check parser logs:
from apple_health_mcp_server.parser import AppleHealthParser
parser = AppleHealthParser("/path/to/export.xml")
parser.validate()
from apple_health_mcp_server.storage.duckdb import DuckDBStorage
storage = DuckDBStorage("./health.db")
print(storage.get_record_type_counts())
Issue: Date filtering not working
Solution: Ensure ISO 8601 date format (YYYY-MM-DD):
search_records(
record_type="HKQuantityTypeIdentifierStepCount",
start_date="2024-01-01",
end_date="2024-12-31"
)
Advanced Usage
Custom Tool Extension
from apple_health_mcp_server.server import app
from fastmcp import Context
@app.tool()
async def custom_health_analysis(
ctx: Context,
metric: str,
threshold: float
) -> str:
"""Custom analysis tool."""
storage = ctx.app_context["storage"]
results = storage.query(
record_type=metric,
filters={"value": {"$gte": threshold}}
)
return f"Found {len(results)} records above threshold"
Batch Data Export
from apple_health_mcp_server.storage.duckdb import DuckDBStorage
import pandas as pd
storage = DuckDBStorage("./health.db")
df = pd.DataFrame(storage.query(
record_type="HKQuantityTypeIdentifierStepCount"
))
df.to_csv("steps_export.csv", index=False)
df.to_parquet("steps_export.parquet")
Related Projects
- Open Wearables - Evolution of this project with continuous sync support
- FastMCP - Framework used to build this MCP server
Resources