# io.github.partymola/google-health-mcp (pypi · google-health-mcp)

MCP server for the Google Health API, with a local SQLite cache and trend analysis.

- Trust score: 62/100 (medium)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-20

## Components

- pypi · `google-health-mcp`: 62/100 (this document), [markdown](https://verifymcp.io/servers/partymola-google-health-mcp/google-health-mcp.md), [page](https://verifymcp.io/servers/partymola-google-health-mcp/google-health-mcp)

## Channel facts

- Registry: `pypi`
- Package: `google-health-mcp`
- Version: `1.1.0`
- Transport: `stdio`

## 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-08-20.

- **Supply Chain Security**: 100/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs setuptools.build_meta at install time, a recognised native-build step with no shell scripting around it.
  - 2 of 30 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 32/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - License check failed: no license is declared.
  - Actively maintained (last published 0 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 66/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 4184 tokens (~220/item across 19 items; 19 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 71/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (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

### Claude

```bash
claude mcp add partymola-google-health-mcp -- uvx google-health-mcp
```

### Codex

```bash
codex mcp add partymola-google-health-mcp -- uvx google-health-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "partymola-google-health-mcp": {
      "type": "local",
      "command": [
        "uvx",
        "google-health-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add partymola-google-health-mcp --command uvx --arg google-health-mcp
```

### Hermes

```yaml
mcp_servers:
  partymola-google-health-mcp:
    command: "uvx"
    args: ["google-health-mcp"]
```

### Other

```json
{
  "mcpServers": {
    "partymola-google-health-mcp": {
      "command": "uvx",
      "args": [
        "google-health-mcp"
      ]
    }
  }
}
```

## 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-08-20 (score 62)

First indexed and scored.

## MCP tools (19)

### `health_sync` (~365 tokens)

Sync health data to the local cache.

Fetches data from the Google Health API and stores it in SQLite for fast
offline queries. Run this before using other health_get_* tools.

Syncs incrementally: only fetches data newer than the most recent
entry in each table. First sync fetches the specified number of days.

Args:
    data_types: What to sync. Options: "all", "heart_rate", "activity",
        "exercises", "sleep", "weight", "spo2", "hrv", "azm",
        "breathing_rate", "skin_temperature", "core_temperature",
        "cardio_fitness", "food_log", "ecg", "irn".
        Comma-separated for multiple, e.g. "sleep,hrv". Default: "all".
    days: Days of history for first sync (default: 30). Ignored
        on subsequent syncs (uses last synced date).
    since: Optional "YYYY-MM-DD" backfill date. When set, fetches from this
        date regardless of what is already cached - use to pull history
        older than the current cache. Overrides incremental resume and days.
    until: Optional "YYYY-MM-DD" inclusive end date; requires since.
        Together they re-fetch and upsert exactly the since..until window -
        use to repair a gap in the middle of the cache without re-pulling
        everything from the gap to today.

Returns summary of records synced per data type.
Not for querying data - use health_get_heart_rate, health_get_activity,
health_get_sleep, etc. instead.

Input parameters:

- `data_types` (string)
- `days` (integer)
- `since`
- `until`

Output parameters:

- `result` (string)

### `health_get_activity` (~190 tokens)

Get daily activity summaries (steps, calories, active minutes, distance).

Returns data from the local cache by default. Use live=True to fetch
from the API. Run health_sync first to populate the cache.

Note: live=True fetches one API call per day - avoid large ranges to
stay within the 150 requests/hour rate limit.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

Returns one entry per day with steps, calories, active minutes, distance.
active_minutes = very_active + fairly_active (excludes lightly active).

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_trends` (~542 tokens)

Analyse trends in cached health data.

Computes averages and totals over time from the local cache,
auto-syncing if stale.

Args:
    data_type: What to analyse. Options: "heart_rate", "activity",
        "exercises", "sleep", "weight", "spo2", "hrv", "azm",
        "breathing_rate", "skin_temperature", "core_temperature",
        "cardio_fitness", "food_log". Default: "activity".
    period: Aggregation period. Options: "weekly", "monthly",
        "quarterly". Default: "monthly".
    start_date: Start date as "YYYY-MM-DD" or "365d". Default: last 12 months.
    end_date: End date as "YYYY-MM-DD". Default: today.
    compare: Compare two periods. Format: "last_30d vs previous_30d",
        "2026-03 vs 2026-02", "2026-Q1 vs 2025-Q4".
        When set, period/start_date/end_date are ignored.

Returns aggregated averages per period. For activity: steps, distance,
active minutes. For exercises: sessions, duration, calories.
For sleep: duration, efficiency, stage breakdown.
For heart_rate: resting HR min/avg/max. For weight: weight, fat%, BMI.
For hrv: daily and deep RMSSD.

Two data types report their history under two definitions, each with the
count of readings behind it - never merge them into one series. For spo2,
min_spo2/max_spo2 are observed nightly extremes, while
avg_nightly_ci_low/avg_nightly_ci_high average the nightly bounds of a
confidence interval on each night's own average. For cardio_fitness,
avg_vo2_max_low/high average a reported band while avg_vo2_max averages a
single value.

Those per-definition fields and their counts appear in the period form
only. `compare=` reports spo2 as avg_spo2 alone, which is deliberate and
not a gap: that column means the same thing under both definitions, so it
is the one figure two windows either side of the switchover can be
compared on. Ask for the period form when you need to know which
definition is behind a number. cardio_fitness has no such neutral column,
so `compare=` carries both definitions there.
Not for ra…

Input parameters:

- `compare`
- `data_type` (string)
- `end_date`
- `period` (string)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_azm` (~225 tokens)

Get daily Active Zone Minutes (AZM), the headline cardio metric.

AZM counts minutes spent in heart rate zones at or above Fat Burn intensity.
\`total_minutes` is the plain sum of the three zone columns as reported, not a
weighted one. Returns from local cache by default, auto-syncing if stale.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

Returns one entry per day with total_minutes plus per-zone breakdown
(fat_burn_minutes, cardio_minutes, peak_minutes).
Distinct from active_minutes in health_get_activity, which counts wall-clock
minutes regardless of intensity - and which has no source in this API, so it
is present only for days that arrived by import.

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_breathing_rate` (~177 tokens)

Get nightly breathing rate (avg breaths per minute during sleep).

Sourced during sleep tracking. Useful as an illness/recovery signal:
sustained increases of 2-3 bpm above personal baseline can indicate
incipient infection or strain. Returns from cache by default,
auto-syncing if stale.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

Returns one entry per night with breaths_per_min.
Typical adult range: 12-20 bpm at rest.

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_cardio_fitness` (~232 tokens)

Get Cardio Fitness Score (VO2 Max estimate).

Estimated from resting HR, HR during walks and runs, and demographics.
Updates roughly weekly. Returns from cache by default, auto-syncing if stale.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

A reading usually carries a range or a single value; one re-synced across
the switchover between providers can hold both. They are different
measurements - do not average them together or fill one from the other.
vo2_max_low and vo2_max_high are a reported band (e.g. 39-43); vo2_max is
a single figure. All in mL/kg/min, higher being better cardiorespiratory
fitness.

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_devices` (~92 tokens)

List paired devices with battery level and last sync time.

Live-only (no caching) - reflects current device state. Useful for
monitoring tracker health, knowing which device produced data, and
spotting sync gaps.

Returns one entry per paired device with id, type, device_version,
battery (e.g. "High"), battery_level (0-100), last_sync_time, mac,
and features list.

Output parameters:

- `result` (string)

### `health_get_exercises` (~213 tokens)

Get exercise log entries (individual tracked activities).

Returns exercise sessions from the local cache by default. Use live=True
to fetch from the API. Run health_sync first to populate the cache.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    exercise_type: Filter by activity name (case-insensitive substring match),
        e.g. "cycling", "walk", "run". Default: all types.
    live: If true, re-fetch this window from the API before reading the cache.

Returns exercise entries with name, duration, calories, avg heart rate,
distance, and source (auto-detect vs manual).
Note: HR data from cycling may be unreliable (optical sensor vs handlebar grip).

Input parameters:

- `end_date`
- `exercise_type`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_food_log` (~164 tokens)

Get daily food and water log summary.

Returns calories consumed and water intake (in mL) per day. Only populated
where the user logs food or water by hand in a connected app. Returns from
cache by default, auto-syncing if stale.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

Returns one entry per day with calories_in and water_ml.
Days with no logging are omitted.

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_heart_rate` (~165 tokens)

Get daily resting heart rate and heart rate zones.

Returns resting HR and zone breakdown (Out of Range, Fat Burn, Cardio, Peak)
from the local cache by default, auto-syncing if stale.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

Returns one entry per day with resting_hr and zones array.
Zone data: name, minutes, caloriesOut, max/min HR for each zone.

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_hrv` (~190 tokens)

Get nightly HRV (heart rate variability) data.

Returns data from the local cache by default. Use live=True to fetch
from the API. Run health_sync first to populate the cache.

HRV data is sparse: only nights with on-wrist sleep tracking produce readings.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

Returns one entry per night with daily_rmssd and deep_rmssd (ms).
RMSSD = root mean square of successive RR interval differences.
Higher values generally indicate better recovery and parasympathetic activity.

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_lifetime_stats` (~125 tokens)

Get all-time activity totals and personal best records.

Totals for steps, floors, distance and calories over every day held in the
cache, plus the best single day for steps, floors and distance with the
date each record was set.

The answer is bounded by what has been synced, so it is returned with a
\`coverage` block giving the first and last dates and the number of days
counted - read it before quoting a total as all-time. There is no
tracker-versus-total split and no "active score"; neither has a source.

Output parameters:

- `result` (string)

### `health_get_ecg` (~302 tokens)

Get electrocardiogram (ECG) readings taken on the watch.

Each reading is a single-lead trace the user started by hand, with a
rhythm classification - NORMAL_SINUS_RHYTHM, ATRIAL_FIBRILLATION, or one
of several inconclusive results (low or high heart rate, poor reading,
unclassified). Use it for questions about heart rhythm or AFib checks;
for resting rate over time use health_get_heart_rate instead.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.
    include_waveform: If true, include the raw voltage samples. These are
        thousands of integers per reading - ask for them only to analyse
        the trace itself. Multiply by scaling_factor for millivolts, and
        read them at sampling_hz samples per second.

Returns one entry per reading with classification, avg_bpm, duration_sec,
sampling_hz, scaling_factor and waveform_samples (null where no trace was
stored, or where the stored one cannot be read).

Input parameters:

- `end_date`
- `include_waveform` (boolean)
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_irregular_rhythm` (~190 tokens)

Get irregular heart rhythm notifications raised by the watch.

These are background checks the watch runs while the user is still - an
alert means it saw a rhythm consistent with atrial fibrillation over one
or more windows, not a diagnosis. Most accounts never have one. For a
deliberate reading with a trace behind it, use health_get_ecg.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

Returns one entry per notification with start_time, end_time and
alert_windows (the periods that triggered it).

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_sleep` (~189 tokens)

Get nightly sleep data (duration, stages, efficiency).

Returns sleep data from the local cache by default. Use live=True
to fetch from the API. Run health_sync first to populate the cache.

Sleep data is sparse: only nights with watch-tracked sleep are present.
Travel, off-wrist nights, or manual logs may be missing.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

Returns one entry per night with total_minutes, efficiency, start/end times,
and stage breakdown (deep, light, REM, wake minutes).

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_spo2` (~268 tokens)

Get nightly SpO2 (blood oxygen saturation) data.

Returns data from the local cache by default. Run health_sync first to
populate it.

SpO2 data is sparse: only nights with on-wrist sleep tracking produce readings.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

Returns one entry per night with avg SpO2 percentage, and a pair of
bounds whose meaning depends on which provider recorded the night:
min/max are the observed nightly extremes, avg_ci_low/avg_ci_high are a
confidence interval on that night's average. Only an import fills the
first pair and only this API fills the second, so a night covered by both
carries all four - which is the ordinary case wherever an imported
history overlaps the synced one. They are different measurements: never
compare or average across them.
Normal range: 95-100%. Below 90% may indicate sleep apnea.

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_skin_temperature` (~189 tokens)

Get nightly skin temperature variation (degrees Celsius from personal baseline).

This is the device-derived RELATIVE deviation recorded during sleep, NOT an
absolute body temperature - for fever / body-temperature readings use
health_get_core_temperature instead. A baseline takes about three nights to
establish before values appear. Useful as an illness/cycle/recovery signal.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

Returns one entry per night with nightly_relative (degrees C, can be negative)
and log_type (e.g. "dermal").

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_core_temperature` (~203 tokens)

Get manually-logged core (body) temperature readings (degrees Celsius).

These are absolute body temperatures the user enters by hand - a
thermometer reading logged in an app - and are the right source for
fever / body-temperature questions. They are NOT the device-derived nightly
skin-temperature variation from health_get_skin_temperature. A single day can
hold several readings (each timestamped), useful for tracking a fever over time.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

Returns one entry per logged reading with datetime (YYYY-MM-DDThh:mm:ss)
and temp_celsius.

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

### `health_get_weight` (~163 tokens)

Get weight log entries (weight, BMI, body fat percentage).

Returns data from the local cache by default. Use live=True to fetch
from the API. Run health_sync first to populate the cache.

Weight data is sparse: only days with weigh-in entries are present.

Args:
    start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days.
    end_date: End date as "YYYY-MM-DD". Default: today.
    live: If true, re-fetch this window from the API before reading the cache.

Returns one entry per weigh-in with weight_kg, bmi, fat_pct.

Input parameters:

- `end_date`
- `live` (boolean)
- `start_date`

Output parameters:

- `result` (string)

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/partymola-google-health-mcp/google-health-mcp#diagnostics

## Score history

- 2026-08-20: 62

## Links

- PyPI project: https://pypi.org/project/google-health-mcp/
- Socket report: https://socket.dev/pypi/package/google-health-mcp
- Repository: https://github.com/partymola/google-health-mcp
- Changelog RSS feed: https://verifymcp.io/servers/partymola-google-health-mcp/google-health-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/partymola-google-health-mcp/google-health-mcp.json
- HTML version of this page: https://verifymcp.io/servers/partymola-google-health-mcp/google-health-mcp
