healthkite-mcp is a small Rust stdio MCP server that exposes the HealthKite MCP iOS LAN server as agent tools. It contains zero server state: it derives discovery/auth material from your pairing secret, discovers the phone with Bonjour/mDNS, opens a TLS-PSK connection, then proxies each tool call to the iPhone.
[ Claude Code / Codex / Cursor / Zed / Continue / ... ]
                │  stdio JSON-RPC (Model Context Protocol)

        healthkite-mcp (Rust, MIT)
                │  Bonjour discovery + TLS-PSK

       HealthKite MCP iOS app on your LAN

Install

cargo install --git https://github.com/alpinevm/healthkite-mcp healthkite-mcp
From a local checkout of the public repo:
cargo install --path mcp --force
healthkite-mcp requires Rust/Cargo and OpenSSL development libraries available to Cargo.

Configure

The canonical agent-config block works across Claude Code, Codex, Cursor, Continue, Zed, and other MCP-aware harnesses:
{
  "mcpServers": {
    "healthkite-mcp": {
      "command": "healthkite-mcp",
      "env": {
        "HEALTHKITE_TOKEN": "<pairing secret from HealthKite MCP Settings>"
      }
    }
  }
}
  • HEALTHKITE_TOKEN / HEALTHKITE_ROOT — the pairing secret shown in HealthKite MCP Settings. It is used locally as the HKDF root for both the Bonjour instance label and the TLS-PSK key.
  • HEALTHKITE_SERVICE_TYPE — optional DNS-SD service type override; default _healthkite-mcp._tcp.local..
  • HEALTHKITE_DISCOVERY_TIMEOUT_MS — optional mDNS browse timeout; default 3000.
The iOS app must be foregrounded with the LAN server toggled on for discovery and tool calls to succeed. No IP address or per-connection URL is copied; the MCP discovers the phone by Bonjour.

Tools

ToolInputOutput
statusnone{ name, version, workoutCount, sampleEncoding }
list_workoutslimit? (1-200, default 50), offset? (default 0)Paginated workout summaries, newest first
get_workoutuuid (string, required)Full WorkoutDetail JSON (columnar-v1)
list_quantity_typesnoneCatalog of standalone HealthKit quantity types with sample counts
get_quantity_seriestype (string, required), from?, to?, limit? (1-50000, default 5000), offset? (default 0)Columnar quantity series for a date range
list_sleep_sessionsfrom?, to?, limit? (1-365, default 30), offset? (default 0)Reconciled nightly sessions with phase intervals
get_day_snapshotdate (YYYY-MM-DD, required)Single-day overview matching the iOS Day view numbers exactly
Each tool returns the response body verbatim — bytes identical to what the LAN server emits. The MCP does no caching, no transformation, no schema translation.

Errors

The MCP surfaces meaningful tool errors so agents can recover gracefully:
ErrorCauseSuggested agent action
UnauthorizedPairing secret is missing or wrong; TLS/auth cannot reach the appAsk the user to re-copy the pairing secret from Settings
NotFoundUUID or path doesn’t existSurface verbatim
UnreachableiOS app is closed/backgrounded, server toggle off, discovery failed, or peers are not on the same LANAsk the user to open HealthKite MCP and confirm both devices are on the same Wi-Fi
ServerErrorInternal 5xxSurface; usually transient
BadDateDate param malformed (snapshot only)Re-format and retry

What the MCP is not

  • Not a backend. It’s a stateless proxy; the iPhone is the source of truth.
  • Not a writeback layer. Read-only tools. No create_workout, update_*, or delete_*.
  • Not a cache. Every call hits the LAN server. Latency is dominated by the LAN round-trip and the HealthKit query — typically 50-500 ms for get_workout, single-digit ms for status.
  • Not exclusive to Claude. Any MCP-compliant client works.

Source

github.com/alpinevm/healthkite-mcp. MIT-licensed. Issues and PRs welcome.