google-health-mcp
Gives Claude read access to wearable health data from Fitbit or Wear OS devices via the Google Health API, exposing tools for metrics like steps, heart rate, sleep, and workouts, plus a computed recovery score.
README
google-health-mcp
Give Claude read access to your wearable health data. This is a Model Context Protocol server that reads a Fitbit or Wear OS device's data from the Google Health API — steps, heart rate, resting HR, HRV, SpO2, respiratory rate, skin-temperature deviation, sleep stages, workouts, weight, VO2max and AFib/irregular-rhythm notifications — and exposes it as MCP tools. It also computes a transparent 0-100 recovery/readiness score as a proxy for Fitbit's Daily Readiness, which the API does not expose.
Ask Claude "how's my recovery this week?" or "did my resting heart rate spike after that hard workout?" and it can pull the real numbers.
Not medical advice. This tool surfaces consumer wearable data for personal, informational use only. It is not a medical device and must not be used for diagnosis or treatment. The readiness score is a heuristic, not a clinical metric. If any reading concerns you (for example an AFib alert), consult a qualified physician.
How it works
Fitbit / Wear OS → Google Health app → your Google account → Google Health API (/v4) → this MCP server → Claude
The device syncs to the Google Health app, which uploads to your Google account. This server authenticates with a read-only OAuth token and calls the Google Health REST API on demand, only when Claude invokes a tool.
Tools exposed
| Tool | What it returns |
|---|---|
daily_summary(days=7) |
Everything, per day: steps, distance, floors, active calories, active-zone minutes, heart rate (avg/min/max), resting HR, HRV, SpO2, respiratory rate, sleep skin-temperature deviation, weight, sleep minutes. |
get_recovery(days=7) |
Per-day recovery panel with the custom readiness score (0-100), plus respiratory rate, skin-temperature deviation, and the personal baselines used. |
get_heart(days=7) |
Heart-rate avg/min/max, resting HR and HRV per day. |
get_sleep(days=7) |
Sleep sessions with start/end/duration and minutes per stage (DEEP/LIGHT/REM/AWAKE). Timestamps in UTC. |
get_workouts(days=14) |
Exercise sessions: type, duration, calories, distance, steps, average pace. |
get_afib(days=30) |
Irregular-rhythm / atrial-fibrillation notifications and whether any were positive. |
available_data_types() |
Probes which data types are available right now and via which API method. |
query(data_type, days=7, method="auto") |
Escape hatch for any raw dataType (accepts kebab/camel/snake case). |
The readiness score
Fitbit's "Daily Readiness" and "Cardio Load" scores are not available through the Google Health API (they only appear in Google Takeout and the app). get_recovery therefore computes its own score from the same underlying signals:
| Input | Weight | Behaviour |
|---|---|---|
| HRV (vs. your baseline) | 45% | Higher HRV relative to your personal mean → higher score. |
| Resting heart rate (vs. your baseline) | 30% | Lower resting HR relative to your mean → higher score (+6 points per bpm below baseline). |
| Sleep duration | 25% | Linear toward a 450-minute (7.5 h) target. |
Each sub-score is clamped to [0, 100]; the weighted total maps to a band: PEAK (≥85), HIGH (≥70), BALANCED (≥50), LOW (≥30), VERY_LOW (<30). Baselines are the mean HRV and mean resting HR over all available history, so the score is relative to your norm, not a population average. This is a deliberately simple, inspectable heuristic — see _readiness() in server.py — and it is not the same algorithm Fitbit uses.
Prerequisites
- A Google account with wearable data. A Fitbit or Wear OS device synced through the Google Health app.
- A Google Cloud project with the Google Health API enabled.
- An OAuth client of type Desktop app in that project. Download its client-secret JSON.
- The Google Health scopes granted on your OAuth consent screen (they are Restricted scopes — see Limitations):
googlehealth.sleep.readonlygooglehealth.health_metrics_and_measurements.readonlygooglehealth.activity_and_fitness.readonlygooglehealth.irn.readonly- plus base
openid,userinfo.email,userinfo.profile
- Python 3.10+.
Install
From source (works today):
git clone https://github.com/jorgeschnura/google-health-mcp
cd google-health-mcp
pip install -e .
This installs two commands: google-health-mcp (the server) and google-health-mcp-auth (the one-time OAuth helper).
If/when this package is published to PyPI,
pip install google-health-mcp— or running it without installing viauvx --from google-health-mcp google-health-mcp— will also work. Until then, use the source install above.
Authenticate (one time)
Point the auth helper at your OAuth client-secret JSON and run the consent flow:
export GOOGLE_HEALTH_CLIENT_SECRET=/path/to/client_secret.json
# optional — defaults to ~/.google-health-mcp/token.json
export GOOGLE_HEALTH_TOKEN_PATH=~/.google-health-mcp/token.json
google-health-mcp-auth
# or: python -m google_health_mcp.auth --client-secret /path/to/client_secret.json
A browser window opens. Sign in and grant access. The helper writes a token.json containing a refresh token, which the server refreshes automatically thereafter. Re-run with --force to re-authenticate (for example after adding a scope).
On Windows, set the variables with set (cmd) or $env:GOOGLE_HEALTH_CLIENT_SECRET = "..." (PowerShell), and use %USERPROFILE% / $env:USERPROFILE in place of ~.
Configure Claude Desktop
Add the server to your claude_desktop_config.json. Use paths appropriate to your machine (%USERPROFILE% on Windows, $HOME/~ on macOS/Linux):
{
"mcpServers": {
"google-health": {
"command": "google-health-mcp",
"env": {
"GOOGLE_HEALTH_TOKEN_PATH": "/home/you/.google-health-mcp/token.json"
}
}
}
}
If you installed from source into a virtual environment, point command at that environment's google-health-mcp executable (or use "command": "python", "args": ["-m", "google_health_mcp.server"]). Restart Claude Desktop after editing the config.
Configuration reference
| Variable | Purpose | Default |
|---|---|---|
GOOGLE_HEALTH_TOKEN_PATH |
Where the OAuth token is read (server) and written (auth helper). | ~/.google-health-mcp/token.json |
GOOGLE_HEALTH_CLIENT_SECRET |
Path to the OAuth client-secret JSON. Used only by the auth helper. | (none — required for auth) |
See .env.example for a template.
Limitations (honest)
- This is a reference implementation. The dataType IDs, payload shapes and scope names reflect the Google Health API as observed at the time of writing. Google's health APIs evolve; you may need to adapt field names or endpoints for your account. Treat this as a working starting point, not a guaranteed-stable client.
- Restricted availability. The Google Health API and its scopes are Restricted. Access depends on Google's availability program for your project/region, and the scopes must be granted on your consent screen. If a data type returns a non-200 status,
available_data_types()will show it as unavailable. - Daily Readiness & Cardio Load are not in the API. They exist only in Google Takeout and the Fitbit/Google Health app. The readiness score here is a proxy, computed locally.
- VO2max needs a GPS run. The API's runtime VO2max requires a GPS-tracked run of ≥10 minutes; walking does not count. The demographic VO2max estimate shown in the app is not exposed by the API.
- Timestamps are UTC. Sleep and workout timestamps are returned in UTC (ISO-8601,
Z). Convert to the wearer's local time zone on the client side if you need local times. - Single user. The server reads
users/mefor whichever account the token belongs to. It is designed for personal, single-account use.
Privacy
Your health data stays on your machine. The token lives locally (git-ignored), and the server only calls the Google Health API — and only returns data to the LLM — when Claude actually invokes a tool. Nothing is sent anywhere else, and no data is stored by this server beyond the OAuth token. When a tool is called, its output is passed to the connected LLM as part of the conversation, so share only what you're comfortable sharing with your model provider.
Development
pip install -e .
python -m py_compile src/google_health_mcp/server.py src/google_health_mcp/auth.py
License
MIT — see LICENSE. Author: Jorge Schnura.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.