You use Claude in three places: the phone app, Desktop, and Code. Only some of them can reach your Apple Health data, and the reason is one line of architecture, not a setting you missed. Here is where each route actually connects, with the config you paste.
Quick answer. A local MCP server is a program that runs on a computer, so Claude Desktop and Claude Code can launch it and the Claude phone app cannot. On the phone, Apple Health is best answered by the app's own on-device Ask, which runs on the iPhone with no cloud AI in the path. On a Mac, the local server reads your export folder and answers from your real numbers. Set up by the job you are doing, not by whichever Claude icon is nearest.
The one rule that decides every route
MCP servers reach a client in one of two ways. The first is local stdio: the client launches a small program and talks to it over standard input and output. The program is a process, so it has to run on the same machine as the client. The second is remote: the server answers at a network address, and the client connects to it like any web service.
That single split explains everything that follows. Claude Desktop runs on a Mac or a PC, so it can launch a local stdio server. Claude Code is a command line tool, so it can too. The Claude phone app runs on iOS, which cannot start a process on your Mac, so the phone can only reach a remote server. There is no config field that changes this. It is where the program lives.
The two values you reuse everywhere. Every local route below needs the same two things: SERVER_PATH (the absolute path to server.mjs) and HEALTH_DATA_DIR (the absolute path to the folder holding your exported .health-cache.json). If you used the iCloud destination on macOS, that folder is:
~/Library/Mobile Documents/iCloud~ai~healthexport~app/Documents
Expand ~ to your real home path in the config files. Most clients do not expand the tilde for you.
Route 1: Claude Desktop (local stdio)
Claude Desktop reads its servers from a config file at launch. The location depends on your OS:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
Merge a health-export entry into the mcpServers block. Leave any servers you already have in place:
{ "mcpServers": { "health-export": { "command": "node", "args": ["/Users/you/.health-export-mcp/server.mjs"], "env": { "HEALTH_DATA_DIR": "/Users/you/Library/Mobile Documents/iCloud~ai~healthexport~app/Documents" } } } } Save the file, then fully quit and reopen Claude Desktop. It reads mcpServers only at startup, so a reload is not enough.
Route 2: Claude Code (local stdio, one command)
Claude Code writes the same entry for you, so you never touch JSON by hand:
claude mcp add health-export \ -e HEALTH_DATA_DIR="/Users/you/Library/Mobile Documents/iCloud~ai~healthexport~app/Documents" \ -- node "/Users/you/.health-export-mcp/server.mjs" That writes user scope to ~/.claude.json. Add --scope project to write a shared .mcp.json into the repo instead. Confirm it landed with claude mcp list. One caveat: if you turned on pairing in the iOS app, do not pass the secret on the command line, because it lands in your shell history. Add "PAIRING_SECRET" to the entry's env in the config file by hand.
Route 3: Claude on the phone (remote or on-device)
The phone cannot launch a local server, so it has two honest options, and they trade differently.
A remote endpoint you host. You run a small receiver somewhere with an address, the iOS app pushes your export to it, and the phone's Claude connects to that address. This works, and the data lives on a machine you control. It is also the most setup: a host, a TLS certificate, an auth scheme, and a receiver that does not silently drop rows. If you want that route, the headers, the signature check and the six failure modes that quietly lose weeks of data are written up in the self-hosted receiver pattern.
On-device Ask. The simpler phone route is to skip the round trip. MetricBridge's own Ask answers questions against your Apple Health data on the iPhone, with a provenance card under each answer that shows the numbers, the date range and the computation. No cloud AI sees the question, and there is no endpoint to keep alive. It answers in English by design, and it is wellness information, not medical advice.
Pick by the job, not the app
| The job | Route | What connects |
| A quick question away from a desk | On-device Ask on the phone | The iPhone, no cloud AI |
| Deep analysis against your real export | Claude Desktop | Local stdio server on your Mac |
| Automation in a project or a script | Claude Code | Same local stdio server |
| An always-on feed for another machine or a team | A remote endpoint you host | Your server, at an address you own |
Notice the server never changes. The same zero-dependency Node process that serves Claude Desktop serves Claude Code, and the same data folder backs both. The only thing that differs is where the client runs.
A worked example: the same question, one route
Once the local server is connected, you just ask. Claude decides which tools to call. A real exchange against an export looks like this:
You: How did my recovery trend this week compared to last week? Use my MetricBridge data. Claude: [calls get_trends -> metric: hrv, period: 7d] [calls compare_periods -> hrv, resting_hr, sleep; this week vs last] Your HRV averaged 59.7 ms this week, up 4.4% from 57.2 ms last week. Resting heart rate fell from 56 to 55 bpm (-2.4%), and sleep held near 7.1 h. Both the HRV rise and the resting-HR fall are deviations from your own recent baseline. Steps were 6.6% higher over the same period. Every number comes from your local export, and every claim is stated against your own baseline rather than a population chart. The tool names you will call most are get_mcp_status, get_freshness, list_metrics, get_health_metrics, get_trends, compare_periods, resolve_metric and query_health_data. The server ships 22 tools (20 read-only, plus two that log events to their own file) and 23 prompts over 194 metrics, and it makes zero network calls.
Gotchas that waste an afternoon
You did not restart Desktop. The config is read once, at launch. Reloading a window does nothing.
The tilde.
~/Library/...in a JSON config is a literal~to the OS. Paste the expanded/Users/you/...path.Wrong env key. Claude Desktop, Claude Code and Cursor use
mcpServerswith anenvobject. opencode uses anmcpkey with anenvironmentobject and an array-stylecommand. Mixing them silently does nothing.A stale pairing secret. If pairing is on, the
PAIRING_SECRETmust match the iOS code exactly. A trailing space is enough to fail.An empty data folder. If the server connects but reports no data, check that export is on in the app and that iCloud Drive has finished syncing the
.health-cache.jsonfile to this computer.
Don't want to touch JSON at all? Paste this into Claude (or any agent): "Read undefined and set up MetricBridge for me." The agent reads the open Agent Skill, asks which client you use and where your data lives, patches its own config, and verifies the connection with get_mcp_status.
Frequently asked
Can the Claude phone app connect to a local MCP server?
No. A local MCP server is a program that runs on a computer. The Claude phone app runs on iOS, which cannot launch that program on your Mac, so the phone can only reach a server that answers at a network address. For Apple Health on the phone, the simpler route is the app's own on-device Ask, which answers on the iPhone with no cloud AI in the path.
Which Claude surface should I use for Apple Health?
Pick by the job, not the app. A quick question away from a desk is on-device Ask on the phone. Deep analysis against your real export is Claude Desktop with the local server. Automation inside a project or a script is Claude Code with the same server. An always-on feed for a team or another machine is a remote endpoint you host.
Is the MCP config the same for Claude Desktop and Claude Code?
The server command is identical: node, the absolute path to server.mjs, and HEALTH_DATA_DIR in the environment. Claude Desktop takes a hand-edited mcpServers block in claude_desktop_config.json. Claude Code writes the same entry for you with claude mcp add.
Does any of this send my Apple Health data to a cloud AI?
On the local routes, no. The app reads Apple Health read-only and writes JSON to a folder you pick, and the MCP server reads that folder on your machine with zero network calls. A remote endpoint you host is your call and your machine, and the phone's on-device Ask runs on the iPhone. Where your data goes is decided by which route you pick.
Put Apple Health where Claude already runs
The app does the export, the open-source server does the rest, and the same data answers on your phone.
Start my 7-day free trial
Install the MCP server
Source on GitHub
Where it goes: the app reads Apple Health read-only and writes JSON to a folder you pick. Nothing reaches us or a cloud AI. What you get: all 194 metrics, 22 tools (20 read-only) and 23 prompts, plus on-device Ask. Setup: about two minutes. Price: $24.99 one time after a 7-day free trial, not a subscription.


