Skip to main content

marrow-mcp

Let your AI agents read your own Apple Health data.

Marrow is a free iOS app that tracks 178 health data series - 172 Apple Health types plus its own meal diary and set-by-set weightlifting log. This repo is its self-hosted companion server: one Python file, standard library only, that keeps a SQLite mirror of your data on hardware you own and serves it over the Model Context Protocol so agents can query it 24/7, phone in your pocket.

Nothing here talks to a cloud. Data flows phone → your machine, full stop.

An agent querying Marrow over MCP: sleep and workout data answered from the phone

Run it

pip install "marrow-mcp[qr]"                  # [qr] adds segno, which draws the pairing QR
marrow-server --port 8800 --data ./data       # prints a pairing URL

Without [qr] the pairing page shows the pairing JSON instead of a code.

or from a clone

python3 marrow_server.py                      # prints a pairing URL
python3 marrow_server.py --port 8800 --data ./data

or with Docker

docker compose up -d

Open the pairing URL on any screen, then in Marrow: Export, Server MCP, Pair with a server, and scan. From then on the app's background pushes keep the mirror current with the app closed. The app pairs over plain http only on your own networks (a private or tailnet IPv4 address, a .local or .ts.net name, a short LAN name); a public address needs https (--url https://...).

Upgrading to 0.3.0

Stop the old server and start the new one on the same --data directory. An existing mirror.sqlite gains the new columns on first start, and the tokens in --data carry over, so the phone stays paired. Sets logged by Marrow 1.4 carry a set_type (work, warmup, failure or drop). Warm-ups are still listed but no longer count toward volume or records, and rows mirrored before the upgrade read as work sets.

Connect an agent

The server speaks MCP over Streamable HTTP (JSON-RPC 2.0, protocol version 2025-06-18), authenticated with a bearer token it generates on first run and prints alongside the pairing link.

Claude Code

claude mcp add --transport http marrow \
  http://<server-ip>:8800/mcp \
  --header "Authorization: Bearer <mcp token>"

Claude Desktop, one click

