Mibly – Apple Health MCP
Open-source Apple Health MCP server. Bring your sleep, heart rate, HRV and workout data from iPhone into Claude, Codex or any MCP agent. Local mode, encrypted, no cloud.
Documentation
Apple Health MCP — Mibly Receiver
An open-source Apple Health MCP server: bring your Apple Health (HealthKit) data — sleep, steps, heart rate, HRV, workouts, weight, body fat, and more — into Claude Desktop/Code, Codex, or any other AI agent you build or run yourself (anything that speaks MCP).
Local mode: your data never touches Mibly's servers. No account, no cloud, no telemetry. It is stored encrypted on a machine you control, and this repository is the code that does it.
Quickest way to get started
- Download Mibly on your iPhone → App Store
- Copy the setup prompt from inside the Mibly app (Connection Settings → "Copy for your Agent") and paste it into your agent.
Your agent sets up the receiver and MCP service for you. No cloning, no building, no config files.
Why an iPhone app?
Apple Health data can only be read through HealthKit, inside a native iOS app. There is no web API. Mibly handles the HealthKit side — permissions, background sync, and data formatting — so you don't need an Apple Developer account or Xcode.
What this repository is
A reference implementation of the receiver your agent installs. It's here so you can:
- Review exactly what runs on your machine and where your data goes
- Customize it if you want to
You don't need this code to use Mibly. The setup prompt above is the recommended path.
Where does the data go?
| Question | Answer |
|---|---|
| Where is health data stored? | ~/.mibly/data.enc only. AES-256-GCM, key = scrypt(pairing token, random salt). |
| Does the service make outbound network requests? | No. It only listens. No telemetry, no update check. |
| Who can read it over the network? | Anyone holding the pairing token. Every route requires Authorization: Bearer <token>. |
| How long is it kept? | 365 days of history. Only the latest sample per type is kept longer. |
| Is traffic encrypted in transit? | No. Local mode is designed for your home or office LAN: the iPhone and this receiver sit on the same Wi-Fi and talk plain HTTP. Don't expose the port to the public internet. |
Check it yourself. This should print nothing:
grep -rnE "fetch\(|https?\.request|axios|net\.connect|XMLHttpRequest" src
The wire protocol (endpoints, payloads, storage format) is in PROTOCOL.md; the threat model is in SECURITY.md.
Run it yourself
Requires Node.js 18+.
npm ci
npm run build
MIBLY_TOKEN=<token from the Mibly app> npm start
On first run the token is saved to ~/.mibly/config.json (mode 0600), so later restarts need no env var. On startup the receiver prints the address(es) to use, e.g. Target Host to enter in Mibly: 192.168.1.24:7345 (en0). Enter that in the app's Target Host field (just IP:port, no http://, no path); pick the address on your Wi-Fi/LAN if several are listed.
| Variable | Meaning | Default |
|---|---|---|
MIBLY_TOKEN | Pairing token from the app | saved config |
MIBLY_HOST | Bind address host:port | 0.0.0.0:7345 |
Connect an MCP client over HTTP to http://<ip>:7345/mcp with the header Authorization: Bearer <token>. For agents that spawn MCP servers over stdio, add --stdio (logs go to stderr).
If you regenerate the token in the app, restart with the new MIBLY_TOKEN. The old encrypted store can't be decrypted with the new key, so the receiver starts empty.
Code map: src/index.ts (routes) · src/auth.ts (token check) · src/config.ts (~/.mibly/config.json) · src/ingest.ts (validation) · src/store.ts (encryption, retention, queries) · src/mcp.ts (the two tools). Run the tests with npm test.
Start automatically on boot
The receiver should keep running after a restart. Replace the paths (and, on Linux, the user) with yours; the token is already saved in ~/.mibly/config.json, so no env var is needed.
macOS (launchd) — ~/Library/LaunchAgents/com.mibly.receiver.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>Label</key><string>com.mibly.receiver</string>
<key>ProgramArguments</key><array>
<string>/usr/local/bin/node</string>
<string>/Users/you/mibly-apple-health-mcp/dist/index.js</string>
</array>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
</dict></plist>
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.mibly.receiver.plist
Linux (systemd) — /etc/systemd/system/mibly-receiver.service:
[Unit]
Description=Mibly receiver
After=network-online.target
Wants=network-online.target
[Service]
User=you
ExecStart=/usr/bin/node /home/you/mibly-apple-health-mcp/dist/index.js
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl enable --now mibly-receiver
Restart the machine, then confirm the receiver is back (use the IP the receiver printed):
curl -H "Authorization: Bearer <token>" http://<ip>:7345/status
A JSON reply with version and lastPushAt means it is running.
Upgrading from an earlier version
Update in place; do not set up a second receiver.
- Pull the new code, then
npm ci && npm run build, and restart the service. - Keep your token and data. Do not delete
~/.miblyand do not change the token. A new token starts an empty store. - Legacy
heartRaterecords (single readings withoutheartRateSummary) are deleted on start-up, becauseheartRateis now an hourly summary. Everything else is kept. - Check
GET /status: it should show the newversionandcapabilities.
Newer Mibly app features need the matching receiver version; older apps keep working with a newer receiver.
Local vs Cloud
| Local (Free) | Cloud (Pro) | |
|---|---|---|
| Data path | iPhone → an agent environment you control | iPhone → Mibly Cloud → your agents |
| Remote access across devices | — | ✓ |
| Multiple agents on the same data | — | ✓ |
| Menstrual cycle data | Available (off by default) | Never uploaded |
This repository covers Local only. You choose which data types are shared and can turn each one off at any time.
Notes
- Mibly does not diagnose or make medical decisions. It only gives your agent access to the data you choose to share.
- Issues in this repo are for the receiver code. For app support, see mibly.app.
- Privacy policy: https://mibly.app/privacy/
License
MIT