![[AWS] How far can CDK/Terraform stacks run on AWS Emulator? [AWSEmulator]](https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-user-contents.imgix.net%2Fhttps%253A%252F%252Fqiita-user-contents.imgix.net%252Fhttps%25253A%25252F%25252Fcdn.qiita.com%25252Fassets%25252Fpublic%25252Farticle-ogp-background-afbab5eb44e0b055cce1258705637a91.png%253Fixlib%253Drb-4.1.1%2526w%253D1200%2526blend64%253DaHR0cHM6Ly9xaWl0YS11c2VyLXByb2ZpbGUtaW1hZ2VzLmltZ2l4Lm5ldC9odHRwcyUzQSUyRiUyRnMzLWFwLW5vcnRoZWFzdC0xLmFtYXpvbmF3cy5jb20lMkZxaWl0YS1pbWFnZS1zdG9yZSUyRjAlMkYxOTI5NDklMkYxYmVjZGE4YTRmMWRiOWU5OTQyZDljOGMwYjZkZDA3NjkwMTM2NjgwJTJGbGFyZ2UucG5nJTNGMTc0MTQ4MzQxMD9peGxpYj1yYi00LjEuMSZhcj0xJTNBMSZmaXQ9Y3JvcCZtYXNrPWVsbGlwc2UmYmc9RkZGRkZGJmZtPXBuZzMyJnM9MDZlM2QxY2EzNTVhN2Y4N2M2ZTQxY2RlYzdmN2M0ODI%2526blend-x%253D120%2526blend-y%253D462%2526blend-w%253D90%2526blend-h%253D90%2526blend-mode%253Dnormal%2526mark64%253DaHR0cHM6Ly9xaWl0YS1vcmdhbml6YXRpb24taW1hZ2VzLmltZ2l4Lm5ldC9odHRwcyUzQSUyRiUyRnMzLWFwLW5vcnRoZWFzdC0xLmFtYXpvbmF3cy5jb20lMkZxaWl0YS1vcmdhbml6YXRpb24taW1hZ2UlMkYxZTIwZGI1ZTdlNDA3ZWFlN2I5NzBlYzk5OTg4MGRjOGMzY2MwZjY0JTJGb3JpZ2luYWwuanBnJTNGMTY2NzI3NDk2Mz9peGxpYj1yYi00LjEuMSZ3PTQ0Jmg9NDQmZml0PWNyb3AmbWFzaz1jb3JuZXJzJmNvcm5lci1yYWRpdXM9OCZiZz1GRkZGRkYmYm9yZGVyPTIlMkNGRkZGRkYmZm09cG5nMzImcz04OTI0NDcwMDk1MDMyZjUxYmZlNzE3ZjVkOGUzYmE3ZA%2526mark-x%253D186%2526mark-y%253D515%2526mark-w%253D40%2526mark-h%253D40%2526s%253D0db13b4aef231a19bc684897cf15021a%3Fixlib%3Drb-4.1.1%26w%3D1200%26fm%3Djpg%26mark64%3DaHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjEuMSZ3PTk2MCZoPTMyNCZ0eHQ9JUUzJTgwJTkwQVdTJUUzJTgwJTkxQVdTJTIwRW11bGF0b3IlRTMlODElQTdDREslMkZUZXJyYWZvcm0lRTMlODElQUUlRTMlODIlQjklRTMlODIlQkYlRTMlODMlODMlRTMlODIlQUYlRTMlODElQUYlRTMlODElQTklRTMlODElOTMlRTMlODElQkUlRTMlODElQTclRTUlOEIlOTUlRTMlODElOEYlRTMlODElOEIlRTMlODAlOTBBV1NFbXVsYXRvciVFMyU4MCU5MSZ0eHQtYWxpZ249bGVmdCUyQ3RvcCZ0eHQtY29sb3I9JTIzMUUyMTIxJnR4dC1mb250PUhpcmFnaW5vJTIwU2FucyUyMFc2JnR4dC1zaXplPTU2JnR4dC1wYWQ9MCZzPTgyMGFkODg1ZTFmOTNiYWMwMGY2OGY3ZjEzMTZhM2Fj%26mark-x%3D120%26mark-y%3D112%26blend64%3DaHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjEuMSZ3PTgzOCZoPTU4JnR4dD0lNDBOYW5hXzc3NyZ0eHQtY29sb3I9JTIzMUUyMTIxJnR4dC1mb250PUhpcmFnaW5vJTIwU2FucyUyMFc2JnR4dC1zaXplPTM2JnR4dC1wYWQ9MCZzPTg1YzQ4MzUyMmVkMGVhNmYxYjhkZjU5MjVjYzhiNjQz%26blend-x%3D242%26blend-y%3D454%26blend-w%3D838%26blend-h%3D46%26blend-fit%3Dcrop%26blend-crop%3Dleft%252Cbottom%26blend-mode%3Dnormal%26txt64%3DS0RESeOCouOCuOODo-OCpOODq-mWi-eZuuOCu-ODs-OCv-ODvOagquW8j-S8muekvg%26txt-x%3D242%26txt-y%3D539%26txt-width%3D838%26txt-clip%3Dend%252Cellipsis%26txt-color%3D%25231E2121%26txt-font%3DHiragino%2520Sans%2520W6%26txt-size%3D28%26s%3Dba21d9d97271ac7f70cc902b1a0ad7bb)