Download marrow.mcpb, double-click it, and Claude Desktop installs the extension and asks for the URL and token. No terminal involved. (The bundle is a tiny zero-dependency bridge in mcpb/; it forwards Claude's stdio to your Marrow URL and nothing else.)

Claude Desktop (manual), Cursor, or anything using an mcp.json

{
  "mcpServers": {
    "marrow": {
      "type": "http",
      "url": "http://<server-ip>:8800/mcp",
      "headers": { "Authorization": "Bearer <mcp token>" }
    }
  }
}

Check it by hand

curl -s http://<server-ip>:8800/mcp \
  -H "Authorization: Bearer <mcp token>" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Tools

Nine tools, all of them reads. The server also carries write tools (log a meal, a workout and so on), but it lists them only after a phone registers it for write-back, and today only Marrow Connect does that. A self-hosted server paired from the app serves the nine reads and nothing an agent can call writes to your health record.

Tool Returns
health_summary Recent days across activity, heart, sleep and nutrition
list_metrics Every metric in the mirror, with units and coverage
metric_daily Daily values for any metric, up to 400 days
metric_samples Raw records with timestamps and source devices
workouts Workouts from every source: activity, start, end, duration and source
nutrition_log The meal diary: every logged food with full nutrient detail, by day
strength_log Every lifting set with its set type and estimated 1RM, per-exercise progression, and volume per muscle group (warm-ups left out)
sleep_log One night per wake day: bedtime, wake time, hours asleep, minutes per stage
symptoms_and_mood Symptoms with their severity, and State of Mind entries with valence, feelings and what they were about

Metric keys: list_metrics shows Apple's short names (active_energy_burned), and the tools also accept the app's own keys (active_energy, heart_rate_variability), so an agent moved over from the phone keeps its vocabulary.

Then ask your agent things like "how did my sleep change once I started training in the mornings?" and let it go and look.

Why not the built-in Claude or ChatGPT connector?

Both Claude (Pro/Max, US) and ChatGPT now read Apple Health natively. Use them if that is all you need. They stop where this server starts:

Claude / ChatGPT connector Marrow + this server
Where it works The iOS app only Claude Code, Claude Desktop, Cursor, OpenClaw, Hermes, any MCP client, on any machine
When it works While you are in the chat on the phone 24/7, phone in your pocket, from your own box
What the model sees Raw HealthKit numbers Daily values reconciled against Apple's own totals, meal diary, set-by-set lifts
Where the data lives Their cloud, per conversation SQLite on hardware you own
Cost Subscription Free, MIT

OpenClaw / Hermes / any agent on a home machine. Point the agent's MCP config at the server URL with the bearer token, exactly as in the mcp.json block above. Reach it from outside the LAN with tailscale serve --bg --https=8800 http://127.0.0.1:8800 and use the tailnet URL.

The other ways in

This server is one of the doors on Marrow's Export tab, and you do not need it to give agents access:

  1. Local MCP. Marrow runs an MCP server on the iPhone itself at http://<phone-ip>:21212/mcp, answering while the app is running. Seven of the nine tools above, zero extra hardware.
  2. Server MCP. This package: an always-on mirror on your own box.
  3. Automated. Scheduled pushes to any URL (Home Assistant, n8n, your own endpoint).
  4. Manual. CSV, JSON and GPX files out of the share sheet.

All four are in the free tier. Setup for all of them: https://marrowhealthapp.com/guides.

Marrow Connect is the hosted Pro path: Marrow runs the mirror, and ChatGPT, Claude or Gemini read it with the phone asleep and nothing to run. It is the only door that can log for you, once you turn on Allow AI write in the app. https://marrowhealthapp.com/connect

Security

  • Both servers are built for a LAN or a tailnet. Do not port-forward this to the open internet. If you need it remotely, front it with tailscale serve, Caddy, or an equivalent so the transport is HTTPS and the device is authenticated before the bearer token is ever presented.
  • Two separate tokens live in --data: .app-token for the phone's pushes and .mcp-token for agents. Rotating one does not disturb the other.
  • Ingest is idempotent and UUID-keyed, so a replayed batch cannot double-count.

Status

Marrow is on the App Store, iOS 17+, and requires Apple Health. Get it on the App Store.

The iOS app is closed source; this server is not, because you should be able to read anything you are asked to run on your own hardware.

Registry

Listed in the official MCP registry as tech.skeletonarmy/marrow, verified by DNS on skeletonarmy.tech.

mcp-name: tech.skeletonarmy/marrow

Help and policies

Licence

MIT. See LICENSE.

Metadata

Release files for marrow-mcp 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for marrow-mcp 0.3.0
File Size Uploaded
marrow_mcp-0.3.0.tar.gz 33.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for marrow-mcp 0.3.0
File Interpreter ABI Platform
marrow_mcp-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 67.7 kB

Release files / marrow_mcp-0.3.0.tar.gz

Download URL marrow_mcp-0.3.0.tar.gz
Size 33.4 kB
Tags Source
SHA-256 checksum
How to use checksums
04518142ac2a4d0a1f57f4096aa9ffc09d0d24732a47aff376e0efbf90c51ba6
BLAKE2b-256 checksum
How to use checksums
40aad5d31b536c0dc7f55302af9a9acb8457b8714985ef76bf96d1b1db349c36
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / marrow_mcp-0.3.0-py3-none-any.whl

Download URL marrow_mcp-0.3.0-py3-none-any.whl
Size 34.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7ef1586e1f37c0f604d6937c21fab9d3829ae8a7f799357b512cbfeaabe0d108
BLAKE2b-256 checksum
How to use checksums
a08c4807c0e64a022693437211e4c944e28d6c01354ccaa0fc57c64fed603ea5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page