<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Philip D'Souza</title>
    <description>The latest articles on DEV Community by Philip D'Souza (@philipad).</description>
    <link>https://dev.to/philipad</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4048242%2Fe490c7ae-56a7-462a-aa6d-f544d6bb9cdb.jpg</url>
      <title>DEV Community: Philip D'Souza</title>
      <link>https://dev.to/philipad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/philipad"/>
    <language>en</language>
    <item>
      <title>On-device health AI needs an MCP bridge, not a silo</title>
      <dc:creator>Philip D'Souza</dc:creator>
      <pubDate>Thu, 03 Sep 2026 23:15:02 +0000</pubDate>
      <link>https://dev.to/philipad/on-device-health-ai-needs-an-mcp-bridge-not-a-silo-1g7n</link>
      <guid>https://dev.to/philipad/on-device-health-ai-needs-an-mcp-bridge-not-a-silo-1g7n</guid>
      <description>&lt;p&gt;On-device health AI keeps your Apple Health data on your phone. That's the right privacy model. It also locks that data inside one app's chat interface.&lt;/p&gt;

&lt;p&gt;You can't ask Claude about it. You can't feed it to Cursor for deeper analysis. You can't chain it into an automation. The privacy win becomes a portability loss.&lt;/p&gt;

&lt;p&gt;An MCP bridge solves that. It's a small server that runs on your machine, exposes your local health data as live tools any MCP-aware agent can call, and never sends anything to the cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the bridge looks like
&lt;/h2&gt;

