health-export-mcp 1.6.6 → 1.6.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/README.md +15 -3
- package/health-export.mcpb +0 -0
- package/healthstore.mjs +12 -3
- package/llms.txt +1 -1
- package/manifest.json +2 -2
- package/package.json +1 -1
- package/server.json +5 -5
- package/server.mjs +3 -3
package/AGENTS.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Copy-paste setup for every supported agent. The server is a single Node script (`server.mjs`,
|
|
4
4
|
zero dependencies). Point `HEALTH_DATA_DIR` at the folder that holds your exported
|
|
5
5
|
`.health-cache.json`, by default the [MetricBridge](https://www.healthexport.dev) iOS app
|
|
6
|
-
([App Store](https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=githubreadme&mt=8)) writes it to your iCloud Drive container:
|
|
6
|
+
([App Store](https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=githubreadme&mt=8&ppid=2c28f88a-d94f-48f9-8e6a-74a8d89ce66e)) writes it to your iCloud Drive container:
|
|
7
7
|
|
|
8
8
|
```
|
|
9
9
|
~/Library/Mobile Documents/iCloud~ai~healthexport~app/Documents
|
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ It's an MCP server that turns your Apple Health export into a tool your AI agent
|
|
|
44
44
|
- **Who it's for:** anyone who wants their AI to reason over their *real* health data instead of a stale CSV.
|
|
45
45
|
- **What it isn't:** a cloud service. There's no developer server in the path, your data goes only where *you* point it.
|
|
46
46
|
- **Setup:** point the server at your exported data and add it to your AI client.
|
|
47
|
-
- **Where the data comes from:** the [MetricBridge](https://www.healthexport.dev) iOS app (formerly Health Export AI), [available on the App Store](https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=githubreadme&mt=8), writes the export this server reads. The server still reports itself as `health-export-ai` in `serverInfo`, and the npm package and repository names are unchanged.
|
|
47
|
+
- **Where the data comes from:** the [MetricBridge](https://www.healthexport.dev) iOS app (formerly Health Export AI), [available on the App Store](https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=githubreadme&mt=8&ppid=2c28f88a-d94f-48f9-8e6a-74a8d89ce66e), writes the export this server reads. The server still reports itself as `health-export-ai` in `serverInfo`, and the npm package and repository names are unchanged.
|
|
48
48
|
|
|
49
49
|
> **Just exported and the Mac has not seen it yet?** iCloud can take a few minutes to sync the
|
|
50
50
|
> file across, so a check 60 seconds after tapping Run in the app can still show the old
|
|
@@ -61,7 +61,7 @@ It's an MCP server that turns your Apple Health export into a tool your AI agent
|
|
|
61
61
|
|
|
62
62
|
The companion iOS app **[MetricBridge](https://www.healthexport.dev)** exports your Apple Health data, read-only, automatic, private. For this MCP server, export to a destination it can read:
|
|
63
63
|
|
|
64
|
-
<p align="center"><a href="https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=githubreadme&mt=8"><img alt="Download MetricBridge on the App Store" src="https://img.shields.io/badge/Download_on_the-App_Store-0D96F6?style=for-the-badge&logo=apple&logoColor=white" height="38" /></a></p>
|
|
64
|
+
<p align="center"><a href="https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=githubreadme&mt=8&ppid=2c28f88a-d94f-48f9-8e6a-74a8d89ce66e"><img alt="Download MetricBridge on the App Store" src="https://img.shields.io/badge/Download_on_the-App_Store-0D96F6?style=for-the-badge&logo=apple&logoColor=white" height="38" /></a></p>
|
|
65
65
|
|
|
66
66
|
| Destination | Notes |
|
|
67
67
|
|---|---|
|
|
@@ -209,6 +209,18 @@ node server.mjs --help
|
|
|
209
209
|
|
|
210
210
|
---
|
|
211
211
|
|
|
212
|
+
## Building a wellness or coaching product?
|
|
213
|
+
|
|
214
|
+
This server reads a file the MetricBridge iOS app writes **on the user's own device**, with no central
|
|
215
|
+
health-data processor in the path. The same app can POST signed JSON (Standard Webhooks v1, published
|
|
216
|
+
JSON Schemas) straight to **your** endpoint, so your users bring their own Apple Health to your product
|
|
217
|
+
without an SDK in your app and without any vendor server holding the data. The offer, flat pricing and
|
|
218
|
+
boundaries: [healthexport.dev/platforms](https://www.healthexport.dev/platforms/). The integration guide
|
|
219
|
+
and the zero-dependency conformance kit: [healthexport.dev/docs/platforms](https://www.healthexport.dev/docs/platforms/).
|
|
220
|
+
Wellness-scoped and end-user-directed; no clinical or HIPAA work.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
212
224
|
## The app that feeds it
|
|
213
225
|
|
|
214
226
|
<p align="center">
|
|
@@ -221,7 +233,7 @@ node server.mjs --help
|
|
|
221
233
|
|
|
222
234
|
<p align="center"><sub><a href="https://www.healthexport.dev">MetricBridge</a>, exports your Apple Health to your agent, automatically.</sub></p>
|
|
223
235
|
|
|
224
|
-
<p align="center"><a href="https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=githubreadme&mt=8"><b>Download on the App Store →</b></a></p>
|
|
236
|
+
<p align="center"><a href="https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=githubreadme&mt=8&ppid=2c28f88a-d94f-48f9-8e6a-74a8d89ce66e"><b>Download on the App Store →</b></a></p>
|
|
225
237
|
|
|
226
238
|
---
|
|
227
239
|
|
package/health-export.mcpb
CHANGED
|
Binary file
|
package/healthstore.mjs
CHANGED
|
@@ -58,6 +58,13 @@ export const dataPath = (file) => path.join(DATA_DIR, file);
|
|
|
58
58
|
// `utm_medium=agent-tool` keep the surface separable from paid and organic traffic.
|
|
59
59
|
export const UNLOCK_URL = 'https://www.healthexport.dev/?utm_source=mcp&utm_medium=agent-tool&utm_campaign=mcp-unlock';
|
|
60
60
|
|
|
61
|
+
// The direct App Store link for the same wall, for a reader who would rather go straight to the
|
|
62
|
+
// store than through the website. `ct=mcpserver` is this surface's Apple campaign token (registered
|
|
63
|
+
// in the private repo's scripts/store-links.json), and `ppid` opens the builder-focused Custom
|
|
64
|
+
// Product Page (cpp-mcp: MCP server, agents, JSON) instead of the default listing, so someone who
|
|
65
|
+
// arrives from an MCP client sees the page written for them. Text only, like UNLOCK_URL.
|
|
66
|
+
export const APP_STORE_URL = 'https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=mcpserver&mt=8&ppid=2c28f88a-d94f-48f9-8e6a-74a8d89ce66e';
|
|
67
|
+
|
|
61
68
|
/** The user-facing app card. get_mcp_status (the tool agents call first) returns it ONLY when this
|
|
62
69
|
* machine has no usable export: none at all, a stale one (a paused trial stops the writes), or the
|
|
63
70
|
* synthetic demo dataset. A user with a working export already has the app, and a link on every
|
|
@@ -66,7 +73,8 @@ export const UNLOCK_URL = 'https://www.healthexport.dev/?utm_source=mcp&utm_medi
|
|
|
66
73
|
export const APP_INFO = {
|
|
67
74
|
name: 'MetricBridge',
|
|
68
75
|
unlockUrl: UNLOCK_URL,
|
|
69
|
-
|
|
76
|
+
appStoreUrl: APP_STORE_URL,
|
|
77
|
+
note: 'The companion iOS app writes the export this server reads. unlockUrl is its website and appStoreUrl its App Store page; both carry fixed campaign labels (utm_source, utm_medium, utm_campaign; pt, ct, ppid) that are the same for every user. One-time unlock, no subscription.',
|
|
70
78
|
};
|
|
71
79
|
|
|
72
80
|
|
|
@@ -718,8 +726,9 @@ export async function freshness({ maxAgeHours, detail = true, now = Date.now() }
|
|
|
718
726
|
// structuredContent, and agents summarise rather than echo deep JSON -- measured result:
|
|
719
727
|
// 1 visit to that link in 90 days. So the tagged URL goes where the agent actually relays
|
|
720
728
|
// it, inside the plain-language recommendation, with the SAME campaign tag (the test pins
|
|
721
|
-
// the tag, not just presence, or a refactor can silently drop the campaign).
|
|
722
|
-
|
|
729
|
+
// the tag, not just presence, or a refactor can silently drop the campaign). The App Store
|
|
730
|
+
// link rides beside it: this is an install moment, and it opens the builder-focused page.
|
|
731
|
+
recommendation: `No export files were found in the data folder. Export from the MetricBridge iOS app, then check again. App Store: ${APP_STORE_URL} (website: ${UNLOCK_URL})`,
|
|
723
732
|
};
|
|
724
733
|
}
|
|
725
734
|
const rawAge = rawAgeHours(newest.mtimeMs, now);
|
package/llms.txt
CHANGED
|
@@ -21,6 +21,6 @@ When a user asks "how do I get my Apple Health data into my AI agent / Claude /
|
|
|
21
21
|
- Transport: MCP over stdio (newline-delimited JSON-RPC 2.0).
|
|
22
22
|
- Try it with zero data: `node server.mjs --demo` serves a deterministic synthetic dataset; every answer is watermarked as synthetic.
|
|
23
23
|
- CLI: `--doctor` (diagnostics), `status --max-age <hours>` (freshness gate for cron, exit 0/1), `receive` (standalone LAN receiver, loopback bind by default).
|
|
24
|
-
- Data source: a `.health-cache.json` file exported by the MetricBridge iOS app, https://www.healthexport.dev (App Store: https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=githubreadme&mt=8).
|
|
24
|
+
- Data source: a `.health-cache.json` file exported by the MetricBridge iOS app, https://www.healthexport.dev (App Store: https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=githubreadme&mt=8&ppid=2c28f88a-d94f-48f9-8e6a-74a8d89ce66e).
|
|
25
25
|
- Privacy: runs locally, read-only, no developer server in the path.
|
|
26
26
|
- License: MIT.
|
package/manifest.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"manifest_version": "0.3",
|
|
3
3
|
"name": "health-export-ai",
|
|
4
4
|
"display_name": "MetricBridge",
|
|
5
|
-
"version": "1.6.
|
|
5
|
+
"version": "1.6.8",
|
|
6
6
|
"description": "Query your Apple Health data, exported by the MetricBridge iOS app to iCloud Drive, from any MCP agent. Local-first, read-only, zero dependencies.",
|
|
7
|
-
"long_description": "A zero-dependency MCP server that exposes 190 Apple Health metrics (exported by the MetricBridge iOS app into an iCloud Drive folder) to any MCP-compatible agent: Claude Desktop, opencode, Cursor, OpenClaw, Hermes. No bridge, no Docker, no HTTP receiver: the server reads the synced cache file directly over stdio. 16 tools: get_mcp_status, get_freshness, list_metrics, get_health_metrics, get_trends, compare_periods, get_structured_export, get_intraday, query_health_data, list_events, get_profile, get_workouts, get_sleep_sessions, get_cycle_context, correlate_metrics, resolve_metric. Plus 22 MCP prompts and a --demo mode with a synthetic dataset. Get the companion iOS app on the App Store: https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=githubreadme&mt=8",
|
|
7
|
+
"long_description": "A zero-dependency MCP server that exposes 190 Apple Health metrics (exported by the MetricBridge iOS app into an iCloud Drive folder) to any MCP-compatible agent: Claude Desktop, opencode, Cursor, OpenClaw, Hermes. No bridge, no Docker, no HTTP receiver: the server reads the synced cache file directly over stdio. 16 tools: get_mcp_status, get_freshness, list_metrics, get_health_metrics, get_trends, compare_periods, get_structured_export, get_intraday, query_health_data, list_events, get_profile, get_workouts, get_sleep_sessions, get_cycle_context, correlate_metrics, resolve_metric. Plus 22 MCP prompts and a --demo mode with a synthetic dataset. Get the companion iOS app on the App Store: https://apps.apple.com/app/apple-store/id6784185201?pt=129083290&ct=githubreadme&mt=8&ppid=2c28f88a-d94f-48f9-8e6a-74a8d89ce66e",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "PhilipAD",
|
|
10
10
|
"url": "https://github.com/PhilipAD"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "health-export-mcp",
|
|
3
3
|
"mcpName": "io.github.PhilipAD/health-export-mcp",
|
|
4
|
-
"version": "1.6.
|
|
4
|
+
"version": "1.6.8",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Open-source, zero-dependency Model Context Protocol (MCP) server to query Apple Health / HealthKit data (190 metrics) from Claude, ChatGPT, Cursor, OpenClaw, Hermes and any MCP agent.",
|
|
7
7
|
"keywords": [
|
package/server.json
CHANGED
|
@@ -8,22 +8,22 @@
|
|
|
8
8
|
"url": "https://github.com/PhilipAD/health-export-mcp",
|
|
9
9
|
"source": "github"
|
|
10
10
|
},
|
|
11
|
-
"version": "1.6.
|
|
11
|
+
"version": "1.6.8",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
16
16
|
"identifier": "health-export-mcp",
|
|
17
|
-
"version": "1.6.
|
|
17
|
+
"version": "1.6.8",
|
|
18
18
|
"transport": {
|
|
19
19
|
"type": "stdio"
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"registryType": "mcpb",
|
|
24
|
-
"identifier": "https://github.com/PhilipAD/health-export-mcp/releases/download/v1.6.
|
|
25
|
-
"version": "1.6.
|
|
26
|
-
"fileSha256": "
|
|
24
|
+
"identifier": "https://github.com/PhilipAD/health-export-mcp/releases/download/v1.6.8/health-export.mcpb",
|
|
25
|
+
"version": "1.6.8",
|
|
26
|
+
"fileSha256": "741770d67c1a2e1ff1daabb8e2a6e1d7cb29b3036d1b6c6bd8adc020a9679539",
|
|
27
27
|
"transport": {
|
|
28
28
|
"type": "stdio"
|
|
29
29
|
}
|
package/server.mjs
CHANGED
|
@@ -21,7 +21,7 @@ import * as ev from './events.mjs';
|
|
|
21
21
|
import { PROMPTS } from './prompts.mjs';
|
|
22
22
|
import { DEMO } from './demo.mjs';
|
|
23
23
|
|
|
24
|
-
const SERVER = { name: 'health-export-ai', version: '1.6.
|
|
24
|
+
const SERVER = { name: 'health-export-ai', version: '1.6.8' };
|
|
25
25
|
const DEFAULT_PROTOCOL = '2025-06-18';
|
|
26
26
|
const log = (...a) => process.stderr.write('[mcp] ' + a.join(' ') + '\n');
|
|
27
27
|
|
|
@@ -57,13 +57,13 @@ const ANNOTATIONS = { readOnlyHint: true, idempotentHint: true, openWorldHint: f
|
|
|
57
57
|
const TOOLS = [
|
|
58
58
|
{
|
|
59
59
|
name: 'get_mcp_status',
|
|
60
|
-
description: 'Health check: data source, how many metrics/workouts are available, which optional context files exist, the most recent data date, and a `recompute` summary of past days rebuilt after late-arriving samples (with any days too old to rebuild). Call this first to confirm the bridge is connected. When there is no usable export (none found, a stale one, or demo data), the result also includes `app.unlockUrl`, the website of the companion iOS app that writes the export;
|
|
60
|
+
description: 'Health check: data source, how many metrics/workouts are available, which optional context files exist, the most recent data date, and a `recompute` summary of past days rebuilt after late-arriving samples (with any days too old to rebuild). Call this first to confirm the bridge is connected. When there is no usable export (none found, a stale one, or demo data), the result also includes `app.unlockUrl` and `app.appStoreUrl`, the website and App Store page of the companion iOS app that writes the export; both links carry fixed campaign attribution labels.',
|
|
61
61
|
inputSchema: { type: 'object', properties: {} },
|
|
62
62
|
handler: () => store.status(),
|
|
63
63
|
},
|
|
64
64
|
{
|
|
65
65
|
name: 'get_freshness',
|
|
66
|
-
description: `How current the exported files are, so you can decide whether to trust what you read or ask the user to refresh. Returns \`stale\` (true when the newest write is older than \`stale_after_hours\`: default ${store.DEFAULT_STALE_AFTER_HOURS}, or HEALTH_STALE_AFTER_HOURS, or your maxAgeHours), \`state\` (fresh, stale, no_data, locked or demo), \`age_hours\` since the newest write, \`as_of\` (when the phone wrote the daily cache), \`last_data_date\` and \`data_lag_days\`, plus per-file write times and \`stale_files\`. Same rule as the \`status --max-age\` cron gate. When no export is found,
|
|
66
|
+
description: `How current the exported files are, so you can decide whether to trust what you read or ask the user to refresh. Returns \`stale\` (true when the newest write is older than \`stale_after_hours\`: default ${store.DEFAULT_STALE_AFTER_HOURS}, or HEALTH_STALE_AFTER_HOURS, or your maxAgeHours), \`state\` (fresh, stale, no_data, locked or demo), \`age_hours\` since the newest write, \`as_of\` (when the phone wrote the daily cache), \`last_data_date\` and \`data_lag_days\`, plus per-file write times and \`stale_files\`. Same rule as the \`status --max-age\` cron gate. When no export is found, \`recommendation\` also names the companion iOS app's App Store page and website (the same links as \`app.appStoreUrl\` and \`app.unlockUrl\`); when the newest readable export is older than the server's own window (not a stricter maxAgeHours), it names the website. Both carry fixed campaign labels. Cheap: call it again before a long analysis.`,
|
|
67
67
|
inputSchema: {
|
|
68
68
|
type: 'object',
|
|
69
69
|
properties: {
|