Your AI agent reads your Apple Health data: sleep, HRV, cycle, workouts. Decrypted on your machine
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
We haven't yet run this listing's install command through our automated sandbox check. This isn't a red flag β we're steadily working through the catalog.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Inspect callable tools, capabilities, and parameters exposed to AI agents by Vaultbeat Apple Health.
vaultbeat_statuslocal binding state (no keys/tokens in the result)
vaultbeat_start_bindinggenerate a fresh QR binding payload
vaultbeat_poll_bindingpoll once for the iOS authorization
vaultbeat_doctordiagnose this install end to end, and report which data types
vaultbeat_sync_sleeprecent sleep records (incl. heart-rate samples) with per-day
get_sleep_detailper-night HR+RR+stage timeline with stage intervals
Your Apple Health data β sleep stages, cycle, HRV, resting heart rate, workouts, weight, VOβ max, meals, lifts, notes β readable and writable by your own AI agent (Claude Code, Hermes, OpenClaw, anything MCP), end-to-end encrypted so that only your machine ever sees plaintext. The Vaultbeat iPhone app captures from HealthKit; this package is the local server that decrypts for the agent.
Technically: the local service program for Vaultbeat's encrypted health-data recipient flow.
Published externally as Fino-wind/vaultbeat-apple-health
(public package name vaultbeat-apple-health since 0.6.2; vaultbeat-mcp and
vaultbeat-mcp-local remain back-compat console scripts). This directory is the source of truth β after any user-visible change here,
re-export the public repo and update its README tool table + the website /mcp page
(see CLAUDE.md "Sync duty").
It runs on the user's computer, generates the Curve25519 keypair used by the iOS app, shows a QR binding payload, receives a one-time server token from the cloud API, and then exposes decrypted health data β sleep, water, weight, cycle, activity, vitals β through either a CLI or a stdio MCP server. Read-only: data is written by the iOS app.
--demo is a global flag, not a subcommand: it goes before the subcommand
(vaultbeat-apple-health --demo sleep), and VAULTBEAT_DEMO=1 does the same thing. It serves a
deterministic synthetic dataset β the same records on every machine, every run β so demo
output can be pasted into a bug report as a shared baseline. Nothing is fetched and nothing
is decrypted; there is no private key involved at all. Every payload carries demo_mode: true plus a [SYNTHETIC DEMO DATA] banner, the tool descriptions say so, and the server
lists itself as Vaultbeat Health [DEMO β SYNTHETIC DATA], so demo output cannot pass for a
real export. Read tools only β the log_* write tools refuse, because writing needs a
real key and a real account, and a write that pretends to succeed is worse than one that says
it needs pairing. It applies to that one invocation and is never written to the config file.
http is a CLI alias for MCP's streamable-http transport.
The default transport remains stdio for local desktop MCP clients.
The config file defaults to ~/.tether/mcp-local/config.json and is written with
0600 permissions. It contains the cloud-issued server token and your public
key; do not commit or share it.
Not in config.json. It is looked for in three places, in order:
VAULTBEAT_PRIVATE_KEY β read if set, never written back, for operators
who inject it from systemd-creds / a vault / a KMS.~/.tether/mcp-local/identity.key, mode 0600 β the automatic fallback
on a machine with no keyring backend at all.Keeping it out of config.json is a boundary, not tidiness: the server token
alone can download your ciphertext but not read it, and the private key alone
has nothing to decrypt. config.json is the file people cat into bug reports.
π΄ Never delete
config.jsonto "start clean". The private key is not in it, so deleting does not clear a bad key β it mints a brand-new identity, and every record already encrypted for the old one becomes permanently unreadable. If a command reports missing key material, the error names all three locations and what was found in each; read that before removing anything.
Headless servers: if the keyring is unreachable, do not set
PYTHON_KEYRING_BACKEND to the null backend. That backend accepts writes and
stores nothing; since 0.4.3 every keyring write is verified by reading it back,
so a null backend just lands the key in layer 3's identity.key file β the same
outcome as having no keyring, with a keyring you might have reached hidden behind
it. Either let layer 3 handle it (automatic when no backend exists) or, if a
D-Bus session exists but this process cannot see it, pass
DBUS_SESSION_BUS_ADDRESS through explicitly β XDG_RUNTIME_DIR on its own is
not enough.
.tether, not.vaultbeatβ that is deliberate, do not "fix" it. The app was renamed but this path is frozen at the pre-rename location, because the Keychain username embeds the resolved config path (_keychain_usernameinstore.py). Moving the directory orphans the bound config and its private-key Keychain entry for every existing install. Until 2026-07-28 this README wrote~/.vaultbeat/..., which does not exist β so anyone who came here to destroy their credentialsrm -rf'd an empty path, got no error, and left the real key in place.
When using HTTP transport, the server binds to 127.0.0.1:8000 and serves MCP at
/mcp by default, and requires a bearer token (see "Authenticating HTTP transport"
below). Binding a non-loopback address fails closed unless you pass both a token and
--allow-remote; always front a network-exposed server with TLS (a reverse proxy).
vaultbeat-apple-health bind generates a fresh pollID and prints a QR payload:
{"pollID":"...","publicKeyBase64":"...","serverName":"..."}mcp-bind-local Edge Function.mcp-poll-binding Edge Function.serverID and serverToken.mcp-sync Edge Function, decrypt the returned envelopes
locally, and return plaintext JSON. (All privileged routes are Supabase Edge
Functions at /functions/v1/<name>.)vaultbeat-apple-health doctorIf binding or reads fail, run the self-diagnosis:
It checks, in order: config file β identity key (Keychain) β cloud reachability β binding state β a real fetch-and-decrypt round trip, and prints a targeted hint for the first thing that's broken (e.g. "codes expire after 10 minutes β re-run bind for a fresh QR", or "the stored key can no longer decrypt your data β delete this server in the iOS app and bind again"). Exit code 0 = all healthy, 1 = something needs the hint above.
vaultbeat-apple-health serve can start either a stdio MCP server or a streamable HTTP MCP
server. Every data tool accepts owner (user-ID prefix) to filter to one person and
fresh to bypass the local cache β omit owner and both partners' records mix into
one pool, so per-person analysis must always pass it. The tool names dropped the old
misleading get_partner_* prefix in the 16-tool release (2026-07-16): the tools
return whichever owners' envelopes this server holds, not specifically "the partner".
Binding / status:
vaultbeat_status β local binding state (no keys/tokens in the result)vaultbeat_start_binding β generate a fresh QR binding payloadvaultbeat_poll_binding β poll once for the iOS authorizationvaultbeat_doctor β diagnose this install end to end, and report which data types
are unavailable and why. Call it before telling a user their data is missing.Health data:
Factual signals from GitHub, npm, and our automated checks β not a rating.
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/vaultbeat-apple-health)<a href="https://allmcps.com/mcp/vaultbeat-apple-health"><img src="https://allmcps.com/api/badge/vaultbeat-apple-health?style=directory" alt="Vaultbeat Apple Health on AllMCPs" /></a>