google-health-fitbit-mcp
v1.0.2
Published
Google Health API MCP server for AI health, sleep and activity agents — reads Fitbit, Pixel Watch and partner data locally over OAuth.
Maintainers
Readme
An MCP server that runs locally and hands your AI agent your own Google Health API data — from Fitbit trackers, Pixel Watch and supported partner sources — through OAuth.
- Install in one command —
npx -y google-health-fitbit-mcp setup - Run it in Claude Desktop · Claude Code · Cursor · Windsurf · Hermes · OpenClaw — see client examples.
- On your machine — OAuth tokens are stored locally with
0600permissions and are never returned by any tool (privacy). - Read-only by default — every shipped data tool is a read. Writes are a gated, opt-in, dry-run-first design that is not enabled.
Beta status: Google Health API is available to developers but the surface is still moving. Because Google's release notes keep listing scope and data-type changes after launch, this connector remains in beta and steers testers toward safe read-only validation before any production use.
Independent, community-built connector — no affiliation with, endorsement from or support by Google, Fitbit or Alphabet. Not a medical device or medical advice; treat the data as trend context only.
⚡ Quick Connect
Prerequisite: a Google Cloud OAuth client (type: Desktop) with the Google Health API enabled and the redirect
http://127.0.0.1:3000/callbackregistered — details in Install.
Step 1 — Install & authorize (once):
npx -y google-health-fitbit-mcp setup # guided: Google Cloud OAuth client + scopes
npx -y google-health-fitbit-mcp auth # browser OAuth — tokens stay on your machine
npx -y google-health-fitbit-mcp checkup # ✓ verifies everything is readysetup asks for a Client ID and Client Secret. You create these once, for free, in Google Cloud:
- New project — open console.cloud.google.com/projectcreate, name it (e.g.
health-mcp), click Create, then select it. - Enable the API — open the Google Health API page and click Enable.
- Consent screen — go to OAuth consent screen, choose External, and fill in the required app name / email fields. Under Test users, add your own Google account — skip this and sign-in fails with
403: access_denied. - Create the client — go to Credentials → + Create credentials → OAuth client ID → Application type: Desktop app → Create.
- Copy the Client ID (ends in
…apps.googleusercontent.com) and the Client secret, then paste each one whensetupprompts you.
Redirect URI: Desktop-app clients allow the
http://127.0.0.1:3000/callbackloopback automatically — you don't register it anywhere. Just press Enter to accept the default whensetupasks. For every othersetupprompt (scope preset, privacy mode), pressing Enter picks a sensible default.
Step 2 — Connect your app:
claude mcp add google-health -- npx -y google-health-fitbit-mcpSettings → Developer → Edit Config, then add to claude_desktop_config.json:
{
"mcpServers": {
"google_health": {
"command": "npx",
"args": ["-y", "google-health-fitbit-mcp"]
}
}
}Restart Claude Desktop — the tools appear under the 🔌 connectors menu.
Add the same mcpServers block to .cursor/mcp.json (per-project) or ~/.cursor/mcp.json (global), or use Settings → MCP → Add new server.
{
"mcpServers": {
"google_health": {
"command": "npx",
"args": ["-y", "google-health-fitbit-mcp"]
}
}
}Add the same mcpServers block to ~/.codeium/windsurf/mcp_config.json.
npx -y google-health-fitbit-mcp setup --client hermes # writes the Hermes config for youThen reload with /reload-mcp or hermes mcp test google_health.
Step 3 — Test it. Ask your agent:
Run google_health_connection_status and tell me if I'm connected.Why this exists
The Google Health API is the successor to the Fitbit Web API: new OAuth, new base URL (https://health.googleapis.com), a streamlined endpoint schema, standardized kebab-case data types, reconciled cross-source streams and daily/physical-time rollups.
It gives agents a clean path to explore the API, verify their setup, sign in locally and pull data — with no need to paste tokens into prompts or agent configs.
Try it with your agent
Three good opening prompts, built around tools this connector genuinely ships:
Check my setup with google_health_connection_status, then call
google_health_data_inventory and tell me which Google Health
domains and scopes I've granted.Pull today's google_health_daily_summary, then google_health_weekly_summary.
Keep observed data separate from any suggestions, and stay non-medical.List my paired devices with google_health_list_paired_devices and tell me
which device is producing my sleep and heart-rate data.Tools
29 tools, all read-only except the two explicitly gated local-profile/auth actions noted below.
Start here
| Tool | What it does |
|---|---|
| google_health_connection_status | Local config, token, scope and MCP-client readiness — no Google call |
| google_health_quickstart | Personalized 3-step setup walkthrough that adapts to your current state |
| google_health_data_inventory | Supported domains, scopes, data-type naming and recommended agent flow |
| google_health_list_data_types | The 39 kebab-case data-type slugs with units, scopes and supported verbs |
| google_health_demo | Realistic synthetic payloads so agents see the contract before real calls |
Data reads (Google Health API)
| Tool | Endpoint |
|---|---|
| google_health_get_identity | /v4/users/me/identity — Google Health + legacy Fitbit identity mapping |
| google_health_get_profile | /v4/users/me/profile |
| google_health_get_settings | /v4/users/me/settings — units, timezone |
| google_health_list_paired_devices | /v4/users/me/pairedDevices — your Fitbit trackers and Pixel Watches, and which device produces which data |
| google_health_get_irn_profile | /v4/users/me/irnProfile — irregular-rhythm (AFib) notification engagement status |
| google_health_list_data_points | /v4/.../dataPoints — intraday detail for any data type |
| google_health_get_data_point | /v4/.../dataPoints/{id} — one specific sleep session, exercise or measurement |
| google_health_reconcile_data_points | /v4/.../dataPoints:reconcile — one clean stream across sources (all-sources, google-wearables, google-sources) |
| google_health_daily_rollup | /v4/.../dataPoints:dailyRollUp — civil-day aggregates |
| google_health_rollup | /v4/.../dataPoints:rollUp — physical-time window aggregates |
Summaries & wellness context
| Tool | What it does |
|---|---|
| google_health_daily_summary | Steps, distance, calories, active-zone minutes, sleep, resting HR, HRV and weight for one day, with data-quality flags |
| google_health_weekly_summary | Weekly scorecard with optional prior-window comparison, load classification and bottlenecks |
| google_health_wellness_context | Normalized activity/sleep context for recommendation engines |
Auth, diagnostics & metadata
google_health_get_auth_url · google_health_exchange_code (gated: requires explicit user intent) · google_health_revoke_access (gated + destructive: disconnects Google Health) · google_health_privacy_audit · google_health_cache_status · google_health_data_type_coverage · google_health_capabilities · google_health_agent_manifest · google_health_onboarding · google_health_profile_get · google_health_profile_update (local file only, requires explicit_user_intent=true)
Resources & prompts
MCP resources: google-health://agent-manifest, google-health://capabilities, google-health://inventory, google-health://latest/steps, google-health://profile, google-health://summary/daily, google-health://summary/weekly.
MCP prompts: google_health_daily_checkin, google_health_weekly_review, google_health_data_type_investigation.
Data types
39 data types from the official Google Health table, including steps, sleep, heart-rate, heart-rate-variability, daily-resting-heart-rate, active-zone-minutes, distance, total-calories, weight, body-fat, blood-glucose, oxygen-saturation, vo2-max, electrocardiogram, irregular-rhythm-notification, exercise, floors, swim-lengths-data, nutrition-log and hydration-log.
Naming rules agents need:
- Endpoints use kebab-case data types:
steps,daily-resting-heart-rate. - Filters use snake_case field paths:
sleep.interval.civil_start_time,heart_rate.sample_time.physical_time. - Source families:
all-sources,google-wearables,google-sources.
Call google_health_list_data_types for the full catalog with units, scopes and which verbs (list/reconcile/rollup) each type supports.
Privacy & what runs offline
- OAuth tokens live on disk at
~/.google-health-mcp/tokens.json, locked down to0600permissions. - Client secrets go in
~/.google-health-mcp/config.jsonor theGOOGLE_HEALTH_*environment variables. - No tool ever hands back an access token, refresh token or client secret; error output is redacted too.
- The default privacy mode is
GOOGLE_HEALTH_PRIVACY_MODE=structured;summarystrips identifiers further, andrawis an explicit opt-in for debugging. - GPS/route data is treated as sensitive and redacted unless explicitly requested.
supportprints a copy-paste support bundle for GitHub issues — always redacted, never contains tokens, secrets, local paths or health measurements.support --feedback --jsonprints an anonymous setup-feedback bundle for beta testers (guide).coverage --live --jsonprints only redacted data-type status and point-count buckets — never raw Google Health payloads (guide).
Install
Set up a Google Cloud OAuth client (type: Desktop), turn on the Google Health API, and register the local redirect:
http://127.0.0.1:3000/callbackThen run:
npx -y google-health-fitbit-mcp setup --scope-preset full
npx -y google-health-fitbit-mcp auth
npx -y google-health-fitbit-mcp checkupScope presets
Presets keep OAuth consent easy to reason about — request only what your use case needs:
| Preset | Grants |
|---|---|
| basic | profile + settings |
| activity | basic + activity/fitness + health metrics |
| sleep | basic + sleep |
| heart | basic + health metrics + ECG + irregular-rhythm notifications |
| full | all recommended read-only scopes (default) |
| nutrition-write | opt-in nutrition write scope — the only preset with any write capability; no write tool ships yet |
Advanced users can pass --scopes with an explicit space/comma-separated scope list.
If setup gets stuck
npx -y google-health-fitbit-mcp checkup --fix # repairs local config/token permissions (chmod 600 where supported)
npx -y google-health-fitbit-mcp checkup --live # hits read-only identity/profile/settings endpoints to confirm the API responds
npx -y google-health-fitbit-mcp coverage --live --json # redacted read-only data-type coverage report
npx -y google-health-fitbit-mcp support # shareable support bundle, stripped of tokens/secrets/measurements
npx -y google-health-fitbit-mcp support --feedback --json # anonymous setup feedback bundleMCP client config
Claude Desktop / Cursor / Windsurf (see examples/):
{
"mcpServers": {
"google_health": {
"command": "npx",
"args": ["-y", "google-health-fitbit-mcp"]
}
}
}Hermes
npx -y google-health-fitbit-mcp setup --client hermes --no-auth
npx -y google-health-fitbit-mcp auth
npx -y google-health-fitbit-mcp checkup --client hermesOnce the config changes, run /reload-mcp or hermes mcp test google_health — there's no need to restart the gateway just to read data.
HTTP transport (optional)
The default transport is stdio. A local Streamable-HTTP transport is available for clients that need it:
npx -y google-health-fitbit-mcp --http # serves http://127.0.0.1:3000/mcp (+ /health)Configuration
| Environment variable | Purpose | Default |
|---|---|---|
| GOOGLE_HEALTH_CLIENT_ID | Google Cloud OAuth client ID | — (or local config) |
| GOOGLE_HEALTH_CLIENT_SECRET | OAuth client secret (prefer local config over MCP client config) | — (or local config) |
| GOOGLE_HEALTH_REDIRECT_URI | Registered redirect URI | — (or local config) |
| GOOGLE_HEALTH_TOKEN_PATH | Token file location | ~/.google-health-mcp/tokens.json |
| GOOGLE_HEALTH_PRIVACY_MODE | summary | structured | raw | structured |
| GOOGLE_HEALTH_CACHE | Optional SQLite response cache (true/sqlite) | disabled |
| GOOGLE_HEALTH_CACHE_PATH | SQLite cache location | ~/.google-health-mcp/cache.sqlite |
| GOOGLE_HEALTH_NO_CACHE | Bypass the in-memory HTTP cache (60s TTL, GET-only) | unset |
| GOOGLE_HEALTH_MCP_TRANSPORT | stdio | http | stdio |
| GOOGLE_HEALTH_MCP_HOST / GOOGLE_HEALTH_MCP_PORT | HTTP transport bind address | 127.0.0.1 / 3000 |
Reliability built in: every Google call goes through retry middleware (exponential backoff + jitter, honors Retry-After, retries 408/429/5xx) and a 60-second GET-only response cache. Multi-day summaries limit request concurrency to stay under rate limits.
CLI commands
All commands run via npx -y google-health-fitbit-mcp <command> (installed binary: google-health-fitbit-mcp-server).
| Command | What it does | Key flags |
|---|---|---|
| (none) | Start the MCP server on stdio | --http — local Streamable-HTTP on 127.0.0.1:3000/mcp |
| setup | Guided setup: writes local config + MCP client config | --scope-preset <basic\|activity\|sleep\|heart\|full\|nutrition-write> · --scopes "<url …>" · --client <generic\|claude\|cursor\|windsurf\|hermes\|openclaw> · --no-auth · --json |
| auth | Browser OAuth with local callback; saves tokens with 0600 permissions | --no-open — print the auth URL instead of opening the browser |
| checkup | Setup diagnosis with ✓/✗ checks and next steps (aliases: doctor, status) | --json · --client <name> · --fix — repair file permissions · --live — prove API reachability · --live-write — dry-run the write path, never POSTs |
| coverage | Data-type coverage report across list/reconcile/rollup | --json · --live — redacted read-only checks against your real account |
| support | Redacted support bundle for GitHub issues | --json · --feedback — anonymous setup-feedback bundle |
| onboarding | Shared wellness onboarding flow as JSON | --pt-BR |
| version / help | Print version / full usage | |
Beta testers wanted
Right now the most valuable thing you can contribute is hands-on setup feedback from real Fitbit, Pixel Watch, Android and Google Health API accounts.
If you have a real account to test with:
- Run
npx -y google-health-fitbit-mcp checkupand let us know whether the OAuth flow reads clearly. - Run
npx -y google-health-fitbit-mcp support --feedback --jsonand drop the anonymous bundle into a GitHub issue. - Once OAuth is done, run
npx -y google-health-fitbit-mcp coverage --live --jsonand post the redacted coverage report after you've reviewed it. - Exercise
google_health_connection_status,google_health_data_inventoryandgoogle_health_daily_summaryfrom inside your MCP client. - File an issue if you hit missing data types, unclear setup steps, client-specific friction or privacy concerns.
- Please keep OAuth tokens, client secrets, local paths and personal health measurements out of public issues.
Development
git clone https://github.com/BerkKilicoglu/google-health-fitbit-mcp.git
cd google-health-fitbit-mcp
npm install
npm testnpm test runs typecheck, build, MCP smoke tests (stdio + HTTP), summary fixtures, privacy/cache/retry suites, CLI UX checks and metadata validation. See CONTRIBUTING.md for guidelines and SECURITY.md for the security policy.
Links
- Google Health API: https://developers.google.com/health
- Release notes: https://developers.google.com/health/release-notes
- REST reference: https://developers.google.com/health/reference/rest
- Scopes: https://developers.google.com/health/scopes
- Data types: https://developers.google.com/health/data-types
- Migration guide (Fitbit → Google Health): https://developers.google.com/health/migration
Contact & support
- 🐛 Bug reports / feature requests — GitHub Issues
- 📨 [email protected] — general questions and integration help
License
MIT — see LICENSE.
