google-health-mcp-aws
Provides access to sleep and recovery data from Fitbit devices (and Pixel Watch) via the Google Health API, including HRV, resting and sleeping heart rate, SpO2, breathing rate, skin temperature, and detailed sleep sessions.
Integrates with the Google Health API to retrieve sleep and recovery metrics, such as HRV, heart rate, SpO2, breathing rate, skin temperature, and sleep stage details.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@google-health-mcp-awsHow recovered am I this morning?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
google-health-mcp-aws
An MCP (Model Context Protocol) server that gives Claude access to sleep and recovery data from a Fitbit or Pixel Watch, through the Google Health API (the successor of the Fitbit Web API). It runs on AWS Lambda as a claude.ai custom connector, so it works in claude.ai on the web, on mobile and in Claude Desktop. Several people can share one deployment, and each signs in with their own Google account.
It's meant for a training coach in Claude: HRV, resting and sleeping heart rate, SpO2, breathing rate, skin temperature and sleep, compared with your own baseline.
"How recovered am I this morning?"
"How has my HRV trended over the last month?"
"Show me last night's sleep in detail. When was my heart rate lowest?"
"Did my sleep get worse during the training block that started on the 1st?"
Tools
Tool | Description |
| One morning's metrics against your baseline over the preceding days: mean, standard deviation, z-score and 7-day average for each metric. Includes flags for notable deviations, and last night's sleep. |
| One row per day: HRV (average and deep-sleep RMSSD), sleeping heart rate (non-REM), resting heart rate, SpO2 (average and range), breathing rate, skin temperature and its deviation from baseline, and minutes asleep. |
| Sleep sessions: bedtime, wake time, time asleep and awake, efficiency, time to fall asleep, awakenings, and minutes and percentages of deep, light and REM sleep. Naps are flagged, and a stage-by-stage timeline is optional. |
| One night in 5-minute buckets (adjustable): sleep stage, heart rate, HRV and SpO2. Includes the night's average and lowest heart rate, SpO2 minimum, and breathing rate per sleep stage. |
All tools are read-only. Nightly metrics belong to the date you woke up, as in the Fitbit app.
Related MCP server: whoop-mcp
Setup
You need an AWS account, a Google account, and a Fitbit or Pixel Watch whose data is in that Google account. A Fitbit account has to be moved to a Google account for the Google Health API to see it.
Install Node.js 20+, the AWS CLI and the SAM CLI, then sign in to AWS with a default region:
winget install OpenJS.NodeJS.LTS
winget install Amazon.AWSCLI
winget install Amazon.SAM-CLI
aws configure # or: aws login
npm install1. Create the Google Cloud project
In the Google Cloud console, create a project, for example
google-health-mcp.Enable the Google Health API in that project.
Open Google Auth Platform and click Get started. Give the app a name (people see it on Google's consent screen), set a support email, and choose External as the audience.
Under Data access → Add or remove scopes, add these four scopes:
openid.../auth/userinfo.email.../auth/googlehealth.sleep.readonly.../auth/googlehealth.health_metrics_and_measurements.readonly
Under Audience, click Publish app to set it In production. Google doesn't need to verify it for up to 100 users.
While the app is inTesting, Google's refresh tokens expire after 7 days, so everyone has to reconnect weekly. Once it's published, it stays unverified: sign-in shows "Google hasn't verified this app", and people continue with Advanced → Go to (app name). Google Health scopes are restricted, so getting verified takes a security review. That's only worth it past 100 users.
2. Deploy
npm run deployConfirm the changeset when asked. The output ends with two values:
McpServerUrl, which people add to claude.ai.GoogleRedirectUri, which the Google OAuth client needs next.
sam list stack-outputs shows them again later.
3. Create the Google OAuth client
In Google Auth Platform, go to Clients → Create client and choose application type Web application.
Under Authorized redirect URIs, add the
GoogleRedirectUrifrom the deploy output. It ends in/oauth/callback.Create the client and download its JSON file.
Store the client in SSM, then delete the downloaded file:
npm run admin -- google-client path/to/client_secret_....jsonAllow your own Google account to connect:
npm run admin -- allow you@gmail.com
4. Connect Claude
In claude.ai, go to Settings → Connectors → Add custom connector and paste the McpServerUrl (it ends in /mcp). Click Connect and sign in with Google. On the consent screen, allow both sleep data and health metrics.
The connector then works on web and mobile, and in Claude Desktop. To use it in a training-coach project, enable it in that project's chat.
Adding someone
Run
npm run admin -- allow their@gmail.comwith the Google account that holds their Fitbit data.Send them the
McpServerUrl. They add the connector in their own claude.ai account and sign in with Google. On the Free plan, claude.ai allows one custom connector.
Each person sees only their own data. Their Google tokens are stored nowhere on the server; they travel inside the encrypted tokens Claude holds for their connection.
Day to day
Task | Command |
Deploy code changes |
|
Show the Google client and who can connect |
|
Let someone connect |
|
Stop someone connecting (signs them out) |
|
Replace the Google OAuth client |
|
Sign everyone out |
|
Show the URLs |
|
Remove everything |
|
Lambda reads its settings once per cold start, so every admin change also replaces the function's running instances. That way changes take effect immediately.
People can also remove the server's access themselves, under Google Account → Third-party connections. Claude then asks them to connect again.
How it works
Sign-in: claude.ai custom connectors only support OAuth, so the server is a small OAuth server that passes sign-in on to Google. When someone connects, the server sends their browser to Google's consent screen. It then checks their Google email against the allowlist and hands Claude a code.
Tokens: Claude's access token carries the person's Google access token, and its refresh token carries their Google refresh token, all encrypted (AES-256-GCM) with a key only the server has. Every hour Claude refreshes its token, and the server gets a new Google access token. If Google no longer accepts the grant, Claude asks the person to reconnect.
No database: nothing is stored per person. The signing secret, the allowlist and the Google OAuth client are SecureString parameters in SSM Parameter Store, so they never appear in the function's configuration or in the repo.
Data: tools use the Google Health API's
reconcileendpoint, which merges data from all sources (Fitbit, Pixel Watch, Health Connect apps) so a night isn't counted twice.Cost: normally $0, within Lambda's always-free allowance (1M requests and 400,000 GB-seconds a month). Set up an AWS budget alert anyway.
Running locally
For testing, or for MCP clients on your own machine, the same server runs locally with settings from .env:
Add
http://localhost:3000/oauth/callbackto the Google OAuth client's authorized redirect URIs.Copy
.env.exampleto.envand fill it in.Run:
npm run build npm start
The server listens on http://localhost:3000/mcp. For example: claude mcp add --transport http google-health http://localhost:3000/mcp.
Known limitations
Data freshness: data only reaches Google after the watch syncs with the Fitbit app, and some metrics (HRV, skin temperature) are computed a while after waking. This morning's values can be missing at first.
Reconnecting: Google ends grants after 7 days while the app is in Testing, and after 6 months without use. Some integrations also report grants ending unexpectedly (home-assistant/core#182964). In all these cases Claude asks you to connect again.
Unverified app: see the note in step 1. The limit is 100 people.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
WHOOP recovery, strain, sleep and workouts in Claude via official WHOOP OAuth. Free, open source.
Garmin data in Claude & ChatGPT via the Garmin Health API. OAuth sign-in, no password sharing.
Pace is a remote MCP server that exposes wearable and fitness data to Claude via the Model Context Protocol. It connects to Garmin, Oura, Whoop, Polar, Fitbit and 20+ devices and provides 15 tools for querying sleep, activity, recovery, and training data. Hosted on Google Cloud Run, OAuth 2.1 authentication, Streamable HTTP transport. Instructions: First you need to create an account at: https://pacetraining.co and connect your wearables. After that you can connect the remote Server via Custom Connector in Claude and OAuth 2.1 Flow startet.
Connect your Oura Ring account securely in minutes. Enable authorized access to your sleep, activi…
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceConnects Whoop health data to Claude via an MCP server, enabling retrieval of recovery, sleep, strain, and workout metrics through natural language tools.196 npmMIT
- AlicenseAqualityCmaintenanceConnects WHOOP fitness tracker data to AI assistants like Claude and ChatGPT, enabling natural language queries about recovery, sleep, strain, and trends.2450 PyPI2MIT
- AlicenseNot gradedqualityCmaintenanceGives 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.MIT
- AlicenseNot gradedqualityDmaintenanceConnects your Whoop health data to Claude, enabling natural language queries about recovery, sleep, strain, and workouts.196 npmMIT