&lt;p&gt;The server is 84 kB, zero dependencies, and makes zero runtime network calls. It reads the on-device iCloud health cache that the iOS app already syncs. Fourteen read-only tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;8 metric queries (get_health_metrics, list_metrics, get_intraday, etc.)&lt;/li&gt;
&lt;li&gt;get_workouts, get_sleep_sessions, get_events&lt;/li&gt;
&lt;li&gt;get_profile, get_cycle_context&lt;/li&gt;
&lt;li&gt;correlate_metrics (names the segment boundary behind a correlation so it's not a travel-day artifact)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plus 22 MCP prompts and a &lt;code&gt;--demo&lt;/code&gt; mode that serves a synthetic dataset with zero setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;One config block. Same server command in Claude Desktop, Claude Code, Cursor, ChatGPT Desktop, Windsurf, Codex CLI, opencode, OpenClaw. Only the config file path changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"metricbridge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"health-export-mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;Most on-device health apps process locally but give you no way to connect that data to the AI agents you already use. No MCP server, no export pipeline, no bridge. The data stays private, but it also stays locked inside one app's UI.&lt;/p&gt;

&lt;p&gt;The trade-off used to be privacy or portability. An on-device app with an MCP bridge gives you both. The data never leaves your phone, and any MCP-aware agent can query it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.healthexport.dev/blog/why-on-device-health-ai-apps-need-an-mcp-bridge?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=exp-20260903-hea84-mcpbridge" rel="noopener noreferrer"&gt;Read the full guide&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>v1.4.0: Apple Health MCP now answers workouts, sleep sessions, events, and correlation</title>
      <dc:creator>Philip D'Souza</dc:creator>
      <pubDate>Wed, 19 Aug 2026 14:14:24 +0000</pubDate>
      <link>https://dev.to/philipad/v140-apple-health-mcp-now-answers-workouts-sleep-sessions-events-and-correlation-3906</link>
      <guid>https://dev.to/philipad/v140-apple-health-mcp-now-answers-workouts-sleep-sessions-events-and-correlation-3906</guid>
      <description>&lt;p&gt;v1.4.0 ships six new read-only tools on top of the eight metric queries, plus 22 MCP prompts, demo mode, and a CLI. The server now answers the questions a health log actually holds, not just the numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  New tools (6), 14 total
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;list_events&lt;/code&gt; for clinical and lifestyle events tagged to days: illness, medication, travel, fasts.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_workouts&lt;/code&gt; for structured workout sessions with type, duration, distance, energy.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_profile&lt;/code&gt; for sex, age range, blood type, device list. The context every other answer depends on.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_sleep_sessions&lt;/code&gt; for per-night sleep architecture instead of one collapsed number.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_cycle_context&lt;/code&gt; for menstrual cycle phase and day, so HRV and sleep correlations land in the right hormonal window.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;correlate_metrics&lt;/code&gt; ranks correlation between two metrics over a window and names the segment boundary behind the number, so a strong correlation is not a travel-day artifact.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  22 MCP prompts
&lt;/h2&gt;

&lt;p&gt;The server now advertises prompts. Trend reads, period comparisons, workout summaries, sleep reviews, cycle-aware analysis, caregiver check-ins. Clients with a prompts panel get a one-click entry into each.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honesty fixes
&lt;/h2&gt;

&lt;p&gt;Trend and period-comparison answers now name the segment boundary they used, not a smooth average that hides it. Day filters, &lt;code&gt;excludeTravelDays&lt;/code&gt;, and anchor comparisons on &lt;code&gt;correlate_metrics&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo mode and CLI
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;npx -y health-export-mcp --demo&lt;/code&gt; serves a watermarked synthetic dataset. Zero setup. Useful for evaluation, screenshots, and registry indexers.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--doctor&lt;/code&gt; runs diagnostics on the cache file and environment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;status --max-age&lt;/code&gt; freshness gate.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;receive&lt;/code&gt; mode for the webhook bridge.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tooling
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;readOnly&lt;/code&gt; and &lt;code&gt;idempotent&lt;/code&gt; annotations on every tool. File contracts in &lt;code&gt;docs/SCHEMA-CONTRACTS.md&lt;/code&gt;. Caregiver and Shortcuts write-bridge patterns in &lt;code&gt;docs/&lt;/code&gt;. 101 unit tests and 42 integration checks green.&lt;/p&gt;

&lt;p&gt;Zero dependencies. Zero network calls. Local-first only. Same &lt;code&gt;npx -y health-export-mcp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Docs and install: &lt;a href="https://healthexport.dev/mcp?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=exp-20260819-hea84-v140" rel="noopener noreferrer"&gt;https://healthexport.dev/mcp?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=exp-20260819-hea84-v140&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cli</category>
      <category>mcp</category>
      <category>software</category>
      <category>tools</category>
    </item>
    <item>
      <title>Claude Code vs Claude Desktop for Apple Health: script vs number</title>
      <dc:creator>Philip D'Souza</dc:creator>
      <pubDate>Tue, 18 Aug 2026 15:10:01 +0000</pubDate>
      <link>https://dev.to/philipad/claude-code-vs-claude-desktop-for-apple-health-script-vs-number-1430</link>
      <guid>https://dev.to/philipad/claude-code-vs-claude-desktop-for-apple-health-script-vs-number-1430</guid>
      <description>&lt;p&gt;Claude Desktop and Claude Code both call the same read-only Apple Health MCP tools. The difference is what they hand back. A chat agent returns a number. A coding agent writes the script that computes the number, saves a chart to disk, and reruns it next month when fresh data lands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Claude Code specifically
&lt;/h2&gt;

&lt;p&gt;Claude Code runs in your terminal, reads and writes files, and executes code, not just chat replies. That combination is what makes it useful for health data. It can call the same read-only Apple Health tools a chat client can, but it can also turn the result into a script, a chart, or a CSV saved to disk, and rerun that script whenever fresh data lands.&lt;/p&gt;

&lt;p&gt;A chat-only client can tell you a number. An agent with a file system and code execution can build you a reusable analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Worked example: does your HRV track your sleep duration?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: Pull my HRV and sleep duration for the last 90 days from health-export,
     compute the correlation between them, and plot it.

Claude Code: [calls list_metrics -&amp;gt; checks `days` and `firstDate` for both series]
             [calls get_health_metrics -&amp;gt; heart_rate_variability, 90d]
             [calls get_health_metrics -&amp;gt; sleep_analysis, 90d]
             [writes analyze_hrv_sleep.py -- aligns both series by date,
              computes Pearson r with scipy, renders a scatter plot]
             [runs the script]

             Pearson r over the nights where both readings exist, with the
             n it actually found, plus a scatter plot saved to
             hrv_vs_sleep.png -- computed from your own data, on your own
             machine.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the first call: &lt;code&gt;list_metrics&lt;/code&gt; returns &lt;code&gt;days&lt;/code&gt;, &lt;code&gt;firstDate&lt;/code&gt; and &lt;code&gt;lastDate&lt;/code&gt; per metric, so the agent checks how much history it actually has before asking for a 90-day window, and tells you if the file is shallower than the question.&lt;/p&gt;

&lt;p&gt;Nothing here required copying a CSV into a chat window or trusting a black-box insight. The script is on disk, the statistics are standard, and you can open &lt;code&gt;analyze_hrv_sleep.py&lt;/code&gt; yourself and check every line. Ask a follow-up: "now split that by whether I trained that day" and Claude Code extends the same script rather than starting over.&lt;/p&gt;

&lt;h2&gt;
  
  
  The eight read-only tools
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What it returns&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_mcp_status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Health check: data source, metric count, most recent data date&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;list_metrics&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every available metric with unit, day count, date range&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_health_metrics&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Values for a metric over a date range with aggregation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_trends&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compare recent N-day window against prior N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;compare_periods&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A/B two arbitrary date windows for a single metric&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_structured_export&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clean structured JSON, paginated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_intraday&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hour-by-hour window, live within-day view&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;query_health_data&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Natural-language convenience query&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;190 Apple Health metrics. 84 kB npm package. Zero dependencies. Zero network calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Register the server with Claude Code
&lt;/h2&gt;

&lt;p&gt;Let the CLI write its own config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add health-export &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;HEALTH_DATA_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/Users/you/Library/Mobile Documents/iCloud~ai~healthexport~app/Documents"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--&lt;/span&gt; node &lt;span class="s2"&gt;"/Users/you/.health-export-mcp/server.mjs"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify with &lt;code&gt;claude mcp list&lt;/code&gt;. Or paste "Read &lt;a href="https://healthexport.dev/SKILL.md" rel="noopener noreferrer"&gt;https://healthexport.dev/SKILL.md&lt;/a&gt; and set up Health Export AI for me" into Claude Code and it patches its own MCP config and verifies the connection.&lt;/p&gt;

&lt;p&gt;Full setup, the comparison table against cloud-upload AI health apps and manual spreadsheets, and the FAQ: &lt;a href="https://www.healthexport.dev/blog/local-first-health-analytics-with-claude-code?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=exp-20260818-hea80-claudecode-local" rel="noopener noreferrer"&gt;complete guide on healthexport.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>claude</category>
      <category>datascience</category>
      <category>mcp</category>
    </item>
    <item>
      <title>One MCP server, eight AI clients: Apple Health setup that works everywhere</title>
      <dc:creator>Philip D'Souza</dc:creator>
      <pubDate>Tue, 18 Aug 2026 13:25:01 +0000</pubDate>
      <link>https://dev.to/philipad/one-mcp-server-eight-ai-clients-apple-health-setup-that-works-everywhere-4lcp</link>
      <guid>https://dev.to/philipad/one-mcp-server-eight-ai-clients-apple-health-setup-that-works-everywhere-4lcp</guid>
      <description>&lt;p&gt;Most Apple Health MCP guides are per-client. Claude today, Cursor tomorrow, ChatGPT next week. That's the wrong abstraction. MCP is a protocol. The server command is identical across every client. Only the config file path and JSON shape change.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the server exposes
&lt;/h2&gt;

&lt;p&gt;Eight read-only tools, all local:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What it returns&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_mcp_status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Health check: data source, metric count, most recent data date&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;list_metrics&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every available metric with unit, day count, date range&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_health_metrics&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Values for a metric over a date range with aggregation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_trends&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compare recent N-day window against prior N&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;compare_periods&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A/B two arbitrary date windows for a single metric&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_structured_export&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clean structured JSON, paginated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_intraday&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hour-by-hour window, live within-day view&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;query_health_data&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Natural-language convenience query&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;190 Apple Health metrics. 84 kB npm package. Zero dependencies. Zero network calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  The config that works everywhere
&lt;/h2&gt;

&lt;p&gt;Claude Desktop (&lt;code&gt;~/Library/Application Support/Claude/claude_desktop_config.json&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"health-export"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"/Users/you/.health-export-mcp/server.mjs"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"HEALTH_DATA_DIR"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/Users/you/Library/Mobile Documents/iCloud~ai~healthexport~app/Documents"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cursor uses the same shape at &lt;code&gt;~/.cursor/mcp.json&lt;/code&gt;. Windsurf uses it at &lt;code&gt;~/.codeium/windsurf/mcp_config.json&lt;/code&gt;. ChatGPT Desktop takes the inner block in Settings &amp;gt; MCP Servers. Codex CLI reads &lt;code&gt;.mcp.json&lt;/code&gt;. opencode uses &lt;code&gt;mcp&lt;/code&gt; + &lt;code&gt;environment&lt;/code&gt; + array &lt;code&gt;command&lt;/code&gt; instead of &lt;code&gt;mcpServers&lt;/code&gt; + &lt;code&gt;env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The server command never changes. Only the file path does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real queries
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: What is my HRV trend over the last 14 days?
Agent: [calls get_trends] Your HRV averaged 58 ms, up 5.5% vs prior 14 days.

You: Compare my sleep this week to last week.
Agent: [calls compare_periods] Deep sleep up 17%, total sleep up 6%.

You: How does my RHR change on days I sleep less than 6 hours?
Agent: [calls query_health_data] RHR averages 58 bpm after &amp;amp;lt;6h sleep, 53 bpm after &amp;amp;gt;7h.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No CSV, no copy-paste, no screenshots. Live data from your iPhone, answered locally.&lt;/p&gt;

&lt;p&gt;Full config blocks for all eight clients, troubleshooting, and FAQ: &lt;a href="https://www.healthexport.dev/blog/query-apple-health-with-any-ai-agent?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=exp-20260818-hea80-multiclient" rel="noopener noreferrer"&gt;complete guide on healthexport.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>mcp</category>
      <category>tools</category>
    </item>
    <item>
      <title>ChatGPT Health vs on-device health AI: what actually leaves your iPhone</title>
      <dc:creator>Philip D'Souza</dc:creator>
      <pubDate>Tue, 18 Aug 2026 12:51:01 +0000</pubDate>
      <link>https://dev.to/philipad/chatgpt-health-vs-on-device-health-ai-what-actually-leaves-your-iphone-1c08</link>
      <guid>https://dev.to/philipad/chatgpt-health-vs-on-device-health-ai-what-actually-leaves-your-iphone-1c08</guid>
      <description>&lt;p&gt;ChatGPT Health launched 23 July 2026. It connects Apple Health and medical records from Epic, Oracle, One Medical so ChatGPT can answer questions about your health data. AppleInsider, TechCrunch, and The Verge all covered the privacy implication: your heart rate, sleep stages, blood oxygen, and medical records now live on OpenAI's servers.&lt;/p&gt;

&lt;p&gt;This is not unusual for a cloud AI product. The question is whether you want your resting heart rate and sleep architecture on a third party's servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  How ChatGPT Health works (and where your data goes)
&lt;/h2&gt;

&lt;p&gt;ChatGPT Health is a cloud service. Your Apple Health data and your question go to OpenAI. GPT processes them and returns an answer. Your HRV, sleep, and medical records now sit on OpenAI's infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  How on-device health AI works (and what stays on your iPhone)
&lt;/h2&gt;

&lt;p&gt;On-device health AI apps process everything on your iPhone. No account, no sign-in. The open-source MCP server makes zero runtime network calls. For Health Export AI, the Meta advertising SDK cannot access HealthKit data: enforced in code with a CI test that fails the build.&lt;/p&gt;

&lt;h2&gt;
  
  
  Same question, two architectures
&lt;/h2&gt;

&lt;p&gt;Consider: "How did my HRV trend this week compared to last week?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ChatGPT Health:&lt;/strong&gt; your question and Apple Health data go to OpenAI's servers. GPT processes the comparison. Your HRV data now lives on OpenAI's infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On-device + MCP:&lt;/strong&gt; the model runs on your phone. Same answer. Nothing leaves.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trade-off that disappeared
&lt;/h2&gt;

&lt;p&gt;On-device health AI apps are private by design, but most are walled gardens. You ask questions in the app, you get answers there. Your data never leaves, but you also cannot feed it to the AI agents you already use.&lt;/p&gt;

&lt;p&gt;If you use an on-device health AI that also ships an MCP bridge, you get both: the privacy of on-device processing and the ability to query your health data from Claude, Cursor, ChatGPT Desktop, or any MCP-aware agent.&lt;/p&gt;

&lt;p&gt;The trade-off used to be privacy or portability. An on-device app with an MCP bridge gives you both.&lt;/p&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-y&lt;/span&gt; health-export-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://healthexport.dev/blog/chatgpt-health-vs-on-device-health-ai?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=exp-20260818-hea80-chatgptvshealth" rel="noopener noreferrer"&gt;healthexport.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>openai</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Apple Health export.xml to JSON: stop using DOM parsers</title>
      <dc:creator>Philip D'Souza</dc:creator>
      <pubDate>Tue, 18 Aug 2026 02:40:00 +0000</pubDate>
      <link>https://dev.to/philipad/apple-health-exportxml-to-json-stop-using-dom-parsers-il3</link>
      <guid>https://dev.to/philipad/apple-health-exportxml-to-json-stop-using-dom-parsers-il3</guid>
      <description>&lt;p&gt;Most "convert Apple Health XML to JSON" guides hand you a Python script with &lt;code&gt;xml.etree.ElementTree&lt;/code&gt;. ElementTree is a DOM parser. It loads the entire XML tree into RAM before you can read a single node.&lt;/p&gt;

&lt;p&gt;A long-term Apple Watch user has a 1.8GB export.xml. That is roughly 4.26 million records. Run a DOM parser against it and the process swaps to disk and dies before it returns one record.&lt;/p&gt;

&lt;p&gt;What actually works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Streaming SAX parsers.&lt;/strong&gt; &lt;code&gt;xml.sax&lt;/code&gt; or &lt;code&gt;lxml.etree.iterparse&lt;/code&gt; hold one record at a time. Constant memory, multi-GB files, no crash.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dedicated CLI tools.&lt;/strong&gt; &lt;code&gt;healthsync&lt;/code&gt; (Go, SQLite output) parses a 950MB export in 30 seconds at ~10MB heap. &lt;code&gt;openhealth&lt;/code&gt; (Bun, saxes SAX) handles a 1M-record file in 5 seconds at 5MB heap. &lt;code&gt;vpetersson/apple-health-mcp-server&lt;/code&gt; (Rust + DuckDB) takes a 2.5GB export in under a minute.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skip the XML entirely.&lt;/strong&gt; The Health Export AI iOS app reads HealthKit directly with read-only permission and writes JSON to iCloud. No export.xml, no computer, no manual transfer of a 1.8GB file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you only need a one-time conversion of an existing export.xml, use a browser converter or a Python script with a streaming parser. If you plan to query your health data with AI agents regularly, skip the XML loop.&lt;/p&gt;

&lt;p&gt;Full guide with all four methods, benchmarks, and code samples: &lt;a href="https://www.healthexport.dev/blog/apple-health-export-xml-to-json-complete-guide?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=exp-20260818-hea44-xmljson" rel="noopener noreferrer"&gt;Apple Health export.xml to JSON: The Complete Guide (2026)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cli</category>
      <category>performance</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>Apple Health data privacy with AI agents: local-first vs cloud</title>
      <dc:creator>Philip D'Souza</dc:creator>
      <pubDate>Tue, 18 Aug 2026 01:25:01 +0000</pubDate>
      <link>https://dev.to/philipad/apple-health-data-privacy-with-ai-agents-local-first-vs-cloud-59dp</link>
      <guid>https://dev.to/philipad/apple-health-data-privacy-with-ai-agents-local-first-vs-cloud-59dp</guid>
      <description>&lt;p&gt;ChatGPT Health launched in July 2026. Ask it about your resting heart rate, and your HRV, sleep stages, and workout history leave your phone for OpenAI servers you do not control. The answer comes back in a chat, so most people assume the data stayed local. It did not.&lt;/p&gt;

&lt;p&gt;AI Health Export (Gemini) works the same way. Your metrics transit a server you cannot audit, get processed by a model you cannot inspect, and the result gets stored by a company you do not own.&lt;/p&gt;

&lt;p&gt;The local-first path is the opposite. An MCP agent reads Apple Health on your own hardware and sends nothing over the network. No upload, no remote model, no stored copy. The data your AI agent reasons over never leaves your machine.&lt;/p&gt;

&lt;p&gt;What this means in practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your resting heart rate, HRV, sleep stages and workouts stay on device.&lt;/li&gt;
&lt;li&gt;The agent queries Apple Health read-only through a local MCP server.&lt;/li&gt;
&lt;li&gt;Zero network calls during a query. Nothing transmits.&lt;/li&gt;
&lt;li&gt;You can read 190 metrics this way without handing them to a cloud model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Privacy here is not a toggle in a settings screen. It is a property of the architecture. If the tool cannot transmit, your data cannot leak. That is a stronger guarantee than any privacy policy.&lt;/p&gt;

&lt;p&gt;Install:&lt;/p&gt;

&lt;p&gt;npx -y health-export-mcp&lt;/p&gt;

&lt;p&gt;Canonical: &lt;a href="https://www.healthexport.dev/blog/apple-health-data-privacy-with-ai-agents?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=exp-20260818-hea44-privacy" rel="noopener noreferrer"&gt;https://www.healthexport.dev/blog/apple-health-data-privacy-with-ai-agents?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=exp-20260818-hea44-privacy&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>cloud</category>
      <category>mcp</category>
      <category>privacy</category>
    </item>
    <item>
      <title>get_intraday: a live within-day window for Apple Health, over MCP</title>
      <dc:creator>Philip D'Souza</dc:creator>
      <pubDate>Tue, 18 Aug 2026 00:35:01 +0000</pubDate>
      <link>https://dev.to/philipad/getintraday-a-live-within-day-window-for-apple-health-over-mcp-5585</link>
      <guid>https://dev.to/philipad/getintraday-a-live-within-day-window-for-apple-health-over-mcp-5585</guid>
      <description>&lt;p&gt;Most health MCP servers stop at yesterday. The live within-day window was the missing piece.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;health-export-mcp&lt;/code&gt; v1.3.0 adds &lt;code&gt;get_intraday&lt;/code&gt;, the 8th read-only tool. The iOS app's hourly automations (app 1.4+) write a small &lt;code&gt;health-intraday.json&lt;/code&gt; file beside the daily cache. The server serves it back:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hour-by-hour points for every metric in the window&lt;/li&gt;
&lt;li&gt;the latest value per metric&lt;/li&gt;
&lt;li&gt;an optional &lt;code&gt;metric&lt;/code&gt; filter&lt;/li&gt;
&lt;li&gt;a clean &lt;code&gt;available: false&lt;/code&gt; answer with setup guidance when no hourly automation has delivered yet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The file is replaced on every hourly run, so you get a live within-day view, not history. Day-level questions still belong to &lt;code&gt;get_health_metrics&lt;/code&gt; and the other daily tools. &lt;code&gt;get_mcp_status&lt;/code&gt; now reports whether the intraday window is present.&lt;/p&gt;

&lt;p&gt;Install with any MCP client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-y&lt;/span&gt; health-export-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eight read-only tools, local-first, zero network calls. Full docs and the tool list: &lt;a href="https://www.healthexport.dev/mcp/?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=exp-20260818-hea59-intraday" rel="noopener noreferrer"&gt;https://www.healthexport.dev/mcp/?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=exp-20260818-hea59-intraday&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ios</category>
      <category>mcp</category>
      <category>software</category>
      <category>tools</category>
    </item>
    <item>
      <title>Connect Apple Health to Claude via MCP, the Exact Config</title>
      <dc:creator>Philip D'Souza</dc:creator>
      <pubDate>Sat, 08 Aug 2026 12:54:30 +0000</pubDate>
      <link>https://dev.to/philipad/connect-apple-health-to-claude-via-mcp-the-exact-config-4ilf</link>
      <guid>https://dev.to/philipad/connect-apple-health-to-claude-via-mcp-the-exact-config-4ilf</guid>
      <description>&lt;p&gt;Claude can reason about your sleep, HRV, and training load. What it cannot do out of the box is reach your Apple Health data. It cannot open the Health app, and pasting a giant CSV into a chat window is a dead end: the units get mangled, the snapshot is stale the moment you export it.&lt;/p&gt;

&lt;p&gt;The fix is MCP, the Model Context Protocol. With a small local server, Claude calls read-only tools against your real Apple Health data whenever you ask a question. This is the exact setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The seven read-only tools
&lt;/h2&gt;

&lt;p&gt;The Health Export AI MCP server is zero-dependency Node. No Docker, no Python environment, no cloud bridge. It exposes seven tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;get_mcp_status&lt;/code&gt; confirms the server can see your data&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;list_metrics&lt;/code&gt; lists which of the 190 metrics are available&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_health_metrics&lt;/code&gt; pulls raw values for a metric and date range&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_trends&lt;/code&gt; week-over-week or month-over-month trend math&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;compare_periods&lt;/code&gt; A/B two time windows (this week vs last)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_structured_export&lt;/code&gt; a tidy structured bundle for deeper analysis&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;query_health_data&lt;/code&gt; flexible plain-language queries across metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The data never leaves your control. The iOS app reads Apple Health read-only and writes a JSON file to a folder you pick. The MCP server reads that folder. Nothing transits the developer's servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Claude Desktop config
&lt;/h2&gt;

&lt;p&gt;Two routes. The one-click &lt;code&gt;.mcpb&lt;/code&gt; bundle: download &lt;code&gt;health-export.mcpb&lt;/code&gt;, double-click it, Claude Desktop prompts you for the data folder, confirm, restart.&lt;/p&gt;

&lt;p&gt;Or edit &lt;code&gt;claude_desktop_config.json&lt;/code&gt; by hand and merge a &lt;code&gt;health-export&lt;/code&gt; entry into &lt;code&gt;mcpServers&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"health-export"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"/Users/you/.health-export-mcp/server.mjs"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"HEALTH_DATA_DIR"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/Users/you/Library/Mobile Documents/iCloud~ai~healthexport~app/Documents"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Swap in your real &lt;code&gt;SERVER_PATH&lt;/code&gt; and &lt;code&gt;HEALTH_DATA_DIR&lt;/code&gt;. Fully quit and reopen Claude Desktop, it only reads the config at launch. Verify by asking: "Use the health-export tools to call get_mcp_status."&lt;/p&gt;

&lt;h2&gt;
  
  
  The same setup for Cursor, opencode, OpenClaw
&lt;/h2&gt;

&lt;p&gt;The server never changes, only where each client wants its config.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cursor&lt;/strong&gt; uses the same &lt;code&gt;mcpServers&lt;/code&gt; shape as Claude Desktop. Drop the identical block into &lt;code&gt;~/.cursor/mcp.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;opencode&lt;/strong&gt; uses a different shape. The top key is &lt;code&gt;mcp&lt;/code&gt;, &lt;code&gt;command&lt;/code&gt; is an array, and the env key is &lt;code&gt;environment&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://opencode.ai/config.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"health-export"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/Users/you/.health-export-mcp/server.mjs"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"environment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"HEALTH_DATA_DIR"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/Users/you/Library/Mobile Documents/iCloud~ai~healthexport~app/Documents"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;OpenClaw&lt;/strong&gt; consumes standard MCP servers; add a &lt;code&gt;health-export&lt;/code&gt; block using the same &lt;code&gt;node server.mjs&lt;/code&gt; command and &lt;code&gt;HEALTH_DATA_DIR&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A worked example
&lt;/h2&gt;

&lt;p&gt;Once connected, you talk to Claude normally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You: How did my recovery trend this week compared to last week?
      Use my Health Export data.

Claude: [calls get_trends, then compare_periods]
        Your HRV averaged 61 ms this week, up 4.4% from 58 ms last week.
        Resting heart rate dropped from 56 to 55 bpm. Sleep held at 7.1 h.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No CSV, no pasting, no stale snapshot. Live numbers from your local export.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Claude shows no health-export tools:&lt;/strong&gt; the config was not loaded. Confirm the JSON is valid, you edited the right file for your OS, and you fully quit and relaunched Claude Desktop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server connects but says no data:&lt;/strong&gt; your &lt;code&gt;HEALTH_DATA_DIR&lt;/code&gt; points at the wrong folder, or the export has not synced the &lt;code&gt;.health-cache.json&lt;/code&gt; file yet. Check export is on in the iOS app, iCloud Drive has finished syncing, and the path matches with &lt;code&gt;~&lt;/code&gt; expanded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wrong env key for your client:&lt;/strong&gt; Claude Desktop, Claude Code, and Cursor use &lt;code&gt;mcpServers&lt;/code&gt; with &lt;code&gt;env&lt;/code&gt;. opencode and OpenClaw use &lt;code&gt;mcp&lt;/code&gt; with &lt;code&gt;environment&lt;/code&gt; and an array-style &lt;code&gt;command&lt;/code&gt;. Putting &lt;code&gt;env&lt;/code&gt; into an opencode file silently does nothing.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is a summary. The complete guide with the full troubleshooting section, the Claude Code CLI setup, and the Hermes notes is on the original post: &lt;a href="https://www.healthexport.dev/blog/connect-apple-health-to-claude-mcp?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=exp-20260808-hea55-claudemcp" rel="noopener noreferrer"&gt;Connect Apple Health to Claude via MCP&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>mcp</category>
      <category>apple</category>
      <category>ai</category>
    </item>
    <item>
      <title>Fix Apple Health export.xml Parse Errors: the iOS 16+ guide</title>
      <dc:creator>Philip D'Souza</dc:creator>
      <pubDate>Sat, 08 Aug 2026 02:48:00 +0000</pubDate>
      <link>https://dev.to/philipad/fix-apple-health-exportxml-parse-errors-the-ios-16-guide-37gb</link>
      <guid>https://dev.to/philipad/fix-apple-health-exportxml-parse-errors-the-ios-16-guide-37gb</guid>
      <description>&lt;p&gt;Since iOS 16 (HealthKit Export Version 12), Apple's &lt;code&gt;export.xml&lt;/code&gt; has shipped with malformed DTD declarations. The file includes incomplete &lt;code&gt;tags without matching&lt;/code&gt; declarations, so every standards-compliant XML parser fails before it reaches your data.&lt;/p&gt;

&lt;h2&gt;
  
  
  The error you see
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ATTLIST: no name for Attribute [68]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or in Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;xml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;etree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ElementTree&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;syntax&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;156&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;xmllint&lt;/code&gt;, R's &lt;code&gt;XML&lt;/code&gt; package, Go's &lt;code&gt;encoding/xml&lt;/code&gt;, they all fail on the same root cause. The file can be 1.7 GB or larger, and the DTD error sits in the first 200 lines. You never reach the actual health records.&lt;/p&gt;

&lt;h2&gt;
  
  
  Root cause
&lt;/h2&gt;

&lt;p&gt;Apple ships a malformed DTD fragment on large exports. It is not your parser, and it is not your data. The &lt;code&gt;RightEye EMPTY&lt;/code&gt; element and a handful of others are declared without their &lt;code&gt;ATTLIST&lt;/code&gt; companion, which violates the XML spec.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fixes that work
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;th&gt;Tools&lt;/th&gt;
&lt;th&gt;Works on &amp;gt;1.7GB&lt;/th&gt;
&lt;th&gt;Effort&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Strip the DOCTYPE&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;head&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pre-process with Python&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lxml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tolerant parser&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lxmlrecover&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dedicated conversion tool&lt;/td&gt;
&lt;td&gt;Health Export AI&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Fastest:&lt;/strong&gt; strip the DOCTYPE declaration entirely. The DTD is not needed to parse the HealthKit record elements, so removing it lets any parser proceed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Permanent:&lt;/strong&gt; skip &lt;code&gt;export.xml&lt;/code&gt; and read HealthKit directly via a native HealthKit export. That avoids the DTD bug and the multi-gigabyte file problem, and gives you clean JSON instead of a broken XML blob.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about AI agents?
&lt;/h2&gt;

&lt;p&gt;If you want Claude, Cursor, or ChatGPT to query your Apple Health data, feeding them a broken 1.7 GB &lt;code&gt;export.xml&lt;/code&gt; is the hard path. A native MCP bridge reads the on-device HealthKit cache directly, so the agent gets structured metrics (HRV, sleep, workouts, 190 types) without touching &lt;code&gt;export.xml&lt;/code&gt; at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is my export corrupted?&lt;/strong&gt; No. The health data is intact. Only the DTD preamble is malformed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will Apple fix it?&lt;/strong&gt; The bug has persisted across iOS 16, 17, 18, and 19. Do not wait.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I just delete the bad lines?&lt;/strong&gt; Yes, stripping the DOCTYPE block (roughly the first 200 lines) is the most reliable fix and loses zero data.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is a summary. The complete guide with code snippets and the full comparison table is on the original post: [Fix Apple Health export.xml Parse Errors, the Complete Guide](&lt;a href="https://dub.sh/oGKpzGL" rel="noopener noreferrer"&gt;https://dub.sh/oGKpzGL&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Best Apple Health MCP Servers Compared 2026: Zero-Dep vs DuckDB vs Health Auto Export</title>
      <dc:creator>Philip D'Souza</dc:creator>
      <pubDate>Thu, 06 Aug 2026 15:40:00 +0000</pubDate>
      <link>https://dev.to/philipad/best-apple-health-mcp-servers-compared-2026-zero-dep-vs-duckdb-vs-health-auto-export-21o9</link>
      <guid>https://dev.to/philipad/best-apple-health-mcp-servers-compared-2026-zero-dep-vs-duckdb-vs-health-auto-export-21o9</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on [healthexport.dev](&lt;a href="https://dub.sh/m4x3o6y" rel="noopener noreferrer"&gt;https://dub.sh/m4x3o6y&lt;/a&gt; Canonical link below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There are now four MCP servers that give AI agents access to Apple Health data. Here is how they compare on setup time, runtime, dependencies, and privacy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four servers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;health-export-mcp&lt;/strong&gt; is a zero-dependency Node.js server with a companion iOS app. The app auto-syncs 190 HealthKit metrics as clean JSON to iCloud. You point the MCP server at that folder. No Docker, no Python, no manual XML export. Setup is about 2 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;the-momentum&lt;/strong&gt; (244 GitHub stars) parses Apple's &lt;code&gt;export.xml&lt;/code&gt; into DuckDB and exposes NL-to-SQL tooling. It needs Docker or &lt;code&gt;uv&lt;/code&gt; plus Python plus DuckDB. Strong for raw SQL, but the original server is in maintenance mode now that the team pivoted to Open Wearables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Health Auto Export&lt;/strong&gt; (321 App Store ratings) runs a TCP bridge from a mobile app instead of stdio. Works, but TCP means port management and no stdio compat with most MCP clients out of the box.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;neiltron&lt;/strong&gt; (42k weekly npm downloads) is the newest. Same DuckDB paradigm as the-momentum but packaged as an npm module. Still needs the manual &lt;code&gt;export.xml&lt;/code&gt; export and transfer. 3 query tools, smaller community.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side-by-side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;health-export-mcp&lt;/th&gt;
&lt;th&gt;the-momentum&lt;/th&gt;
&lt;th&gt;Health Auto Export&lt;/th&gt;
&lt;th&gt;neiltron&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;Node.js (zero-dep)&lt;/td&gt;
&lt;td&gt;Python + Docker / uv&lt;/td&gt;
&lt;td&gt;Mobile app + TCP&lt;/td&gt;
&lt;td&gt;Node + DuckDB (npm)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dependencies&lt;/td&gt;
&lt;td&gt;None beyond Node&lt;/td&gt;
&lt;td&gt;Docker, Python, DuckDB&lt;/td&gt;
&lt;td&gt;Mobile app on iPhone&lt;/td&gt;
&lt;td&gt;DuckDB WASM via npm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data source&lt;/td&gt;
&lt;td&gt;Auto-synced JSON from iOS&lt;/td&gt;
&lt;td&gt;Manual export.xml to DuckDB&lt;/td&gt;
&lt;td&gt;App SQLite to TCP&lt;/td&gt;
&lt;td&gt;Manual export.xml to DuckDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Setup time&lt;/td&gt;
&lt;td&gt;~2 minutes&lt;/td&gt;
&lt;td&gt;~15 minutes&lt;/td&gt;
&lt;td&gt;~8 minutes&lt;/td&gt;
&lt;td&gt;~10 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data freshness&lt;/td&gt;
&lt;td&gt;Auto-sync (background)&lt;/td&gt;
&lt;td&gt;Manual re-export&lt;/td&gt;
&lt;td&gt;On-demand or scheduled&lt;/td&gt;
&lt;td&gt;Manual re-export&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP transport&lt;/td&gt;
&lt;td&gt;stdio&lt;/td&gt;
&lt;td&gt;stdio&lt;/td&gt;
&lt;td&gt;TCP socket&lt;/td&gt;
&lt;td&gt;stdio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tools exposed&lt;/td&gt;
&lt;td&gt;7 deterministic tools&lt;/td&gt;
&lt;td&gt;NL-to-SQL + DuckDB&lt;/td&gt;
&lt;td&gt;5 query tools&lt;/td&gt;
&lt;td&gt;3 query tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iOS companion app&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;On-device AI chat&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;License&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;Proprietary&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The honest take
&lt;/h2&gt;

&lt;p&gt;The DuckDB route is the right call if you already run DuckDB and want SQL over your data. For everyone else, the dependency cost is steep just to get your steps into Claude or Cursor. Two minutes and zero installs is a better default for the person who just wants to ask their agent about their sleep.&lt;/p&gt;

&lt;p&gt;All four run locally. None sends health data to a cloud. The practical difference is friction: one auto-syncs from your phone, the other three need a manual &lt;code&gt;export.xml&lt;/code&gt; export and transfer every time you want fresh data.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;How many Apple Health MCP servers are there in 2026?&lt;/strong&gt; Four, plus healthsync (Go/SQLite) which does not implement MCP natively but can be wrapped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which is easiest to set up?&lt;/strong&gt; health-export-mcp. Install the iOS app, grant HealthKit access, turn on iCloud sync, then &lt;code&gt;npx health-export-mcp&lt;/code&gt;. No Docker, no Python, no manual XML export.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which has zero dependencies?&lt;/strong&gt; Only health-export-mcp. The others need DuckDB (the-momentum, neiltron), Python/Docker (the-momentum), or a mobile app TCP setup (Health Auto Export).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does any server auto-sync?&lt;/strong&gt; Only health-export-mcp. The companion iOS app reads HealthKit on a schedule and writes fresh JSON. The other three require a manual re-export of &lt;code&gt;export.xml&lt;/code&gt; for fresh data.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is a syndicated summary. [Read the full comparison with the FAQ and the data-model breakdown on healthexport.dev](&lt;a href="https://dub.sh/m4x3o6y" rel="noopener noreferrer"&gt;https://dub.sh/m4x3o6y&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
