Skip to main content
Glama
trenerok

oura-mcp-server

by trenerok

Oura Ring MCP Server

License: MIT Node.js MCP

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 install

2. Get OAuth2 Credentials

See Getting an Access Token below.

3. Build

npm run build

4. 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

  1. Go to Oura Cloud Applications

  2. Click "New Application"

  3. 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

  4. Select all the Scopes you want to access

  5. Click "Create Application"

  6. 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_SECRET

This will:

  1. Open your browser to authorize the application

  2. Exchange the authorization code for tokens

  3. 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

OURA_ACCESS_TOKEN

Yes*

OAuth2 access token for user data

OURA_REFRESH_TOKEN

No

Refresh token for automatic token renewal

OURA_CLIENT_ID

No**

OAuth2 application client ID

OURA_CLIENT_SECRET

No**

OAuth2 application client secret

OURA_USE_SANDBOX

No

Set to true for sandbox/mock data

* 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_personal_info

Get user profile: age, weight, height, biological sex, email

Sleep (6 tools)

Tool

Description

get_sleep

Detailed sleep sessions with stages (deep, light, REM), HRV, heart rate

get_sleep_by_id

Single sleep session by document ID

get_daily_sleep

Daily sleep scores with contributor breakdown

get_daily_sleep_by_id

Single daily sleep document by ID

get_sleep_time

Optimal bedtime recommendations

get_sleep_time_by_id

Single sleep time document by ID

Activity (2 tools)

Tool

Description

get_daily_activity

Daily steps, calories, active time, MET minutes

get_daily_activity_by_id

Single daily activity document by ID

Health Metrics (14 tools)

Tool

Description

get_heart_rate

Heart rate time series (BPM with timestamps)

get_daily_readiness

Daily readiness scores with contributors

get_daily_readiness_by_id

Single readiness document by ID

get_daily_spo2

Blood oxygen saturation (SpO2) data

get_daily_spo2_by_id

Single SpO2 document by ID

get_daily_stress

Daily stress levels and recovery time

get_daily_stress_by_id

Single stress document by ID

get_daily_resilience

Daily resilience scores

get_daily_resilience_by_id

Single resilience document by ID

get_daily_cardiovascular_age

Vascular age estimates

get_daily_cardiovascular_age_by_id

Single cardiovascular age document by ID

get_vo2_max

VO2 max estimates (cardiovascular fitness)

get_vo2_max_by_id

Single VO2 max document by ID

Workouts (4 tools)

Tool

Description

get_workouts

Workout sessions (activity type, calories, distance, duration)

get_workout_by_id

Single workout document by ID

get_sessions

Meditation and breathing sessions with HRV data

get_session_by_id

Single session document by ID

Tags (4 tools)

Tool

Description

get_tags

User-created tags for tracking behaviors

get_tag_by_id

Single tag document by ID

get_enhanced_tags

Enhanced tags with metadata and time ranges

get_enhanced_tag_by_id

Single enhanced tag document by ID

Device (4 tools)

Tool

Description

get_ring_configuration

Ring details: color, size, firmware, hardware type

get_ring_configuration_by_id

Single ring configuration by ID

get_rest_mode_periods

Rest mode activation history

get_rest_mode_period_by_id

Single rest mode period by ID

Webhooks (6 tools) - Requires Client Credentials

Tool

Description

list_webhook_subscriptions

List all webhook subscriptions

get_webhook_subscription

Get a specific webhook by ID

create_webhook_subscription

Create new webhook subscription

update_webhook_subscription

Update existing webhook

delete_webhook_subscription

Delete a webhook subscription

renew_webhook_subscription

Renew webhook before expiration


Tool Reference

Common Parameters

Date Range Parameters (most tools)

Parameter

Format

Required

Description

start_date

YYYY-MM-DD

No

Start of date range

end_date

YYYY-MM-DD

No

End of date range

next_token

string

No

Pagination token for next page

DateTime Parameters (heart rate only)

Parameter

Format

Required

Description

start_datetime

ISO 8601

No

Start datetime (e.g., 2024-01-01T00:00:00Z)

end_datetime

ISO 8601

No

End datetime

next_token

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_token for pagination

Quick Start for AI Agents

  1. Verify connectivity: Call get_personal_info first

  2. Use date ranges: Always specify start_date to limit data

  3. Handle empty data: Empty arrays mean no data for that period

  4. Check null values: Many fields may be null if unavailable

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 patterns

Sleep 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 recommendations

Fitness 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 rate

Stress & 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 status

Key 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

Access token not configured

Missing OURA_ACCESS_TOKEN

Add token to config

401 Unauthorized

Token expired

Server auto-refreshes if refresh token provided

403 Forbidden

Scope not authorized

Re-authorize with required scopes

429 Rate Limit

Too many requests

Server auto-retries with backoff

Empty data: []

No data for date range

Try different date range

Important Notes

  • Date Format: Use YYYY-MM-DD for dates

  • Datetime 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_token is not null, more data is available

  • Null 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.md

Security

Best Practices

  1. Never commit tokens — Use environment variables

  2. Use refresh tokens — Enable automatic token renewal

  3. Test with sandbox — Set OURA_USE_SANDBOX=true for development

  4. Limit 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

Cannot find module

Run npm run build

Access token not configured

Add OURA_ACCESS_TOKEN to env

401 Unauthorized

Token expired; add refresh token or get new token

403 Forbidden

Missing OAuth2 scope; re-authorize app

Empty data returned

Check date range; ensure ring synced data

Token not authorized for scope

Re-create OAuth2 app with required scopes

Getting Help

  1. Check Oura API Documentation

  2. Open an issue on GitHub

  3. Check MCP Protocol Documentation


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 clean

Contributing

  1. Fork the repository

  2. Create a feature branch: git checkout -b feature/my-feature

  3. Make changes and test: npm run build

  4. Commit: git commit -m "Add my feature"

  5. Push: git push origin feature/my-feature

  6. Create 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.

A
license - permissive license
-
quality - not tested
D
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

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