Vaultbeat MCP Server
Apple Health MCP Server — live sleep, cycle, weight & more for your AI agent
Vaultbeat's local MCP server gives Claude Code, Claude Desktop, and any MCP-capable agent read access to your — and your partner's — Apple Health data, plus the ability to log meals, lifts, weight, notes and symptoms back into your own account. Everything is end-to-end encrypted and synced continuously in the background: the cloud only ever holds ciphertext, decryption happens on your machine, and there are no manual exports.
Requires the Vaultbeat — Health MCP for AI iOS app, and Python 3.11+ on the machine where your agent runs. The server is open source on GitHub.
Connect Apple Health to Claude Code
Get the app
Install Vaultbeat — Health MCP for AI on your iPhone and sign in. The app starts syncing your Apple Health data end-to-end encrypted in the background.
Install & bind
On the computer where your agent runs, verify the server with uvx (no clone, no venv), then start pairing:
uvx vaultbeat-apple-health@latest status
uvx vaultbeat-apple-health@latest bind
bind is the command that shows the QR code — serve (below) prints nothing at all, so don't wait on it for one.
bind generates a Curve25519 keypair on your machine and prints a QR code. In the Vaultbeat iOS app, open MCP tab → Connect an AI server (app 1.2.8 and earlier: Settings → Data & AI) and scan it. From that moment your iPhone seals an encrypted copy of each record for this machine. The private key never leaves that machine: it lives in your system keyring, or in a 0600 file beside the config on a headless box, and is never uploaded anywhere.
Add it to Claude Code
claude mcp add vaultbeat-health -- uvx vaultbeat-apple-health@latest serve --transport stdio
Done. Ask Claude: “How did we sleep last night?” Reads are cache-first on your own machine (10-minute TTL by default), so repeat queries answer in about 0.2 seconds.
Claude Desktop — and any other agent framework
After binding (steps 1–2 above), add this to your claude_desktop_config.json:
{
"mcpServers": {
"vaultbeat-health": {
"command": "uvx",
"args": ["vaultbeat-apple-health@latest", "serve", "--transport", "stdio"]
}
}
}Using Hermes, OpenClaw, or your own harness? Use the same split as above: command is just the executable (uvx, or its absolute path if the framework does not inherit your shell PATH), and everything else goes in args as a list. Putting the full command line into command is the most common way this fails: the server starts, prints its help, and exits — which the host reports as Connection closed, as though the server were broken.
Works with any MCP client
The server speaks standard MCP over two transports. For clients that spawn a subprocess, use stdio:
uvx vaultbeat-apple-health@latest serve --transport stdio
For clients that connect over HTTP, a streamable-HTTP endpoint is available:
uvx vaultbeat-apple-health@latest serve --transport http
HTTP binds to loopback only by default and requires a bearer token; binding a non-loopback address fails closed unless explicitly allowed. Hermes, OpenClaw, and any other MCP-capable agent connect the same way.
What your agent can do
The server currently exposes 29 tools — 17 that read and 12 that write. Every read returns your own data unless your agent asks for your partner's — and then only what they chose to share. Sensitive categories reach the server only if the data owner explicitly opts in from the iOS app — they are off by default and never re-exported.
Read
| Tool | Returns |
|---|---|
| vaultbeat_doctor | Self-diagnosis of this install: pairing state, which data types are unavailable and why |
| get_sleep_nights | Every night as one compact row — bed and wake time, stages, awakenings, heart and breathing rate while asleep, naps. A year in one call (server 0.9.0+) |
| get_sleep_detail | One or two nights in depth: stage bands and per-stage heart and breathing rate — the newest nights, or any night by date (server 0.9.1+) |
| get_menstrual_cycleopt-in only | Cycle samples plus a next-period prediction |
| get_symptoms | Symptom days from Apple Health (only once you turn that on), and beside them the episodes you reported yourself — type, severity, onset and end, place, suspected triggers |
| get_state_of_mindopt-in only | Moods — Apple Health's State of Mind, from Apple Watch, the Health app or other apps, plus the ones your AI recorded: how pleasant each felt, the feeling words and life areas, and a per-day count and average — the 100 newest, or a date range for older ones (server 0.9.3+, app 1.3.0+ for the Apple Health half) |
| get_notes | Free-text day annotations with their writer |
| get_workouts | Workout records: type, duration, calories, distance |
| get_user_profileopt-in only | Biological sex, age and height — for anything that depends on them (BMR, heart-rate zones, VO₂ max bands). Owner only, never shared with a partner. Needs Vaultbeat for iOS 1.2.9 or later |
| get_metric | Any one-number-per-day series — steps, activity, resting HR, HRV, weight, water, wrist temperature, VO₂ max, basal energy, TDEE, mindfulness, sleep duration, timing, stages and awakenings. One, several or all at once; avg / sum / min / max / latest and weekly, monthly or day-of-week buckets computed server-side (server 0.9.0+) |
| get_intraday | Samples within a day for HRV — hourly buckets or raw per-sample (server 0.9.0+) |
| get_strength_log | Strength-training sessions — exercises, sets, reps and weight per day |
| get_food_log | Daily food logs as plain text, with optional portions and timing — the 14 newest days that have a log, or a date range (server 0.9.0+) |
| list_metric_series | Every series name get_metric and the analysis tools accept, with its unit and how much data backs it (server 0.7.0+) |
| get_metric_trend | Least-squares trend for one daily series — slope per day, endpoints, spread. Numbers only, no verdict (server 0.7.0+) |
| compare_metric_periods | Two periods of a series side by side — the newest N days against the N before, or two named date ranges such as a semester and a summer (server 0.7.0+; date ranges 0.9.0+) |
| correlate_metric_series | Pearson r between two series over days that have both recorded, with the pair count and a causation caveat; can pair a day with a later one (server 0.7.0+; lag 0.9.0+) |
Every read tool also returns a coverageblock — how many distinct days the answer actually rests on, the span they fall across, and how many days inside that span are missing. It is there so an agent can say “this is based on 3 days” rather than presenting a three-day average and a thirty-day one in the same words: they are the same shape and the same number of digits, and nothing else in the result tells them apart.
Write
Your agent can log six kinds of record for you — food, strength training, weight, free-text notes, the symptoms you report and how you feel — useful when you would rather say “I did 5×5 squats at 80kg” than open the app and tap it in. Three of those kinds come as a pair, and the names say which is which: a log_ tool replaces a whole day, while its _appendtwin only adds and cannot delete — so an agent that cannot see what you have already recorded has a safe option. Writes are encrypted on your machine before upload, exactly like the ones your iPhone makes, so our cloud still only ever receives ciphertext. None of these tools takes an owner argument: an agent can write to your own account and nowhere else, never your partner's. Sleep, cycle, and the symptom days and moods Apple Health records stay read-only.
| Tool | Writes |
|---|---|
| log_weight_entry | Record a weigh-in. Can also sync into Apple Health — only if you enable "Allow AI to update Apple Health" in the MCP tab (app 1.2.8 and earlier: Settings → Data & AI), off by default |
| log_food_entry | Record a day's meals as plain text, with optional portions and timing. Replaces the whole day — use log_food_append to add to a day that already has entries |
| log_food_append | Add meals to a day already logged, leaving everything else that day untouched. Cannot delete anything — prefer this when the day may not be empty |
| log_strength_entry | Record a strength session — exercises, sets, reps, weight. Replaces the whole day — use log_strength_append to add to a day that already has entries |
| log_strength_append | Add exercises to a day already logged, leaving everything else that day untouched. Cannot delete anything — prefer this when the day may not be empty |
| log_note | Record a free-text note for a day, so narrative context sits beside the metrics. Replaces that day's note. Sleep and cycle notes stay iOS-authored and are refused; from server 0.9.3 a feeling goes to log_state_of_mind instead |
| log_note_append | Add a line to a day's note, leaving the existing text untouched. Cannot delete anything |
| log_symptom | Record one symptom you report — type, your own words, severity, when it started and ended, where, what you suspect set it off — as fields a later read can line up with sleep, food and heart rate (server 0.9.0+) |
| update_symptom | Change a reported symptom, usually its end time once it eased. Only the fields passed change, and the old values come back (server 0.9.0+) |
| delete_symptom | Erase a symptom logged by mistake; the deleted entry comes back so it can be re-logged (server 0.9.0+) |
| log_state_of_mind | Record how you say you feel, in Apple Health's own terms — how pleasant, the feeling words, what it was about. Shows in the app's mood calendar; reaches Apple Health only with "Allow AI to update Apple Health" on, off by default (server 0.9.3+, app 1.3.0+) |
| delete_state_of_mind | Erase a mood your AI recorded by mistake; your iPhone also removes the copy it wrote into Apple Health (server 0.9.3+) |
Only log_weight_entry and log_state_of_mind can reach Apple Health, and only when you enable MCP tab → “Allow AI to update Apple Health” (app 1.2.8 and earlier: Settings → Data & AI) — off by default. The full detail is in the Privacy Policy. The authoritative tool list lives in the GitHub README.
And 8 prompts, so it does not have to guess how
Tools are what your agent can call. prompts/list is how it asks what the server is for — and every MCP client can read it. Without one, each agent invents its own routine, and the two mistakes that do real damage with health data get left to whichever agent happened to connect: calling an association a cause, and reading a gap as a zero. Each entry below names the tools to call for it and carries the same two rules — say what the data covers before concluding anything, describe rather than prescribe, invent no scores or grades; and where a read can come back empty, never treat that emptiness as a measurement of zero.
| Prompt | What it asks for |
|---|---|
| daily_brief | The most recent day, set against the fortnight behind it — and it names the newest date it can actually see before drawing anything from it |
| sleep_reviewnights (optional) | Duration and stages across recent nights. Nights where the watch logged time in bed without ever measuring sleep stay their own category instead of averaging in as zero-minute nights that never happened |
| energy_balancedays (optional) | Calories in against calories out, with the days missing hours of basal data excluded rather than quietly dragging the average down |
| training_block_reviewdays (optional) | Lifting and cardio volume beside the recovery signals from the same weeks — offered as context, never as a verdict on the block |
| cycle_aware_readmetric (optional) | A metric read against the same phase of earlier cycles instead of against last week, which mixes phases and manufactures a trend out of an ordinary rhythm |
| partner_check_indays (optional) | Both of you side by side, read once per person rather than averaged across two bodies — and described rather than assessed, because sharing is a kindness and not a monitoring feature |
| log_from_conversationentry (optional) | Turns something you said in passing into an entry, and asks you for a weight, rep count or portion it was not told rather than reaching for a plausible one |
| why_is_this_emptycontext (optional) | Works out which of the four causes is behind an empty or stale read, then gives the single next step for that one instead of a checklist of all four |
Every argument is optional. Omit one and it is filled with a default written into the prompt itself, so asking for a prompt with no arguments is a supported call rather than a degraded one.
Why not just export my Apple Health XML?
Most Apple Health MCP servers work on a manual export: you generate an XML or CSV dump, import it, and query a snapshot that is stale the moment it lands. Vaultbeat takes a different approach — the iOS app syncs continuously in the background, so your agent always reads current data.
| Export-based MCP servers | Vaultbeat | |
|---|---|---|
| Freshness | Manual XML/CSV export — a stale snapshot from the moment it lands | Continuous background sync — always current |
| Workflow | Re-export and re-import every time you want new data | Bind once with a QR scan; your agent just asks |
| People | Single user only | Couples — your partner's data too, with their explicit per-category consent |
| Security | Plaintext export files sitting on disk | E2EE — the cloud holds ciphertext only; keys never leave your devices |
How the end-to-end encryption works
Every health record is encrypted on your iPhone before it leaves the device: the record is sealed with AES-GCM, and its key is wrapped for each authorized recipient using Curve25519 ECDH with HKDF-SHA256 — one envelope for you, one for your partner if sharing is on, one for each machine you pair. The cloud stores and routes ciphertext only; we hold no decryption keys and cannot read your health data — architecturally, not just by policy. When you bind a machine, it generates its own Curve25519 keypair. The private key never leaves that machine: it lives in your system keyring, or in an owner-only file beside the config when the machine has no keyring at all, and is never uploaded anywhere. Decryption happens in exactly the places you chose: your own devices, an opted-in partner's device, and the machine your agent runs on. The decryption code is open source — audit it.
Frequently asked questions
My agent suddenly cannot read my health data — what should I check?
Check https://vaultbeat.app/status first. It shows whether the sync endpoint your agent reads through is reachable right now. If a service is degraded, waiting is the fix — do not re-pair, since that means setting your AI connection up again for nothing. If everything there is green, run `uvx vaultbeat-apple-health@latest doctor`, which walks the whole chain locally: config present, keypair usable, binding valid, cloud reachable, and a real record decrypted end to end.
How is this different from exporting my Apple Health data?
An export is a snapshot: you hand your agent a file, and it is stale from the moment it lands — asking a fresh question next week means repeating the export, the unzip and the file path. Vaultbeat syncs continuously from HealthKit, so your agent reads last night’s sleep without you doing anything. The reason most Apple Health MCP servers work from exports is structural rather than a shortcut: HealthKit is only reachable through an iOS app holding the user’s permission, so a server that installs from npm or PyPI alone has no way to read it directly. Vaultbeat ships that iOS half — and the cloud in between only ever holds ciphertext, because the decryption key never leaves your machine.
Do I need a computer, or does this work from my phone alone?
You need a computer — the same one your AI agent runs on. The MCP server runs locally there, which is exactly what keeps the decryption key off our servers: run `uvx vaultbeat-apple-health@latest bind` on that machine and scan the QR code it prints with the iPhone app to pair them. Your phone records and syncs on its own, but an AI reading that data always happens on hardware you control.
Do I need an Apple Watch?
No. Without a Watch, Vaultbeat uses Apple’s on-device Motion & Fitness inference on your iPhone to record sleep sessions, and your agent reads them the same way. An Apple Watch adds stage-level detail (core, deep, REM) and heart-rate samples during sleep — when both sources exist, Vaultbeat automatically prefers the Watch record.
Can my agent read my partner’s data?
Yes — with their explicit consent, granted per category from their own phone. Vaultbeat is a health app on the App Store designed to be read by your own AI agent, and that extends to partner data: ask Claude Code, Hermes, or OpenClaw how your partner slept, and it answers from the records they chose to share. Sensitive categories are off by default and revocable at any time.
Which plan do I need?
None to start, in Vaultbeat 1.2.3 and later: connecting an AI server is open on every plan, and once your machine is paired you get three free days of the agent interface. (On 1.2.2 and earlier, connecting still requires Pro — update the app first.) After that, continued agent access is Vaultbeat Pro: $9.99/month, $29.99/year, or $74.99 lifetime, which also unlocks full history and trend charts in the app. From app 1.2.9 the cloud is part of a membership: with Pro or a live trial (yours or your partner’s) your whole history is uploaded, and a free account uploads nothing (on app 1.2.8 and earlier, Free and the trial upload the last 7 days).
Is my data used to train AI?
No — and not just as a policy promise: it is impossible by design. The cloud stores ciphertext only, and Vaultbeat holds no decryption keys, so there is nothing readable to train on. Your data is decrypted in exactly three user-chosen places: your own devices, an opted-in partner’s device, and the machine you explicitly paired.
Not here for the agent? Vaultbeat also lets you share sleep data with your partner — either of you with a membership is enough for that. Questions? Email support@vaultbeat.app or open an issue on GitHub.