health-hub
Provides tools for querying health data from Apple Health (iPhone Health app), including body measurements, steps, heart rate, sleep, and workouts, and for searching bundled Apple HealthKit documentation.
Provides tools for iOS development, enabling checking the development environment, building, installing, and reading logs from the iOS collector app.
Allows querying and logging health data stored in the local SQLite database, including samples, weekly reports, sync status, workouts, and meals.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@health-hubhow did my weight change last week?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Health Data Hub: iPhone collector + local Mac database + MCP
A lightweight, personal health-data collector. It moves the data in your iPhone's Health app to your own Mac, stores it as one SQLite file, and lets AI assistants such as Claude and Codex query it. No cloud, no account, no server.
Version 0.3.2 (changelog) · Status: in daily use by the author since 2026-10 (as of 2026-10-06) · iPhone with iOS 18+ and a Mac on the same Wi-Fi.
Want an AI assistant to install it for you? Hand docs/AGENT_INSTALL.md to Claude Code or Codex and it will follow the steps.
What it is
Three small parts in a line:
iPhone collector app (native Swift): reads the Health app and pushes new data to the Mac.
Mac receiver (Python, FastAPI): receives the data on your home Wi-Fi and writes it to the local SQLite file
data/health.sqlite.MCP server (Python, no dependencies): lets Claude Code, Codex and other AI assistants query the data, build weekly reports, and log workouts and meals by hand.
What it does
Collects 11 data types automatically: body mass, lean body mass, body fat %, BMI, waist circumference, steps, heart rate, resting heart rate, heart rate variability (HRV), sleep and workouts. Field meanings: docs/health-data-fields.md.
Anything a smart scale or watch writes into the Health app is collected too — the collector reads the Health app and does not care which device wrote the data.
Ask your AI assistant directly: "How did my weight change last week?", "Am I sleeping enough?", "Give me this week's report."
Log workouts and meals by hand (
log_workout/log_meal).
Why
The Health app keeps its data on the phone: exporting means tapping through menus, the export is one huge XML file, and AI assistants cannot see it. Most sync services upload the data to someone else's server.
This project takes another route: the data only travels between your own phone and your own Mac, lands in a SQLite file you can open directly, and reaches your local AI assistant through MCP.
Scope
Built for one person, one iPhone and one Mac. It is not a multi-user platform.
Advantages:
Private: phone → home Wi-Fi → your Mac. No third party in between.
No loss, no duplicates: the phone keeps a sync position per data type; batches that fail to send wait in a local queue on the phone and are resent unchanged; the Mac deduplicates by sample uuid, so a resend is stored once.
Open format: one SQLite file any tool can read; schema in
server/schema.sql.Ready for AI: the MCP server plugs into Claude Code and Codex as is.
Light: no cloud service, database server or Docker. The Mac runs one Python process.
Tested: automated tests on both the Python and Swift sides, plus on-device acceptance.
Limits — what it does not do:
iPhone + Mac only. No Android, Windows or Linux phone side. The receiver can run anywhere Python runs, but
server/run.shuses macOSnetworksetupanddns-sd.Read-only. It never writes back to the Health app.
iOS background wake-ups are unreliable. iOS decides when to wake the app; the author measured 2 background wake-ups in 33 hours. So a Shortcuts automation opens the app on a schedule, which guarantees at least one sync a day, not real time.
Phone and Mac must share a Wi-Fi network (or you set up Tailscale as a backup path). While the Mac is off or asleep the data waits in the phone's queue and is resent later.
Scale data must reach the Health app first. A Eufy scale, for example, writes through its own app; only then can the collector read it.
Only the 11 types above. No ECG, blood oxygen, medications, etc.
No web UI. You query through MCP (an AI assistant) or read SQLite directly.
The app is not on the App Store. You build it with Xcode and install it yourself. A free Apple ID works, but the installed app expires after 7 days and must be reinstalled.
How it works
iPhone
┌─ Health app (HealthKit)
│ │ read only
│ ▼
└─ Collector app
· one sync position per data type
· failed batches are queued and resent
· syncs when the app opens / on background wake
│
│ HTTP POST + Bearer token → healthhub.local:8765
▼
Mac (same Wi-Fi)
┌─ Receiver: server/run.sh (FastAPI :8765)
│ POST /ingest · GET /health
│ │ dedupe by uuid, write
│ ▼
├─ data/health.sqlite
│ │
│ ▼
└─ MCP server health-hub ← Claude / CodexIncremental sync: the app uses HealthKit anchored queries to fetch only what is new. A type's anchor moves forward only after the Mac confirms receipt, so a failure halfway never loses data.
When it syncs: when the app opens (with the "打开 App 时自动同步" — auto-sync on open — switch on), and when iOS wakes it in the background, which is rare. A daily Shortcuts automation is the safety net.
Finding the Mac: the receiver binds to the Mac's Wi-Fi address and announces the Bonjour name
healthhub.local, so the phone keeps working when the Mac's IP changes.Auth: the Mac generates a 32-character access token; it is baked into the app at build time (locally, never in git) and sent with every request.
Full protocol: docs/sync-protocol.md.
Install
Prerequisites
A Mac with Xcode (iOS 18 SDK or later), uv, XcodeGen (
brew install xcodegen) and Python 3.9+.An iPhone on iOS 18+, connected by cable, with Developer Mode on.
An Apple ID signed in under Xcode → Settings → Accounts (a paid developer account is easier).
Step 1: Mac receiver
git clone <this-repo-url> health-hub && cd health-hub
uv sync # install Python dependencies
uv run python -m server.token new # create the access token in data/ingest_token (mode 0600)
server/run.sh # start the receiver: Wi-Fi address :8765, announces healthhub.localCheck from another terminal: curl http://healthhub.local:8765/health returns {"status":"ok"}.
On first run macOS may ask whether to accept incoming connections — choose Allow.
To keep it running, start server/run.sh from launchd or your login items.
Step 2: build and install the iPhone app
Create
ios/local.xcconfig(already in.gitignore):DEVELOPMENT_TEAM = <your 10-character Team ID> PRODUCT_BUNDLE_IDENTIFIER = com.<your-name>.healthcollectorsecurity find-identity -v -p codesigningshows the Team ID in parentheses.Bake the Mac address and token into the app, generate the project and build:
ios/make_local_config.sh # writes ios/HealthCollector/LocalConfig.plist (not in git; never prints the token) cd ios && xcodegen generate xcodebuild -project HealthCollector.xcodeproj -scheme HealthCollector \ -destination 'generic/platform=iOS' -configuration Debug \ -allowProvisioningUpdates buildOr, after
xcodegen generate, openios/HealthCollector.xcodeprojin Xcode, pick your iPhone and press Run.Install on the phone from the command line:
APP=$(find ~/Library/Developer/Xcode/DerivedData -path '*Debug-iphoneos/HealthCollector.app' | head -1) xcrun devicectl list devices # find your device name xcrun devicectl device install app --device "<device-name>" "$APP"On first install, trust the developer on the phone under Settings → General → VPN & Device Management.
Step 3: first run on the phone
The app's interface is in Chinese; the English meaning is in parentheses.
Open the collector, tap 授权读取健康数据 (allow reading health data) and allow everything in the system sheet.
Tap 测试连接 (test connection); it should succeed — the Mac address and token are already filled in.
Tap 立即同步 (sync now). The first sync uploads your full history to the Mac.
Turn on 打开 App 时自动同步 (auto-sync on open). The same switch also controls background sync.
Step 4: Shortcuts automations for a daily sync (recommended)
iOS rarely wakes the app in the background, so in the Shortcuts app → Automation, create two automations:
Time of Day: every day at 12:00 → action "Open App" → the collector → "Run Immediately".
Charger: when connected → open the collector → "Run Immediately".
Opening the app triggers a sync. Automations can only be created on the phone, not from the Mac.
Usage
Connect an AI assistant (MCP)
Claude Code: .mcp.json at the repo root already registers health-hub. Start claude in the repo; the first time it asks whether to enable this project MCP server — approve it.
Codex: add to ~/.codex/config.toml (use your absolute path):
[mcp_servers.health-hub]
command = "python3"
args = ["/absolute/path/health-hub/src/health_hub_mcp/server.py"]Then ask: "health-hub weight for the last 7 days", "weekly report", "how is sync doing?"
Tool | What it does |
| query samples by type and time range |
| one-week summary (weight, steps, sleep, heart rate…) |
| last sync time and row counts per type |
| log a workout / meal by hand |
| for developing the app: check the environment, build, install, read logs (output redacted) |
| search the bundled Apple HealthKit documentation |
Without an AI assistant, from the command line:
python3 src/health_hub_mcp/server.py sync-status # sync status
python3 src/health_hub_mcp/server.py env-check # iOS development environment check
python3 src/health_hub_mcp/server.py kb-search "background delivery"Variable | Purpose | Default |
| data directory |
|
| access token (wins over | — |
| bundle ID used by |
|
| device name used by | — (put it in the git-ignored |
Agent skill: ios-dev-env
The repo ships a Claude Code skill at .claude/skills/ios-dev-env/SKILL.md. It teaches the assistant to check the iOS toolchain, generate the project, build, install, read logs and debug signing, and it keeps secrets (Team ID, certificates, device IDs) out of chat and git.
In this project only: nothing to install. Claude Code loads project skills from
.claude/skills/when started in the repo. Say "build the collector", "install on my phone", "signing error", or type/ios-dev-env.In every project: copy it into your personal skills directory:
mkdir -p ~/.claude/skills && cp -R .claude/skills/ios-dev-env ~/.claude/skills/Codex: ask Codex to read
.claude/skills/ios-dev-env/SKILL.mdand follow it; if your Codex version supports skills, you can copy the folder into its skills directory (see the Codex docs).Before first use: keep your own values out of git — device name in
local.env, bundle ID inios/local.xcconfig, and anything else about your machine in a git-ignored.claude/skills/ios-dev-env/local.md, which the skill reads first.
Documentation
Document | What is in it |
What the Health app can give you: the 11 types collected today with meaning and unit, every database column, sleep states, common metadata keys, and HealthKit types that could be added later | |
How the phone talks to the Mac: request and response fields, examples, timestamps, deduplication, transport, auth | |
Step-by-step install for Claude Code / Codex, with a check after every step | |
Every file and folder, and where new things go | |
What changed in each version |
Project layout
Path | Purpose |
| Swift package: sync engine, queue, encoding — all testable logic |
| thin iPhone app shell (HealthKit access, UI, background delivery) |
| Mac receiver: FastAPI app, token tool, |
| MCP server, also usable from the command line |
| bundled Apple documentation for the MCP knowledge-base tools |
| protocol, field reference, plans, device test records, agent install guide |
| pytest suites and fixtures |
| your database and token — git-ignored, never leaves the Mac |
Every file and folder: STRUCTURE.md.
For developers
uv run pytest # Python: unit / integration / contract / e2e
swift test --package-path ios/CollectorCore # Swift collector coreChanges per version: CHANGELOG.md · How to contribute: CONTRIBUTING.md · Reporting security problems: SECURITY.md.
Privacy
data/(database, token),ios/local.xcconfig,ios/HealthCollector/LocalConfig.plistand the generated.xcodeprojare all git-ignored.tests/_privacy.pychecks that identifiers such as Team IDs, device UDIDs, Tailscale IPs and certificate fingerprints never enter the repo.
License
MIT. The optional reference material described in kb/README.md is not included and keeps its own terms.
This server cannot be deployed
Maintenance
Related MCP Connectors
- SomviaOAuthapp.somvia
Apple Health training load, recovery, HRV and workout detail for Claude, ChatGPT and any MCP client.
Log meals, water, and weight to Garmin Connect from Claude or ChatGPT.
Garmin data in Claude & ChatGPT via the Garmin Health API. OAuth sign-in, no password sharing.
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.