Oura MCP for Claude
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., "@Oura MCP for ClaudeHow have my readiness and HRV trended over the last month?"
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.
Oura MCP for Claude
Your own private Oura Ring connector for Claude. It's a remote MCP server that gives Claude read-only access to your Oura data: sleep, readiness, HRV, heart rate, activity, workouts, stress, resilience, SpO2, VO2 max and cardiovascular age.
Works in claude.ai, Claude Desktop and the Claude iOS/Android apps.
Runs free on Cloudflare Workers.
Locked to your Oura account.
Ask Claude things like:
"How have my readiness and HRV trended over the last month?"
"Did late workouts hurt my deep sleep this week?"
"Compare my resting heart rate on days I hit 10k steps vs. days I didn't."
Not affiliated with Oura or Anthropic. Uses the official Oura API v2 with OAuth. Oura retired personal access tokens in December 2025, so OAuth is now the only way in.
You need:
an Oura account with an active membership (API access requires it),
a free Cloudflare account,
a Claude plan that supports custom connectors.
Setup: pick one (about 10–15 minutes)
Option A: Deploy button (browser only, no terminal)
Click Deploy to Cloudflare. Cloudflare copies this repo to your GitHub, creates the storage and deploys.
When it asks for
OURA_CLIENT_IDandOURA_CLIENT_SECRET, enterpendingif you don't have an Oura app yet. ForTIMEZONE, enter yours, e.g.Europe/London.Open your new Worker's URL (
https://<name>.<you>.workers.dev). The home page is a setup checklist. It shows the exact values to paste into Oura's developer-app form for your deployment, and where to put each secret. Refresh it as you go.When everything is ticked, add
<your URL>/mcpin Claude (see Add it to Claude).
The Deploy-button flow is new. If anything looks off, use Option B or open an issue.
Option B: guided terminal setup (tested end to end)
You need Node.js 22 LTS and Git.
git clone https://github.com/Jerebearz/oura-mcp-for-claude.git
cd oura-mcp-for-claude
npm install
npm run setupnpm run setup walks you through everything, checks each step, and can be re-run any time:
Logs in to Cloudflare in your browser.
Deploys and creates its storage. You get a URL like
https://personal-oura-mcp.<you>.workers.dev.Prints exactly what to type into Oura's developer-app form, then verifies your Client ID and Secret with Oura before saving them as Cloudflare secrets.
Asks for your timezone, which it detects automatically.
Locks the server to your Oura account. It opens
/setup, you sign in to Oura, and paste back the ID it shows.Confirms the server reports itself ready.
Then run npm run doctor at any time for a health check.
Option C: let your AI agent do it
In Claude Code, or any agent with a terminal, say:
Set up https://github.com/Jerebearz/oura-mcp-for-claude for me. Follow its AGENTS.md.
The agent runs the commands and checks progress with npm run doctor -- --json. You only do the browser parts: the Cloudflare login, the Oura form and the Oura sign-in. You never paste secrets into the chat.
Add it to Claude
Go to claude.ai → Settings → Connectors → Add custom connector.
Fill in:
Name:
OuraURL:
https://<your-worker>.workers.dev/mcpLeave the OAuth fields empty.
Click Connect, then Continue to Oura, then sign in and approve.
Enable the connector in a chat. It syncs to the Claude mobile apps automatically.
Your computer doesn't need to stay on. The server runs on Cloudflare, and personal use fits easily in the free plan.
Related MCP server: Fernanda Health
Tools
Every tool is read-only and takes optional start_date / end_date in YYYY-MM-DD. The defaults are the last 7 days and the maximum is 90 days. Dates are calendar days in your configured TIMEZONE. Responses are compact JSON, not Oura's full raw payloads.
Tool | Oura data | Returns |
| Readiness | score, temperature deviation, contributors |
| Sleep score | score, contributors |
| Sleep periods | bed/wake times, total/deep/REM/light/awake minutes, efficiency, latency, average HRV, average and lowest HR, breathing rate |
| Activity | score, steps, calories, activity minutes, contributors |
| Heart rate | min/avg/max bpm per local hour (≤7 days) or day, by source |
| Workouts | activity, start/end, intensity, calories, distance |
| Stress | stress-high and recovery-high minutes, day summary |
| Resilience | level, contributors |
| SpO2 | average SpO2 %, breathing disturbance index |
| VO2 max | VO2 max |
| Cardiovascular age | vascular age |
Oura scopes requested: personal daily heartrate workout spo2 stress heart_health. Nothing else, not even email.
How it works and why it's safe
Claude ──/authorize──▶ consent page ──▶ Oura login ──▶ /callback
│ exchange code, read Oura user ID
│ ID == ALLOWED_OURA_USER_ID ? else 403, nothing stored
▼
MCP token issued (Oura tokens encrypted inside the grant)
Claude ──Bearer──▶ /mcp ──▶ tools ──▶ api.ouraring.com (GET only)
Claude ──refresh──▶ /token ──▶ Oura tokens refreshed automaticallyOnly your Oura account can connect. It's checked at login, on every token refresh, and on every request.
Your Oura tokens are stored encrypted inside the OAuth grant (via
@cloudflare/workers-oauth-provider), in your own Cloudflare account. No health data is stored anywhere.Health data and tokens are never logged. Only status lines are, such as
oura /v2/usercollection/sleep: HTTP 429.Rate limiting allows 30 tool calls per minute per connection.
The consent page follows MCP's confused-deputy guidance: it can't be framed or forged, and the state is bound to your browser.
Public pages:
the OAuth endpoints (
/authorize,/callback,/token,/register,/.well-known/*),/(setup checklist until configured) and/status(the same as JSON),static
/privacyand/termspages, which the Oura form asks for,/setup, which only works until your Oura ID is set and then switches itself off.
All settings live in Cloudflare secrets, never in code:
OURA_CLIENT_ID,OURA_CLIENT_SECRET,ALLOWED_OURA_USER_IDandTIMEZONE. The cookie-signing key is generated automatically and kept in your KV. You can setCOOKIE_ENCRYPTION_KEYyourself if you prefer./and/statusonly report whether settings exist (✅/⬜), never their values.
Built on Cloudflare's agents createMcpHandler (stateless Streamable HTTP) and MCP SDK v2.
Day-to-day
I want to… | Run |
Update to the latest version |
|
Change the Oura client ID/secret or timezone |
|
Rotate one secret |
|
See logs (status lines only) |
|
Check everything is OK |
|
Revoking access, from lightest to most complete:
In Claude, go to Settings → Connectors → Oura and click Disconnect.
In Oura, revoke the app under authorized apps, or delete it in the developer portal.
To block every client instantly, run
npx wrangler secret put ALLOWED_OURA_USER_IDand enterdisabled.To delete everything, run
npx wrangler delete, then delete theOAUTH_KVnamespace in the Cloudflare dashboard and the Oura app.
Local development (optional)
cp .dev.vars.example .dev.vars # Windows: copy .dev.vars.example .dev.vars
# fill in the values, and add these two lines:
# ALLOWED_OURA_USER_ID= (empty at first; the login page shows your ID)
# PUBLIC_BASE_URL=http://localhost:8788
npm run dev # http://localhost:8788
npx @modelcontextprotocol/inspector@latestAdd http://localhost:8788/callback as a redirect URI in your Oura app. In the Inspector, add a Streamable HTTP server with the URL http://localhost:8788/mcp.
npm test # unit tests
npm run type-checkTroubleshooting
These are real problems hit during setup, and their fixes.
Symptom | Fix |
"Oura sign-in failed: could not exchange the authorization code" / | The Client Secret doesn't match the Oura app. It was probably regenerated after you copied it. Copy it again, or regenerate it, then run |
"Access denied" after the Oura login | You signed in with a different Oura account than the allowlisted one. The page shows both IDs so you can compare. |
"Setup: allowlist not configured" |
|
Not sure what's missing | Open your Worker's home page, or run |
One tool returns 401/403 while others work | That scope wasn't ticked in your Oura app. SpO2, Stress and Heart Health are easy to miss. Tick it, then disconnect and reconnect in Claude. |
"Invalid redirect URI" in the MCP Inspector | The Inspector reused an old registration. Close all private windows, then open the Inspector in a new private window and add the server again. |
Local server hangs and pages never load (Windows) | Clicking inside a PowerShell window pauses the program in it ("Select" mode). Press Esc in that window, and from then on only click its title bar. |
| You pressed |
Local login works at | Use |
Inspector says "PORT IS IN USE" | An old Inspector is still running. Close its window, or on Windows run |
Windows: | Use |
For AI agents and tools
AGENTS.mdcovers setup, diagnosing problems, the architecture, the rules to keep and how to add a tool.CLAUDE.mdpoints to it.llms.txtis a short, machine-readable summary of this repo.npm run doctor -- --jsonis a non-interactive health check with anext_stepfield. It never prints secrets.GET <worker>/statusreturns JSON with the deployment's readiness, its Oura form values and the next step.
FAQ
Does my computer need to be on? No. After setup it runs on Cloudflare around the clock.
What does it cost? Nothing for personal use on Cloudflare's free plan. Oura API access needs an active Oura membership.
Can other people use my server? No. Only the one Oura account in ALLOWED_OURA_USER_ID can connect. Everyone else gets a 403 and nothing is stored.
Can I use a different timezone, or move? Yes. Run npm run setup -- --reconfigure, or npx wrangler secret put TIMEZONE, with an IANA name like Europe/London. Daylight saving is handled.
Can I add more tools? Yes. See src/tools.ts and AGENTS.md. Pull requests are welcome.
How is this different from other Oura MCP servers? Most run locally on your computer (stdio), so they don't work in the Claude mobile apps. This one is a remote server with OAuth and a single-user lock, made to be added as a Claude custom connector.
License
MIT. See LICENSE.
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.
Garmin data in Claude: 135 tools — activities, sleep, HRV, training, workouts. Free, open source.
Multi-tenant hosted MCP server for Oura Ring — 21 read-only tools, OAuth per user.
Related MCP Servers
- AlicenseBqualityFmaintenanceConnects your Oura Ring to AI assistants like Claude, providing human-readable insights about sleep, readiness, activity, and health metrics with smart analysis.2785 npm30MIT
- FlicenseNot gradedqualityDmaintenanceA private, read-only MCP server that lets Claude retrieve your Oura Ring health data for a daily check-in, self-hosted on Cloudflare with OAuth authentication.-
- AlicenseAqualityAmaintenanceEnables users to access and query Oura ring health data, including sleep periods, readiness, activity, workouts, heart rate, stress, SpO2, resilience, and more, through Claude.ai or Claude Code using the Oura API v2 with OAuth 2.1 login.1935 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables Claude to securely read your own WHOOP account data — recovery, HRV, resting heart rate, sleep, strain, workouts and body profile — through the official WHOOP developer API on a self-hosted server. Supports natural-language questions such as whether you are ready to train hard today.4 npmMIT