Skills healthsync
Queries Apple Health data stored in a local SQLite database. Use this skill to read heart rate, steps, SpO2, VO2 Max, sleep, workouts, resting heart rate, HRV, blood pressure, active/basal energy, body metrics, mobility, running metrics, mindful sessions, wrist temperature, and more. Can query via the healthsync CLI or directly via SQLite. Read-only — never write to the database.
git clone https://github.com/openclaw/skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/bro3886/healthsync" ~/.claude/skills/clawdbot-skills-healthsync && rm -rf "$T"
skills/bro3886/healthsync/SKILL.mdhealthsync — Apple Health Data Query Skill
Installing healthsync
# macOS and Linux (recommended) curl -fsSL https://healthsync.sidv.dev/install | bash # Or via Go go install github.com/BRO3886/healthsync@latest
After installing the binary, parse your Apple Health export:
# Export from Health app → profile picture → Export All Health Data healthsync parse ~/Downloads/export.zip
Install this skill into your agent:
# Claude Code or Codex healthsync skills install # OpenClaw healthsync skills install --agent openclaw
Query Apple Health export data stored in a local SQLite database. This skill is read-only — never INSERT, UPDATE, DELETE, or DROP anything.
Important Constraints
- READ ONLY — You must NEVER write to the database. No INSERT, UPDATE, DELETE, DROP, ALTER, or any write operations.
- Two query methods: CLI (
) or direct SQLite (healthsync query
)sqlite3 ~/.healthsync/healthsync.db - Prefer CLI for simple queries. Use direct SQLite for complex aggregations, joins, or custom SQL.
Database Location
Default:
~/.healthsync/healthsync.db
Quick Start
# Recent heart rate readings healthsync query heart-rate --limit 10 # Steps in a date range healthsync query steps --from 2024-01-01 --to 2024-06-30 --limit 100 # Deduplicated daily step totals healthsync query steps --total --from 2024-01-01 # Deduplicated daily active energy totals healthsync query active-energy --total --from 2024-01-01 # Workouts as JSON healthsync query workouts --format json --limit 20 # Sleep data as CSV healthsync query sleep --format csv --limit 50 # Resting heart rate trend healthsync query resting-heart-rate --limit 30 # HRV readings healthsync query hrv --limit 30 # Blood pressure healthsync query blood-pressure --limit 20 # Body weight trend healthsync query body-mass --limit 30 # Direct SQLite for aggregations sqlite3 ~/.healthsync/healthsync.db "SELECT date(start_date) as day, SUM(value) as total_steps FROM steps GROUP BY day ORDER BY day DESC LIMIT 7" # Average resting heart rate per week sqlite3 ~/.healthsync/healthsync.db "SELECT strftime('%Y-W%W', start_date) as week, ROUND(AVG(value),1) as avg_rhr FROM resting_heart_rate GROUP BY week ORDER BY week DESC LIMIT 12"
CLI Reference
healthsync query <table>
healthsync query <table>| Flag | Description | Default |
|---|---|---|
| Filter records from this date (inclusive) | — |
| Filter records to this date (inclusive) | — |
| Maximum records to return | 50 |
| Output format: , , | table |
| Deduplicated daily totals (steps, active-energy, basal-energy only) | false |
| Override database path | |
Available Tables
Cardiac
| CLI Name | DB Table | Notes |
|---|---|---|
| | BPM; high-frequency |
| | Daily RHR |
| | HRV SDNN (ms); nightly |
| | Post-exercise HR recovery |
| | Breaths/min |
| | Paired systolic + diastolic (mmHg) |
Activity / Energy
| CLI Name | DB Table | Notes |
|---|---|---|
| | Supports |
| | kcal; supports |
| | kcal; supports |
| | Minutes |
| | Minutes |
| | Count |
| | km/mi |
| | km/mi |
Body
| CLI Name | DB Table | Notes |
|---|---|---|
| | kg/lb |
| | |
| | m/ft |
Mobility / Walking
| CLI Name | DB Table | Notes |
|---|---|---|
| | m/s |
| | m |
| | % |
| | % |
| | Score |
| | ft/s |
| | ft/s |
| | m |
Running
| CLI Name | DB Table | Notes |
|---|---|---|
| | m/s |
| | W |
| | m |
| | ms |
| | cm |
Other
| CLI Name | DB Table | Notes |
|---|---|---|
| | 0-1 fraction (0.98 = 98%) |
| | mL/min·kg |
| | Sleep stages (category, no unit) |
| | duration, distance, energy |
| | °C deviation |
| | Minutes |
| | mL/L |
| | MET score |
| | BPM while walking |
| | Category; no unit column |
| | Category; no unit column |
healthsync parse <file>
healthsync parse <file>Parse an Apple Health export into the database. (Informational — do not run unless the user asks.)
| Flag | Description | Default |
|---|---|---|
| Verbose logging with progress rate | false |
| Override database path | |
healthsync server
healthsync serverStart HTTP server for receiving uploads. (Informational — do not start unless the user asks.)
Endpoints:
— UploadPOST /api/upload
or.zip
(multipart form, field:.xml
). Returns 202, parses async.file
— Poll parse progress.GET /api/upload/status
— Query data as JSON.GET /api/health/{table}?from=&to=&limit=
Database Schema
Standard quantity tables
Schema:
id, source_name, start_date, end_date, value REAL, unit TEXT, created_at
Applies to all tables except
blood_pressure, sleep, mindful_sessions, stand_hours, and workouts.
CREATE TABLE resting_heart_rate ( id INTEGER PRIMARY KEY AUTOINCREMENT, source_name TEXT NOT NULL, start_date TEXT NOT NULL, end_date TEXT NOT NULL, value REAL NOT NULL, unit TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP, UNIQUE(source_name, start_date, end_date, value) );
blood_pressure (special — paired systolic + diastolic)
CREATE TABLE blood_pressure ( id INTEGER PRIMARY KEY AUTOINCREMENT, source_name TEXT NOT NULL, start_date TEXT NOT NULL, end_date TEXT NOT NULL, systolic REAL NOT NULL, -- mmHg diastolic REAL NOT NULL, -- mmHg unit TEXT NOT NULL, -- "mmHg" created_at TEXT DEFAULT CURRENT_TIMESTAMP, UNIQUE(source_name, start_date, end_date, systolic, diastolic) );
Category tables — no unit column
Applies to:
sleep, mindful_sessions, stand_hours
CREATE TABLE sleep ( id INTEGER PRIMARY KEY AUTOINCREMENT, source_name TEXT NOT NULL, start_date TEXT NOT NULL, end_date TEXT NOT NULL, value TEXT NOT NULL, -- e.g. HKCategoryValueSleepAnalysisAsleepCore created_at TEXT DEFAULT CURRENT_TIMESTAMP, UNIQUE(source_name, start_date, end_date, value) );
workouts
CREATE TABLE workouts ( id INTEGER PRIMARY KEY AUTOINCREMENT, activity_type TEXT NOT NULL, source_name TEXT NOT NULL, start_date TEXT NOT NULL, end_date TEXT NOT NULL, duration REAL, duration_unit TEXT, total_distance REAL, total_distance_unit TEXT, total_energy_burned REAL, total_energy_burned_unit TEXT, created_at TEXT DEFAULT CURRENT_TIMESTAMP, UNIQUE(activity_type, start_date, end_date, source_name) );
Date Format
All dates stored as text:
2024-01-15 08:30:00 +0530. Filter with date prefix — 2024-01-01 works via SQLite string comparison.
Sleep Stage Values
| Value | Meaning |
|---|---|
| In bed |
| Core sleep |
| Deep sleep |
| REM sleep |
| Awake |
| Unspecified |
Common Query Patterns
Daily step totals (deduped)
healthsync query steps --total --from 2024-01-01
Daily active energy totals (deduped)
healthsync query active-energy --total --from 2024-01-01
Average resting heart rate per week
SELECT strftime('%Y-W%W', start_date) as week, ROUND(AVG(value), 1) as avg_rhr FROM resting_heart_rate GROUP BY week ORDER BY week DESC LIMIT 12;
HRV trend
SELECT date(start_date) as day, ROUND(AVG(value), 1) as hrv_ms FROM hrv GROUP BY day ORDER BY day DESC LIMIT 30;
Blood pressure history
SELECT date(start_date) as day, ROUND(AVG(systolic), 1) as avg_sys, ROUND(AVG(diastolic), 1) as avg_dia FROM blood_pressure GROUP BY day ORDER BY day DESC LIMIT 30;
Body weight trend
SELECT date(start_date) as day, value as kg FROM body_mass ORDER BY day DESC LIMIT 30;
Sleep duration per night
SELECT date(start_date) as night, ROUND(SUM((julianday(end_date) - julianday(start_date)) * 24), 1) as hours FROM sleep WHERE value LIKE '%Asleep%' GROUP BY night ORDER BY night DESC LIMIT 14;
Average heart rate per day
SELECT date(start_date) as day, ROUND(AVG(value), 1) as avg_hr, MIN(value) as min_hr, MAX(value) as max_hr FROM heart_rate GROUP BY day ORDER BY day DESC LIMIT 30;
Workout summary
SELECT activity_type, COUNT(*) as count, ROUND(AVG(duration), 1) as avg_min, ROUND(SUM(total_energy_burned)) as total_kcal FROM workouts GROUP BY activity_type ORDER BY count DESC;
Weekly VO2 Max trend
SELECT strftime('%Y-W%W', start_date) as week, ROUND(AVG(value), 2) as avg_vo2 FROM vo2_max GROUP BY week ORDER BY week DESC LIMIT 12;
Mindfulness minutes per week
SELECT strftime('%Y-W%W', start_date) as week, ROUND(SUM((julianday(end_date) - julianday(start_date)) * 1440), 0) as minutes FROM mindful_sessions GROUP BY week ORDER BY week DESC LIMIT 12;
Limitations
- Read-only — This skill must never write to the database
- No real-time data — Data is only as fresh as the last
runhealthsync parse - Date filtering is string-based — Timezone offsets are part of the stored date string
- SpO2 values are fractions — 0.98 means 98%, not 98
- Blood pressure is paired — systolic and diastolic are stored together in one row per measurement
- Category tables have no unit column —
,sleep
,mindful_sessions
store text values, not numericstand_hours