# MetricBridge Apple Health (mcpb · health-export.mcpb)

Ask your agent about your own Apple Health data: 194 metrics, 22 tools, local, 0 deps.

- Trust score: 51/100 (low)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- mcpb · `health-export.mcpb`: 51/100 (this document), [markdown](https://verifymcp.io/servers/philipad-health-export-mcp/health-export.md), [page](https://verifymcp.io/servers/philipad-health-export-mcp/health-export)
- npm · `health-export-mcp`: 96/100, [markdown](https://verifymcp.io/servers/philipad-health-export-mcp/health-export-mcp.md), [page](https://verifymcp.io/servers/philipad-health-export-mcp/health-export-mcp)

## Channel facts

- Registry: `mcpb`
- Package: `https://github.com/PhilipAD/health-export-mcp/releases/download/v1.10.2/health-export.mcpb`
- Version: `1.10.2`
- Transport: `stdio`
- SHA-256: `ed575969205de53d77611fd674ced59bc48023e5e34d6230f120bec46e1e0b94`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Supply Chain Security**: 0/100
  - No malware scan is available for this kind of package: the supply-chain vendors we use do not cover it. This is a permanent gap in our coverage, not a finding about the package.
  - Known CVEs could not be checked: we found no dependency list to check in this bundle: either it runs a compiled binary, whose bundled manifests we do not read, or none of the package.json, requirements.txt, pyproject.toml or uv.lock files it ships for its runtime declares a dependency we can read (a requirements.txt that only points at a setup.py project, a local path, or a nested requirements file we cannot follow counts as none).
  - Install-script risk not yet assessed.
  - Dependency health could not be checked: we found no dependency list to check in this bundle: either it runs a compiled binary, whose bundled manifests we do not read, or none of the package.json, requirements.txt, pyproject.toml or uv.lock files it ships for its runtime declares a dependency we can read (a requirements.txt that only points at a setup.py project, a local path, or a nested requirements file we cannot follow counts as none).
- **Provenance & Transparency**: 48/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 1 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 78/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 4738 tokens (~215/item across 22 items; 22 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 73/100
  - Stability observed for 22 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 95/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 86% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 23 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

**Unverified: 1 category.** A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### How do I install the MetricBridge Apple Health MCP server?

MetricBridge Apple Health ships as an MCPB bundle, a single file you download and open in an MCP host that supports MCPB bundles, such as Claude Desktop. The host reads the launch command from the bundle's own manifest, so there is no command to copy. Before opening it, check the file's SHA-256 matches the one the MCP registry declares for it, ed575969205de53d77611fd674ced59bc48023e5e34d6230f120bec46e1e0b94; the commands to do that are on this page. If it does not match, do not open it.

- Download bundle: `https://github.com/PhilipAD/health-export-mcp/releases/download/v1.10.2/health-export.mcpb`
- SHA-256: `ed575969205de53d77611fd674ced59bc48023e5e34d6230f120bec46e1e0b94`

### Verify on macOS / Linux

```bash
echo "ed575969205de53d77611fd674ced59bc48023e5e34d6230f120bec46e1e0b94  health-export.mcpb" | shasum -a 256 -c
```

### Verify on Windows (PowerShell)

```powershell
(Get-FileHash -Algorithm SHA256 .\health-export.mcpb).Hash -eq "ed575969205de53d77611fd674ced59bc48023e5e34d6230f120bec46e1e0b94"
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-04 (score 51, 0)

- [security regression] Provenance: unverified → fail

### 2026-11-03 (score 51, +1)

- [security regression] Provenance: fail → unverified
- [functional] Package version: 1.10.1 → 1.10.2

### 2026-11-02 (score 50, 0)

- [functional] Package version: 1.9.0 → 1.10.1
- [functional] Package version: 1.9.0 → 1.10.0

### 2026-11-01 (score 50, +1)

- [security regression] Stability: 0.57 → unverified
- [security regression] Tool safety: pass → unverified
- [functional regression] Schema quality: 3803 → 4407
- [functional regression] Schema quality: 100 → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Capabilities: pass → unverified
- [functional] Package version: 1.8.0 → 1.9.0

### 2026-10-30 (score 49, +1)

No change was recorded against any check on this day. Stability & Change Management went from 50 to 53. That category is still filling its 30-day observation window: 15 days of observed history at the previous scan, 16 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-28 (score 48, +1)

- [functional regression] Schema quality: 177 → 211
- [functional] Destructive annotations: pass → 100
- [functional] Package version: 1.7.3 → 1.8.0

### 2026-10-27 (score 47, 0)

- [functional] Package version: 1.7.1 → 1.7.3
- [functional] Package version: 1.7.1 → 1.7.2

### 2026-10-26 (score 47, 0)

- [functional] Package version: 1.7.0 → 1.7.1

## MCP tools (22)

### `get_mcp_status` (~164 tokens)

Health check: data source, how many metrics/workouts are available, which optional context files exist, the most recent data date, a compact `freshness` block (its `state` is stale_copy, with a `stale_copy` list, when this machine holds an older copy of the export than the phone last wrote), and a `recompute` summary of past days rebuilt after late-arriving samples (with any days too old to rebuild; `supported: null` when the cache cannot tell). Call this first to confirm the bridge is connected. 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.

### `get_freshness` (~437 tokens)

How current the exported files are, so you can decide whether to trust what you read or ask the user to refresh. `stale` is judged on the core files (the daily cache and health-sessions.json), never on the hourly intraday file: true when their newest write is older than `stale_after_hours` (default 26, or HEALTH_STALE_AFTER_HOURS, or your maxAgeHours), or when this machine holds a stale copy. `state` is fresh, stale, stale_copy, no_data, locked or demo. stale_copy means the phone's manifest (.health-manifest.json) or iCloud says the phone wrote a newer version of a core file than the one on this machine (`stale_copy` lists each file with localWrittenAt, phoneWrittenAt and reason); relay the recommendation, which says how to make iCloud Drive download it. Also returns `age_hours`, `as_of` (when the phone wrote the daily cache), `last_data_date`, `data_lag_days`, per-file write times with each file's match against the manifest, `stale_files`, `manifest_behind` (the manifest lags the data, not stale), `sessions_last_night` (present or absent; without a manifest, advisory only, people skip nights) and, on a Mac, an advisory `icloud` status per core file. 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.

Input parameters:

- `maxAgeHours` (number): Treat the data as stale when the newest write is older than this many hours (greater than 0, at most 8760). Default 26, or HEALTH_STALE_AFTER_HOURS when set.

### `list_metrics` (~34 tokens)

List every available Apple Health metric with its unit, day count, and date range. Use this to discover metric names before querying.

### `get_health_metrics` (~441 tokens)

Get values for a metric (or all metrics) over an optional date range, with an aggregate (avg/sum/min/max/latest). The core data-retrieval tool. Every result carries a `coverage` block giving the metric's real firstDate/lastDate/days: check it before trusting a long window, and note that `aggregate` is always computed over the full range even when `points` are rolled up. Single-metric answers also list any logged point events inside the window as segmentBoundaries. For blood_pressure_systolic or blood_pressure_diastolic at day granularity, the individual readings behind the daily mean are attached as `readings` [{t, systolic, diastolic, source, manual}] when the app exported them (health-readings.json), the most recent 150 in range, with `readingsOmitted` counting the rest. A day the app rebuilt after samples arrived late (or were deleted) carries `recomputed_at`, and a metric with rebuilt or possibly stale past days carries a `recompute` block (backfilled_days, recomputed_at, capped); untouched days carry neither.

Input parameters:

- `aggregation` (string)
- `end` (string): YYYY-MM-DD
- `filterDays` (object): Restrict to days covered by matching logged events (health-events.json and health-events-agent.json): endDate ranges cover every day inclusive, point events cover their single day, negate:true keeps…
- `granularity` (string): Roll daily values up before returning them. 'auto' (default) picks the finest granularity that fits the response budget, so a multi-year range returns monthly points instead of thousands of daily one…
- `limit` (integer): Maximum data points to return (default 365, max 3000). The server rolls up rather than truncating.
- `metric` (string): Metric name, e.g. step_count, heart_rate, sleep_analysis. Omit for all.
- `start` (string): YYYY-MM-DD

### `get_trends` (~164 tokens)

Compare the most recent N-day window against the prior N days for a metric: change, percent change and direction (up/down/flat). Also returns `daysAvailable` and `windowSatisfied`: if windowSatisfied is false the file does not hold enough history for the window you asked for, and the comparison is over less data than requested. Logged point events inside the compared span are listed as segmentBoundaries.

Input parameters:

- `excludeTravelDays` (boolean): Drop days on which a timezone change landed (health-days.json): those days were not 24 hours long, so their totals are stretched or shortened by the clock. The answer reports how many days were exclu…
- `metric` (string, required)
- `window` (integer): days per window (default 7)

### `compare_periods` (~224 tokens)

Compare a metric between two arbitrary date periods (A vs B): each aggregate plus the change and percent change. Pass periodA/periodB explicitly, or pass anchor {eventId, days} to build both periods around a logged event (the before/after question, with the event day excluded from both sides).

Input parameters:

- `anchor` (object): Build both periods around a logged event instead of passing dates: periodA is the {days} days before the event date, periodB the {days} days after, the event day itself excluded from both. Get event…
- `excludeTravelDays` (boolean): Drop days on which a timezone change landed (health-days.json): those days were not 24 hours long, so their totals are stretched or shortened by the clock. The answer reports how many days were exclu…
- `metric` (string, required)
- `periodA` (object)
- `periodB` (object)

### `get_structured_export` (~193 tokens)

Return clean structured JSON for the chosen metrics/date range. Paginated: the result carries `nextCursor` when more metrics remain; pass it back as `cursor` for the next page. Prefer naming the metrics you need and a date range; calling it bare over a full history is a lot of data.

Input parameters:

- `cursor` (string): Opaque cursor from a previous call's nextCursor.
- `end` (string): YYYY-MM-DD
- `granularity` (string): Roll daily values up before returning them. 'auto' (default) picks the finest granularity that fits the response budget, so a multi-year range returns monthly points instead of thousands of daily one…
- `limit` (integer): Maximum data points to return (default 365, max 3000). The server rolls up rather than truncating.
- `metrics` (array)
- `start` (string): YYYY-MM-DD

### `get_intraday` (~204 tokens)

The current hour-by-hour window from the iOS app's HOURLY automations (health-intraday.json, app 1.4+): each metric's hourly points (t, v = the hour's value) plus its latest value. The window covers a 48-hour span, yesterday 00:00 local to now, and the file is REPLACED on every run, so this is a live recent view, not history; use get_health_metrics for day-level questions. Discrete metrics (heart rate, SpO2, respiratory rate, HRV, resting heart rate) carry the hour's Min and Max beside v (the hour's mean) when the app version writes them; older exports cover today only and have no Min/Max. Returns available:false with setup guidance when no hourly automation has delivered yet.

Input parameters:

- `metric` (string): Metric name to filter, e.g. heart_rate. Omit for every metric in the window.

### `query_health_data` (~60 tokens)

Natural-language convenience: pass a question and get routed structured results. Prefer the specific tools above when you can, and call list_metrics first to see how much history exists, since this tool answers over whatever the file holds.

Input parameters:

- `question` (string, required)

### `list_events` (~190 tokens)

Logged context events: medication starts, habit changes, doctor visits, life events, shift blocks, episodes, travel, and any type a newer app adds. Merges the app's health-events.json with health-events-agent.json (events logged with add_event); every event carries source "app" or "agent". Optional {type, tag, start, end} filters; a range event matches a window it overlaps. Sorted ascending by date. Returns available:false when neither file exists; absence means nothing was logged or exported, not that nothing happened.

Input parameters:

- `end` (string): YYYY-MM-DD
- `start` (string): YYYY-MM-DD
- `tag` (string): Match events carrying this tag.
- `type` (string): Event type, e.g. medication, habit, visit, life, shift, episode, travel, other. Unknown types pass through and can be filtered by their stored string.

### `add_event` (~359 tokens)

Log a context event the user tells you about (a medication start, a habit change, a visit, a trip) so later analysis can segment around it. Writes ONLY health-events-agent.json in the export folder, never Apple Health and never a file the iOS app writes; the app shows these events read-only. Returns the stored event with its id (starting "agent-"). Idempotent: repeating a call with the same clientEventId (or, without one, the same date, type, title and endDate) returns the event already logged instead of adding a duplicate. Ask the user before logging anything they did not state. Refused in demo mode, when the folder is not writable, and on an encrypted export without HEALTH_EXPORT_PASSPHRASE (the file is sealed like the rest of the export when the passphrase is set).

Input parameters:

- `clientEventId` (string): Optional idempotency key: the same key never logs a second event.
- `date` (string, required): Local day the event happened or started, YYYY-MM-DD.
- `endDate` (string): Last day of a range event (inclusive), YYYY-MM-DD, not before date. Omit for a point event.
- `note` (string): Optional longer note, at most 2000 characters.
- `tags` (array): Optional tags for filtering, e.g. ["magnesium"]. At most 20.
- `title` (string, required): Short description, e.g. "Started magnesium 300 mg". At most 200 characters.
- `type` (string, required): Event type: medication, habit, visit, life, shift, episode, travel or other. Range types (shift, travel, episode) usually carry an endDate.

### `remove_event` (~97 tokens)

Remove an event that was logged with add_event (id starting "agent-", source "agent" in list_events) from health-events-agent.json. Events logged in the iOS app are refused: they are edited in the app. Removing an id that is already gone changes nothing and says so. Refused in demo mode and when the folder is not writable.

Input parameters:

- `id` (string, required): The agent event id from list_events or add_event.

### `get_profile` (~63 tokens)

The context fields the user explicitly opted in to sharing (health-profile.json): conditions, medications, goals, allergies, notes. Returns the fields plus a presentFields list. An absent field was withheld by the user or never enabled; absence must never be read as "none".

### `get_check_ins` (~144 tokens)

Morning check-ins the user chose to share (health-check-ins.json): per day a self-rated feeling (1 rough to 5 great), an optional note, an intention for the day and whether it happened (answered the next morning). Optional {start, end} filters. Returns the rows plus a summary (rated, averageFeeling, intentionsAnswered, intentionsMet). Opt-in in the iOS app and off by default, so available:false is the usual answer and means not shared, never "felt nothing". A self-rating is the person's own words, not a measurement.

Input parameters:

- `end` (string): YYYY-MM-DD
- `start` (string): YYYY-MM-DD

### `get_workouts` (~207 tokens)

Query the workouts cache with {activityType (a name like Running, or a raw HealthKit id like 37), start, end} filters and pagination ({limit} default 50 max 200, {cursor} from a previous nextCursor). Records are returned exactly as stored, including the newer optional keys (avgHeartRate, maxHeartRate, running dynamics, cycling power, intervals, hasRoute) when the app exported them; older caches simply lack those keys and nothing is fabricated. Also returns summary {count, byActivityType} over everything that matched.

Input parameters:

- `activityType` (string): Activity name (e.g. Running) or raw HealthKit activity id (e.g. 37).
- `cursor` (string): Opaque cursor from a previous call's nextCursor.
- `end` (string): YYYY-MM-DD
- `limit` (integer): Workouts per page (default 50, max 200).
- `start` (string): YYYY-MM-DD

### `get_sleep_sessions` (~192 tokens)

Clustered sleep sessions from health-sessions.json with {start, end, day} filters. Sessions are attributed to the WAKING day, matching the daily cache's sleep_analysis, so the two surfaces never disagree; a split night appears as separate sessions with the same day. Duplicate copies of one night left by older app versions (sharing an end time with, or lying inside, a longer session on the same day) are collapsed to the longer one and counted in `collapsedDuplicates`. A session with manualInBed:true was built from an In Bed entry typed into the Health app with no asleep sample. Timestamps carry the local UTC offset at the time of the sample.

Input parameters:

- `day` (string): A single waking day, YYYY-MM-DD.
- `end` (string): Last waking day (inclusive), YYYY-MM-DD.
- `start` (string): First waking day (inclusive), YYYY-MM-DD.

### `get_strength_log` (~259 tokens)

The strength log the user keeps in the MetricBridge app (health-strength.json, opt-in, off by default): each session with its exercises and every set as entered (reps, kg, warmup or working, RPE), plus volumeKg, workingSets and an Epley bestEstimateKg per exercise, all-time records per exercise, and the routines the user saved (their own templates). Filters: {exercise (exact name, case-insensitive, e.g. "Back squat"), start, end (local days, inclusive)}. Sessions come oldest first; above 150 matches the most recent 150 are listed and `sessionsOmitted` counts the rest. An unknown exercise returns count 0 with `knownExercises`. Logged by hand, never read from Apple Health; when the file is missing the answer is available:false, which means the user has not switched the export on, not that they do not train.

Input parameters:

- `end` (string): Last day (inclusive), YYYY-MM-DD.
- `exercise` (string): One exercise, by the exact name in the log (case-insensitive), e.g. Back squat. Omit for every exercise.
- `start` (string): First day (inclusive), YYYY-MM-DD.

### `get_lab_results` (~331 tokens)

The user's lab results from Apple Health Records (health-labs.json), exported only when they switched on Lab results > Include in exports in the MetricBridge iOS app, and only into a picked folder (never iCloud Drive). Off by default. Each test (LOINC code when the lab sent one, name, unit) lists its results oldest first, with the value, date, institution and the lab's own reference range, all exactly as reported. Nothing is flagged, graded or interpreted: do not call a result normal or abnormal, and never convert between units (a test in two units is listed once per unit, splitByUnit: true). Filters: {test (case-insensitive part of the name, e.g. ldl), loinc (exact code, e.g. 13457-7), start, end (local days, inclusive)}. Above 400 matching results the newest 400 are returned with `resultsOmitted`. No match returns count 0 with `knownTests`. When the file is missing the answer is available:false, which means the user has not exported lab results, not that they have none.

Input parameters:

- `end` (string): Last result day (inclusive), YYYY-MM-DD.
- `loinc` (string): Exact LOINC code, e.g. 13457-7. Omit for every test.
- `start` (string): First result day (inclusive), YYYY-MM-DD.
- `test` (string): Part of a test name, case-insensitive, e.g. ldl or vitamin d. Omit for every test.

### `list_tags` (~190 tokens)

Tags the user logged in the iOS app (health-tags.json): lifestyle tags such as Alcohol or Sauna, and supplements such as Creatine or Magnesium, by name only and never an amount. Optional {kind: all | supplement | lifestyle, start, end}. Returns one row per tag (kind, days logged, firstDay, lastDay, most logged first) and the tag names per day. Tag export is opt-in in the app and off by default, so available:false is the usual answer and means the file was not exported, not that nothing was tagged. Treat any difference after tagged days as an association in this person's own data, never as evidence that a supplement works.

Input parameters:

- `end` (string): YYYY-MM-DD
- `kind` (string): Which tags: 'all' (default), 'supplement' or 'lifestyle'.
- `start` (string): YYYY-MM-DD

### `get_cycle_context` (~100 tokens)

Cycle context derived from user-logged period starts (health-cycles.json): day-in-cycle and a coarse phase label (follicular from day 1 to the observed midpoint of that cycle, luteal for the remainder). Derived from logged periods only, never predictive, and no ovulation estimate is made. Optional {date} for a single day; default returns per-day context for the last cycle.

Input parameters:

- `date` (string): YYYY-MM-DD

### `correlate_metrics` (~175 tokens)

Pearson correlation between two metrics' daily values: {metricA, metricB, lag (0 to 3, default 0), start, end}. lag pairs metricA on day d with metricB on day d+lag, so lag 1 compares against the FOLLOWING day. Returns alignedPairs, r (withheld below 10 aligned pairs), and both means. The answer always carries the association-not-causation caveat; treat every r as alignment in this file, not mechanism.

Input parameters:

- `end` (string): YYYY-MM-DD
- `lag` (integer): 0 to 3 days. lag 1 pairs metricA on day d with metricB on the following day.
- `metricA` (string, required)
- `metricB` (string, required)
- `start` (string): YYYY-MM-DD

### `resolve_metric` (~360 tokens)

Look a metric name up in the canonical naming and unit table. Accepts the export's own name (step_count), a HealthKit identifier (StepCount, HKQuantityTypeIdentifierStepCount), a display title (Step Count) or a common alias (steps, hrv, spo2, weight) and returns the canonical metric, its unit (percentages are 0 to 1 fractions), the unit variants other apps use with the exact formula into the canonical unit, and whether this export holds it. Pass {value, unit} to convert one value, e.g. 180 lb to kg. A word naming several metrics (distance, calories) comes back ambiguous with candidates, and a different measure (RMSSD vs the SDNN that Apple Health stores) is refused with the reason: nothing is guessed. get_health_metrics, get_trends, compare_periods, get_structured_export and correlate_metrics accept the same aliases and report `resolvedFrom` when they used one; other tools take the export's own names. The export holds one value per metric per day, merged across sources by Apple Health, so this tool states honestly whether per-source disagreement can be seen in the file (exports that record per-source attribution carry `src`/`by` and a `sources` block; others report it as not available) rather than inventing it.

Input parameters:

- `name` (string, required): Any spelling of a metric, e.g. steps, StepCount, Body Weight, VO2 max.
- `unit` (string): Unit of value, e.g. lb, mmol/L, degF, km, %. Unknown units are refused, never guessed.
- `value` (number): Optional value to convert into the canonical unit. Pass with unit.

## Diagnostics

Captured diagnostic sections: Provenance. The full working is on the page: https://verifymcp.io/servers/philipad-health-export-mcp/health-export#diagnostics

## Score history

- 2026-11-05: 51
- 2026-11-04: 51
- 2026-11-03: 51
- 2026-11-02: 50
- 2026-11-01: 50
- 2026-10-31: 49
- 2026-10-30: 49
- 2026-10-29: 48
- 2026-10-28: 48
- 2026-10-27: 47
- 2026-10-26: 47
- 2026-10-25: 47
- 2026-10-24: 46
- 2026-10-23: 46
- 2026-10-22: 45
- 2026-10-21: 45
- 2026-10-20: 44
- 2026-10-19: 44
- 2026-10-18: 43
- 2026-10-17: 43
- 2026-10-16: 42
- 2026-10-15: 42
- 2026-10-14: 42
- 2026-10-13: 10
- 2026-10-12: 10

## Common questions

### What is the MetricBridge Apple Health MCP server?

MetricBridge Apple Health is an MCP server listed in the public MCP registry as io.github.PhilipAD/health-export-mcp. Ask your agent about your own Apple Health data: 194 metrics, 22 tools, local, 0 deps. This page covers its MCPB bundle (https://github.com/PhilipAD/health-export-mcp/releases/download/v1.10.2/health-export.mcpb).

### Is the MetricBridge Apple Health MCP server safe to use?

MetricBridge Apple Health scores 51 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the MetricBridge Apple Health MCP server expose?

MetricBridge Apple Health exposes 22 tools: get_mcp_status, get_freshness, list_metrics, get_health_metrics, get_trends, and 17 more. Their descriptions and schemas cost roughly 4,588 tokens of context every time the server is loaded.

### What licence is the MetricBridge Apple Health MCP server under?

MetricBridge Apple Health declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- Repository: https://github.com/PhilipAD/health-export-mcp
- Website: https://www.healthexport.dev/mcp/
- Changelog RSS feed: https://verifymcp.io/servers/philipad-health-export-mcp/health-export.xml
- Changelog JSON feed: https://verifymcp.io/servers/philipad-health-export-mcp/health-export.json
- HTML version of this page: https://verifymcp.io/servers/philipad-health-export-mcp/health-export
