google-health-mcp
Static Go MCP for Google Health data
from modern Fitbit / Pixel Watch devices via the
Google Health API
(health.googleapis.com).
Built for ai-gantry / LOCAL_AGENT: lean
core tool surface (Garmin-shaped nouns), stdio only, CGO_ENABLED=0.
Read + summarize — never writes fake workouts.
Naming follows
ai-gantry MCP tool naming:
host server id ghealth → tools like ghealth__sleep_get (tool names do
not repeat the server id).
New school only
| Path |
This package? |
| Google Health API + Google OAuth 2.0 |
✅ Yes |
| Legacy Fitbit Web API (FOT auth) |
❌ Turned down Sept 2026 — skip |
| Google Fit REST |
❌ Closed to new apps — skip |
| Health Connect (on-device Android) |
❌ Wrong shape for stdio MCP |
Friends on the new Google/Fitbit line sync through the Fitbit app → data is
available on Google Health API. Chris keeps go-garmin.
Background: docs/why-google-health.md.
| Tool |
Google Health data type(s) |
sleep_get |
sleep (reconcile) |
activities_list |
exercise (list / reconcile) |
activities_get |
exercise get by name |
heart_rate_get |
daily-resting-heart-rate (+ optional heart-rate) |
hrv_get |
daily-heart-rate-variability |
weight_get |
weight |
profile_get |
identity / profile |
account_get |
auth / token status |
Host: ghealth__sleep_get, ghealth__activities_list, …
Agent contract
sleep_get / heart_rate_get / hrv_get → recovery
last night / today: omit date
a span: after_date + before_date once (sessions[] / entries[])
activities_list → activities_get → “what did I do?”
weight_get → scale (period already a series)
The Google Health app’s 0–100 Sleep Score is not on dataTypes/sleep
(no sleep-score data type either). sleep_get returns the session the API
does expose: duration, stages_minutes, and efficiency
(round(minutes asleep / minutes in the sleep period × 100)). It does not
invent a score.
Same recipes as garmin__… — swap prefix for Fitbit friends.
Setup
- Personal GCP project →
enable Google Health API
→ OAuth Web client (setup).
- Authorized redirect URI:
http://127.0.0.1:4101/oauth2callback
- Add readonly scopes you need on the Data Access page (Restricted —
testing limited to ~100 users until verification).
- Export:
export GOOGLE_HEALTH_CLIENT_ID=...
export GOOGLE_HEALTH_CLIENT_SECRET=...
# after auth (optional — $DATA_DIR/.config/ghealth/tokens.json is the gantry default):
# export GOOGLE_HEALTH_TOKEN_PATH=...
- Auth (on the machine with your browser):
google-health-mcp auth
# Docker / ai-gantry: make ghealth-auth → publishes localhost:4101
PKCE + loopback → tokens on disk.
Core scopes (readonly)
https://www.googleapis.com/auth/googlehealth.sleep.readonly
https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly
https://www.googleapis.com/auth/googlehealth.profile.readonly
Boot safety
MCP starts even if tokens are missing. Data tools return a clear auth
error. Optional fitness MCP must not take Tim down.
Development
make help
make tools
make check
make cli
make self-test
Status: live health.googleapis.com/v4 client (reconcile + wearables filter) +
OAuth CLI. See TODO.md for release / ai-gantry wiring.
ai-gantry wiring
[[server]]
name = "ghealth"
command = "google-health-mcp"
auth_args = ["auth"]
download_tag = "latest"
download_url = "https://github.com/shotah/google-health-mcp/releases/download/{tag}/google-health-mcp_{version}_{os}_{arch}.tar.gz"
License
MIT