oura-mcp-server
Click on "Install 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-serverHow was my sleep last night?"
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 Ring MCP Server
A comprehensive Model Context Protocol (MCP) server for the Oura Ring API V2. Access sleep, activity, readiness, heart rate, stress, and other health data from your Oura Ring through AI assistants like Claude, ChatGPT, or Cursor IDE.
Security First: This server implements read-only operations only for user data. Your health information cannot be modified.
What is This?
This MCP server allows AI assistants to access your Oura Ring health data. When connected, you can ask questions like:
"How did I sleep last night?"
"What's my readiness score this week?"
"Show me my heart rate trends"
"Analyze my stress patterns"
Keywords: Oura Ring, MCP Server, Model Context Protocol, Sleep Tracking, Health Data, Wearable API, AI Integration, Claude, ChatGPT, Cursor
Related MCP server: Oura Ring MCP Server
Table of Contents
What is Oura Ring?
Oura Ring is a smart ring that tracks:
Sleep - Sleep stages (deep, light, REM), sleep quality, timing
Activity - Steps, calories, movement throughout the day
Readiness - Recovery score based on sleep, activity, and body signals
Heart Rate - Continuous heart rate and HRV (heart rate variability)
Body Temperature - Skin temperature deviations
Stress - Daytime stress and recovery patterns
SpO2 - Blood oxygen saturation levels
This MCP server provides access to all this data through the Oura API V2.
Features
Feature | Description |
37 MCP Tools | Complete coverage of all Oura API V2 endpoints |
Read-only by design | Cannot modify user data |
OAuth2 Authentication | Secure token-based authentication with refresh token support |
Automatic Token Refresh | Automatically refreshes expired access tokens |
Sandbox Support | Test with mock data before using real data |
Rate Limiting | Built-in rate limiting with exponential backoff |
Token Sanitization | Access tokens are never exposed in logs or errors |
Quick Start
1. Clone and Install
git clone https://github.com/trenerok/oura-mcp-server.git
cd oura-mcp-server
npm install2. Get OAuth2 Credentials
See Getting an Access Token below.
3. Build
npm run build4. Configure MCP Client
See MCP Client Setup for Claude Desktop, Cursor IDE, or other clients.
Getting an Access Token
Oura uses OAuth2 for authentication. Personal access tokens were deprecated in December 2025.
Step 1: Create an OAuth2 Application
Go to Oura Cloud Applications
Click "New Application"
Fill in the required fields:
Display Name: Your app name (e.g., "My MCP Server")
Description: Brief description
Website: Your website or GitHub repo URL
Privacy Policy: URL (can be your GitHub repo for personal use)
Terms of Service: URL (can be your GitHub repo for personal use)
Redirect URI:
http://localhost:8080/callback
Select all the Scopes you want to access
Click "Create Application"
Copy your Client ID and Client Secret
Step 2: Get Access Token
Use the included helper script:
node scripts/get-token.js YOUR_CLIENT_ID YOUR_CLIENT_SECRETThis will:
Open your browser to authorize the application
Exchange the authorization code for tokens
Display your access token and refresh token
Step 3: Save Your Tokens
Add the tokens to your MCP configuration (see MCP Client Setup).
Configuration
Environment Variables
Variable | Required | Description |
| Yes* | OAuth2 access token for user data |
| No | Refresh token for automatic token renewal |
| No** | OAuth2 application client ID |
| No** | OAuth2 application client secret |
| No | Set to |
* Required for user data endpoints ** Required for token refresh and webhook management
Automatic Token Refresh
If you provide OURA_REFRESH_TOKEN, OURA_CLIENT_ID, and OURA_CLIENT_SECRET, the server will automatically refresh your access token when it expires (typically after 24 hours).
MCP Client Setup
Claude Desktop
Add to your claude_desktop_config.json:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"oura": {
"command": "node",
"args": ["/absolute/path/to/oura-mcp-server/dist/index.js"],
"env": {
"OURA_ACCESS_TOKEN": "your_access_token",
"OURA_REFRESH_TOKEN": "your_refresh_token",
"OURA_CLIENT_ID": "your_client_id",
"OURA_CLIENT_SECRET": "your_client_secret"
}
}
}
}Cursor IDE
Add to .cursor/mcp.json in your project directory:
{
"mcpServers": {
"oura": {
"command": "node",
"args": ["./dist/index.js"],
"env": {
"OURA_ACCESS_TOKEN": "your_access_token",
"OURA_REFRESH_TOKEN": "your_refresh_token",
"OURA_CLIENT_ID": "your_client_id",
"OURA_CLIENT_SECRET": "your_client_secret"
}
}
}
}Other MCP Clients
Use similar configuration with the appropriate config file format for your client.
Available Tools (37 Total)
Overview by Category
Category | Count | Tools |
Personal Info | 1 | User profile (age, weight, height) |
Sleep | 6 | Sleep sessions, daily scores, bedtime recommendations |
Activity | 2 | Daily activity, steps, calories burned |
Health Metrics | 14 | Heart rate, readiness, SpO2, stress, resilience, cardiovascular age, VO2 max |
Workouts | 4 | Workout sessions, meditation/breathing sessions |
Tags | 4 | User-created tags and enhanced tags |
Device | 4 | Ring configuration, rest mode periods |
Webhooks | 6 | Webhook subscription management |
Complete Tool List
Personal Info (1 tool)
Tool | Description |
| Get user profile: age, weight, height, biological sex, email |
Sleep (6 tools)
Tool | Description |
| Detailed sleep sessions with stages (deep, light, REM), HRV, heart rate |
| Single sleep session by document ID |
| Daily sleep scores with contributor breakdown |
| Single daily sleep document by ID |
| Optimal bedtime recommendations |
| Single sleep time document by ID |
Activity (2 tools)
Tool | Description |
| Daily steps, calories, active time, MET minutes |
| Single daily activity document by ID |
Health Metrics (14 tools)
Tool | Description |
| Heart rate time series (BPM with timestamps) |
| Daily readiness scores with contributors |
| Single readiness document by ID |
| Blood oxygen saturation (SpO2) data |
| Single SpO2 document by ID |
| Daily stress levels and recovery time |
| Single stress document by ID |
| Daily resilience scores |
| Single resilience document by ID |
| Vascular age estimates |
| Single cardiovascular age document by ID |
| VO2 max estimates (cardiovascular fitness) |
| Single VO2 max document by ID |
Workouts (4 tools)
Tool | Description |
| Workout sessions (activity type, calories, distance, duration) |
| Single workout document by ID |
| Meditation and breathing sessions with HRV data |
| Single session document by ID |
Tags (4 tools)
Tool | Description |
| User-created tags for tracking behaviors |
| Single tag document by ID |
| Enhanced tags with metadata and time ranges |
| Single enhanced tag document by ID |
Device (4 tools)
Tool | Description |
| Ring details: color, size, firmware, hardware type |
| Single ring configuration by ID |
| Rest mode activation history |
| Single rest mode period by ID |
Webhooks (6 tools) - Requires Client Credentials
Tool | Description |
| List all webhook subscriptions |
| Get a specific webhook by ID |
| Create new webhook subscription |
| Update existing webhook |
| Delete a webhook subscription |
| Renew webhook before expiration |
Tool Reference
Common Parameters
Date Range Parameters (most tools)
Parameter | Format | Required | Description |
|
| No | Start of date range |
|
| No | End of date range |
| string | No | Pagination token for next page |
DateTime Parameters (heart rate only)
Parameter | Format | Required | Description |
| ISO 8601 | No | Start datetime (e.g., |
| ISO 8601 | No | End datetime |
| string | No | Pagination token |
Example Responses
Personal Info
{
"id": "abc123",
"age": 35,
"weight": 75.5,
"height": 1.80,
"biological_sex": "male",
"email": "user@example.com"
}Daily Sleep
{
"data": [
{
"id": "sleep123",
"day": "2024-01-15",
"score": 85,
"contributors": {
"deep_sleep": 80,
"efficiency": 90,
"latency": 85,
"rem_sleep": 75,
"restfulness": 82,
"timing": 95,
"total_sleep": 88
},
"timestamp": "2024-01-15T00:00:00.000+00:00"
}
],
"next_token": null
}Daily Readiness
{
"data": [
{
"id": "ready123",
"day": "2024-01-15",
"score": 78,
"contributors": {
"activity_balance": 85,
"body_temperature": 100,
"hrv_balance": 72,
"previous_day_activity": 80,
"previous_night": 75,
"recovery_index": 90,
"resting_heart_rate": 82,
"sleep_balance": 70
},
"temperature_deviation": 0.1,
"timestamp": "2024-01-15T00:00:00.000+00:00"
}
],
"next_token": null
}Heart Rate
{
"data": [
{
"bpm": 62,
"source": "awake",
"timestamp": "2024-01-15T08:30:00+00:00"
},
{
"bpm": 58,
"source": "rest",
"timestamp": "2024-01-15T08:35:00+00:00"
}
],
"next_token": null
}For AI Agents
This section provides structured guidance for AI agents using this MCP server.
Server Capabilities
Data Access: Read-only access to all Oura Ring health data
Authentication: OAuth2 Bearer token with automatic refresh
Real-time Data: Data is fetched live from Oura API
Pagination: Large datasets return
next_tokenfor pagination
Quick Start for AI Agents
Verify connectivity: Call
get_personal_infofirstUse date ranges: Always specify
start_dateto limit dataHandle empty data: Empty arrays mean no data for that period
Check null values: Many fields may be null if unavailable
Recommended Workflows
Health Dashboard
1. get_personal_info() → Get user profile
2. get_daily_readiness(start_date: "<7 days ago>") → Weekly readiness trend
3. get_daily_sleep(start_date: "<7 days ago>") → Weekly sleep scores
4. get_daily_activity(start_date: "<7 days ago>") → Weekly activity
5. get_daily_stress(start_date: "<7 days ago>") → Weekly stress patternsSleep Analysis
1. get_daily_sleep(start_date: "<30 days ago>") → Monthly sleep scores
2. get_sleep(start_date: "<7 days ago>") → Detailed sleep sessions with stages
3. get_sleep_time(start_date: "<7 days ago>") → Bedtime recommendationsFitness Assessment
1. get_daily_activity(start_date: "<30 days ago>") → Activity trends
2. get_workouts(start_date: "<30 days ago>") → Workout history
3. get_vo2_max(start_date: "<30 days ago>") → Cardiovascular fitness
4. get_heart_rate(start_datetime: "<today>T00:00:00Z") → Today's heart rateStress & Recovery
1. get_daily_stress(start_date: "<7 days ago>") → Stress levels
2. get_daily_resilience(start_date: "<7 days ago>") → Resilience scores
3. get_daily_readiness(start_date: "<7 days ago>") → Recovery statusKey Metrics Explained
Metric | Range | Meaning |
Sleep Score | 0-100 | Overall sleep quality (>85 = optimal) |
Readiness Score | 0-100 | Recovery level (>85 = ready for activity) |
Activity Score | 0-100 | Daily movement goal progress |
Stress (high) | seconds | Time in high stress state |
Recovery (high) | seconds | Time in recovery/rest state |
HRV | ms | Heart rate variability (higher = better recovery) |
Resting HR | bpm | Resting heart rate (lower = better fitness) |
Error Handling
Error | Cause | Solution |
| Missing OURA_ACCESS_TOKEN | Add token to config |
| Token expired | Server auto-refreshes if refresh token provided |
| Scope not authorized | Re-authorize with required scopes |
| Too many requests | Server auto-retries with backoff |
Empty | No data for date range | Try different date range |
Important Notes
Date Format: Use
YYYY-MM-DDfor datesDatetime Format: Use ISO 8601 for
get_heart_rate(e.g.,2024-01-15T00:00:00Z)Timezone: Data is returned in user's timezone
Pagination: If
next_tokenis not null, more data is availableNull Values: Fields may be null if ring wasn't worn or data unavailable
Rate Limiting
The server implements automatic rate limiting per Oura API documentation.
Limit | Value |
Requests | 5000 per 5 minutes |
Algorithm | Token bucket with refill |
Retry | Exponential backoff (1s → 2s → 4s, max 30s) |
Max Retries | 3 attempts |
Project Structure
oura-mcp-server/
├── src/
│ ├── index.ts # MCP server entry point
│ ├── client.ts # Oura API client with auth & rate limiting
│ ├── rate-limiter.ts # Token bucket rate limiter
│ ├── types.ts # TypeScript type definitions
│ └── tools/
│ ├── index.ts # Tool aggregator
│ ├── personal-info.ts
│ ├── sleep.ts
│ ├── activity.ts
│ ├── health.ts
│ ├── workout.ts
│ ├── tags.ts
│ ├── device.ts
│ └── webhook.ts
├── scripts/
│ └── get-token.js # OAuth2 token helper
├── dist/ # Compiled JavaScript
├── package.json
├── tsconfig.json
├── .env.example
├── .gitignore
├── LICENSE
├── CHANGELOG.md
└── README.mdSecurity
Best Practices
Never commit tokens — Use environment variables
Use refresh tokens — Enable automatic token renewal
Test with sandbox — Set
OURA_USE_SANDBOX=truefor developmentLimit scopes — Only request OAuth2 scopes you need
Security Features
Access tokens sanitized from all error messages
Read-only API access (cannot modify data)
Automatic token refresh (no manual token management)
Rate limiting prevents API abuse
Troubleshooting
Common Issues
Issue | Solution |
| Run |
| Add |
| Token expired; add refresh token or get new token |
| Missing OAuth2 scope; re-authorize app |
Empty data returned | Check date range; ensure ring synced data |
| Re-create OAuth2 app with required scopes |
Getting Help
Check Oura API Documentation
Open an issue on GitHub
Development
# Install dependencies
npm install
# Build TypeScript
npm run build
# Watch mode (auto-rebuild)
npm run dev
# Run server
npm start
# Clean build
npm run cleanContributing
Fork the repository
Create a feature branch:
git checkout -b feature/my-featureMake changes and test:
npm run buildCommit:
git commit -m "Add my feature"Push:
git push origin feature/my-featureCreate a Pull Request
API Reference
License
MIT License — see LICENSE file.
Disclaimer
This software is provided "as is" without warranty. This project is not affiliated with or endorsed by Oura Health Oy.
Not medical advice. Oura Ring data is for informational purposes only and should not be used for medical diagnosis or treatment.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/trenerok/oura-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server