Pairing-secret auth

HealthKite MCP no longer sends a bearer token in HTTP headers. The Settings screen shows one Pairing Secret. Both the iOS app and healthkite-mcp use that secret locally as HKDF input:
  • discovery_id = HKDF(root, "healthkite-mcp:discovery:v1") → Bonjour instance label.
  • psk = HKDF(root, "healthkite-mcp:auth:v1") → TLS pre-shared key.
The secret itself is never sent over the network. Bonjour discovery is only a hint; a spoofed advertisement still cannot complete the TLS-PSK handshake without the derived key. Tap Pairing Secret in Settings to copy it for MCP configuration. Tap Regenerate Pairing Secret to rotate it; clients using the old secret stop discovering/authenticating immediately.

Foreground-only execution

The LAN server is built on Apple’s Network framework (NWListener over TCP). It only runs while the HealthKite MCP app is in the foreground. This is an iOS platform limitation, not a HealthKite MCP design choice. iOS suspends third-party apps within ~30 seconds of being backgrounded; arbitrary listening sockets are not preserved. Apple offers narrow background modes (VoIP, audio, location) for specific app categories — none of which legitimately apply to a generic LAN server, and abusing them is an App Store rejection. In practice:
  • Open HealthKite MCP, leave it on screen → the server is up and advertised with Bonjour.
  • Switch apps, lock the phone, or use FaceTime → iOS suspends HealthKite MCP within ~30 seconds → the listener stops accepting new connections.
  • Open HealthKite MCP again → the server comes back on the configured port within 1-2 seconds.
The Settings screen says “Active while HealthKite MCP is open” to keep this expectation honest.

What this means for agents

MCP tools should expect transient Unreachable errors when the user steps away from the phone, disables Local Network permission, or joins a network that blocks mDNS/client-to-client traffic. The right pattern for agents: surface the message verbatim to the user. They’ll know to open HealthKite MCP and keep both devices on the same Wi-Fi.

Local Network permission

The first time the LAN server starts on a given iOS install, iOS shows the Local Network usage permission sheet:
“HealthKite MCP” Would Like to Find and Connect to Devices on Your Local Network.
Allowing this lets the app advertise with Bonjour and accept local TCP connections. Denying it prevents discovery/connection. You can re-grant at iOS Settings → Privacy & Security → Local Network → HealthKite MCP.

Port and addressing

Default port is 8080, configurable from 1024-65535. Users do not copy the IP address: the app advertises the configured port with Bonjour as <derived-instance>._healthkite-mcp._tcp.local, and healthkite-mcp resolves it automatically. Both devices must be on the same broadcast domain. Guest Wi-Fi/client isolation, separate VLANs, and some VPNs block mDNS or peer-to-peer LAN traffic.

TLS

The LAN server runs HTTP inside a TLS-PSK channel created by Apple Network.framework. There is no public certificate, public CA, or DNS name to validate; possession of the derived PSK authenticates the peer and encrypts the stream.