healthmirror-mcp

HealthMirror MCP

English · 简体中文

A local MCP server that exposes your own Apple Health data — exported to iCloud Drive by the HealthMirror iOS app — to AI tools running on your Mac (e.g. Claude).

It reads the JSONL files HealthMirror writes into its iCloud container and answers structured queries (sleep, heart-rate metrics, workouts, a daily recovery summary). Your health data never leaves your machine: the server runs locally, has no network access, and only returns query results to the MCP client you connect.

How it works

iPhone HealthKit
  ↓  HealthMirror iOS app   (reads HealthKit, writes JSONL)
iCloud Drive container:  iCloud.com.mlyz.HealthBridge
  ↓  macOS iCloud auto-sync
~/Library/Mobile Documents/iCloud~com~mlyz~HealthBridge/Documents/
  ↓  this MCP server        (reads JSONL, runs queries)
Claude / any MCP client

The server is read-only over your data and makes no outbound network requests (enforced by a sandbox profile — see Security model).

Requirements

Install

git clone https://github.com/mlyxz/healthmirror-mcp.git
cd healthmirror-mcp
uv sync

Confirm your health data has actually synced to this Mac — this folder should exist and contain per-metric subfolders:

ls ~/Library/Mobile\ Documents/iCloud~com~mlyz~HealthBridge/Documents/raw/

If it’s missing or empty, open the HealthMirror app on your iPhone, let it finish syncing, and make sure iCloud Drive is enabled on this Mac.

Smoke test (no sandbox)

Confirm dependencies resolve and the server starts:

uv run health-bridge-mcp

It speaks the MCP protocol over stdio and waits for a client, so you’ll see no visible output. If it starts without an import error, you’re good — press Ctrl+C to exit.

The repo ships run-sandboxed.sh, which launches the server inside a macOS sandbox-exec profile that denies all network access and restricts writes to a small allow-list. This is the recommended way to run it.

claude mcp add healthmirror /ABSOLUTE/PATH/TO/healthmirror-mcp/run-sandboxed.sh

Replace /ABSOLUTE/PATH/TO/healthmirror-mcp with the real path where you cloned the repo. The wrapper resolves your home directory and the repo location automatically, so you never have to edit absolute paths inside sandbox.sb.

To run without the sandbox (e.g. while debugging), register the plain command:

claude mcp add healthmirror -- uv run --directory /ABSOLUTE/PATH/TO/healthmirror-mcp health-bridge-mcp

Other MCP clients: launch run-sandboxed.sh as the server command; it communicates over stdio.

uv: command not found? GUI-launched MCP clients sometimes don’t inherit your shell PATH. run-sandboxed.sh tries common install locations automatically; if it still fails, run which uv and use that full path. For Claude Desktop, point its MCP config JSON at "command": "/ABSOLUTE/PATH/TO/healthmirror-mcp/run-sandboxed.sh".

Tools

Tool What it does
ping Liveness / connection check.
get_sleep Sleep episodes (main sleep + naps), per-stage minutes, coverage.
get_metric A quantity metric (heart_rate, hrv_sdnn, resting_heart_rate, active_energy, steps, weight) with aggregation, optional per-day buckets, and per-source breakdown.
get_workouts Workout records with multi-source dedup, plus a per-type summary.
get_daily_summary One-shot daily summary: recovery score, cycle phase, today’s activity, last night’s sleep.

By default queries are limited to the last 30 days; pass allow_historical=true for older data. Every tool call is appended as a line to ~/Library/Application Support/HealthBridge/audit.log, so you can see what the AI queried (tail -f it). See Security model for exactly what that log records.

Security model

sandbox-exec is marked deprecated by Apple but remains functional on current macOS.

Why two names?

The product and this repository are named HealthMirror. The Python package and module keep the original development codename health_bridge (distribution health-bridge-mcp, import health_bridge_mcp), and the iCloud container ID is iCloud.com.mlyz.HealthBridge. These identifiers were frozen early to avoid disrupting a working data pipeline, so they intentionally differ from the product name. Functionally it’s all the same project.

Maintainer

Developed by Xiao Zhang, publishing as @mlyxz on GitHub. Contact: support@mlyz.me

License

MIT