npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@iflow-mcp/meimakes-oura-mcp-server

v1.0.0

Published

MCP server for accessing Oura Ring data via OAuth2

Readme

Oura MCP Server

UPSTRM

MCP (Model Context Protocol) server that enables AI assistants to access your Oura Ring health data through OAuth2-authenticated API calls.

Built for seamless integration with Poke and other MCP-compatible clients. Deploy to Railway for production use or run locally for development.

Deploy on Railway

Features

  • OAuth2 with PKCE - Secure authentication with automatic token refresh
  • 9 MCP Tools - Access sleep, readiness, activity, heart rate, workouts, and more
  • Dual Transport Support - Both SSE and Streamable HTTP transports
  • Token Encryption - AES-256-GCM encryption for OAuth tokens at rest
  • Smart Caching - Reduce API calls with intelligent data caching
  • Rate Limiting - Built-in protection against API quota exhaustion
  • ngrok Support - Easy remote access for mobile and cloud integrations

Prerequisites

  • Node.js 18 or higher
  • Oura Ring (all generations supported - Gen 2, Gen 3, and Gen 4)
  • Oura account with API access
  • Railway account (recommended for production deployment) or ngrok (for local development)

Installation

  1. Clone the repository:
git clone https://github.com/meimakes/oura-mcp-server.git
cd oura-mcp-server
  1. Install dependencies:
npm install
  1. Copy the example environment file:
cp .env.example .env
  1. Generate required secrets:
# Generate AUTH_TOKEN
openssl rand -hex 32

# Generate TOKEN_ENCRYPTION_KEY
openssl rand -hex 32

Quick Start - Railway Deployment (Recommended)

Step 1: Deploy to Railway

  1. Click the button below to deploy to Railway:

Deploy on Railway

Or manually:

  • Go to Railway
  • Create new project from GitHub repo
  • Connect your fork of this repository
  1. Generate required secrets locally:
# Generate AUTH_TOKEN
openssl rand -hex 32

# Generate TOKEN_ENCRYPTION_KEY
openssl rand -hex 32
  1. In Railway dashboard, add environment variables:

    • AUTH_TOKEN - Your generated auth token
    • TOKEN_ENCRYPTION_KEY - Your generated encryption key
    • NODE_ENV - Set to production
    • CORS_ORIGIN - Set to * or your specific domain
    • PORT - Leave unset (Railway will auto-assign)
  2. Wait for deployment to complete and note your Railway URL (e.g., https://your-app.up.railway.app)

Step 2: Register Oura OAuth Application

  1. Go to https://cloud.ouraring.com/oauth/applications
  2. Click "Create New Application"
  3. Fill in:
    • Application Name: "Personal MCP Server" (or your choice)
    • Redirect URI: https://your-app.up.railway.app/oauth/callback
    • Scopes: Select all available scopes
  4. Save the Client ID and Client Secret

Step 3: Configure OAuth Credentials in Railway

Add these environment variables in Railway dashboard:

  • OURA_CLIENT_ID - Your Oura client ID
  • OURA_CLIENT_SECRET - Your Oura client secret
  • OURA_REDIRECT_URI - https://your-app.up.railway.app/oauth/callback

Railway will automatically redeploy with the new configuration.

Local Development Setup

Step 1: Set up ngrok

  1. Install and authenticate ngrok:
ngrok config add-authtoken YOUR_NGROK_TOKEN
  1. Start ngrok tunnel:
ngrok http 3001
  1. Note your ngrok URL (e.g., https://your-domain.ngrok.dev)

Step 2: Configure Environment Variables

Copy .env.example to .env and configure:

# MCP Server Authentication
AUTH_TOKEN=<generated-token>

# Oura OAuth Credentials
OURA_CLIENT_ID=<your-client-id>
OURA_CLIENT_SECRET=<your-client-secret>
OURA_REDIRECT_URI=https://your-domain.ngrok.dev/oauth/callback

# Server Configuration
PORT=3001
NODE_ENV=development

# Token Encryption
TOKEN_ENCRYPTION_KEY=<generated-key>

# CORS Origin
CORS_ORIGIN=*

# Logging (optional)
LOG_LEVEL=info  # Options: error, warn, info, debug

Usage

Starting the Server

  1. Build the TypeScript code:
npm run build
  1. Start the server:
npm start

For development with auto-reload:

npm run dev

Connecting Your Oura Account

  1. Open your browser to your server's /oauth/authorize endpoint:
    • Railway: https://your-app.up.railway.app/oauth/authorize
    • ngrok: https://your-domain.ngrok.dev/oauth/authorize
    • Local: http://localhost:3001/oauth/authorize
  2. Log in to your Oura account
  3. Approve the requested permissions
  4. You'll be redirected back with a success message

Connecting to MCP Clients

Poke

  1. Open Poke app
  2. Go to Settings → Integrations → Add Integration
  3. Select "Model Context Protocol (MCP)"
  4. Enter:
    • Name: Oura
    • Server URL: https://your-app.up.railway.app/sse (or your deployment URL)
    • API Key: Your AUTH_TOKEN from environment variables
  5. Tap "Add Integration"

The server supports both SSE and Streamable HTTP transports for maximum compatibility.

Other MCP Clients

Configure your MCP client with:

  • Server URL: https://your-app.up.railway.app/sse (or your deployment URL)
  • API Key (Bearer Token): Your AUTH_TOKEN from environment variables

Available MCP Tools

1. get_personal_info

Get user's personal information and ring details.

2. get_sleep_summary

Get sleep data for a date range.

Parameters:

  • start_date (required): YYYY-MM-DD
  • end_date (optional): YYYY-MM-DD
  • include_hrv (optional): boolean

3. get_readiness_score

Get daily readiness scores.

Parameters:

  • start_date (required): YYYY-MM-DD
  • end_date (optional): YYYY-MM-DD

4. get_activity_summary

Get activity data for a date range.

Parameters:

  • start_date (required): YYYY-MM-DD
  • end_date (optional): YYYY-MM-DD

5. get_heart_rate

Get heart rate data in 5-minute intervals.

Parameters:

  • start_datetime (required): ISO 8601 format
  • end_datetime (optional): ISO 8601 format

6. get_workouts

Get workout sessions.

Parameters:

  • start_date (required): YYYY-MM-DD
  • end_date (optional): YYYY-MM-DD

7. get_sleep_detailed

Get detailed sleep period data with heart rate and HRV.

Parameters:

  • start_date (required): YYYY-MM-DD
  • end_date (optional): YYYY-MM-DD

8. get_tags

Get user-created tags and notes.

Parameters:

  • start_date (required): YYYY-MM-DD
  • end_date (optional): YYYY-MM-DD

9. get_health_insights

Get AI-powered insights based on recent data.

Parameters:

  • days (optional): Number of days to analyze (default: 7)

API Endpoints

Health Check

GET /health

Returns server status, OAuth connection status, and cache statistics.

OAuth Endpoints

GET  /oauth/authorize     - Start OAuth flow
GET  /oauth/callback      - OAuth callback (automatic)
GET  /oauth/status        - Get connection status (requires auth)
POST /oauth/disconnect    - Disconnect and clear tokens (requires auth)

MCP Endpoints

The server supports both transport modes:

Streamable HTTP (recommended for Poke):

POST /sse                 - JSON-RPC requests with direct responses

Classic SSE:

GET  /sse                 - Establish SSE connection
POST /message             - Send JSON-RPC requests via session

Security

Token Encryption

All OAuth tokens are encrypted at rest using AES-256-GCM encryption.

Authentication

MCP endpoints require Bearer token authentication:

Authorization: Bearer YOUR_AUTH_TOKEN

Rate Limiting

  • MCP endpoints: 100 requests per 15 minutes per IP
  • Oura API: 5000 requests per day (tracked automatically)

CORS

Configure allowed origins in .env with CORS_ORIGIN.

Logging

The server uses structured logging with configurable log levels:

  • error - Only critical errors (recommended for production)
  • warn - Warnings and errors
  • info - Key operations, warnings, and errors (default)
  • debug - Full verbosity including request/response bodies

Configure via the LOG_LEVEL environment variable:

LOG_LEVEL=info  # Default - balanced logging
LOG_LEVEL=error # Production - minimal output
LOG_LEVEL=debug # Development - verbose debugging

What gets logged at each level:

  • Error: Authentication failures, API errors, OAuth failures, rate limits
  • Warn: Invalid API key attempts, missing SSE sessions
  • Info: SSE connections, tool executions, OAuth operations, MCP method calls
  • Debug: Full JSON-RPC requests/responses, connection lifecycle events

Troubleshooting

OAuth Callback Failed

  • Verify redirect URI matches exactly in Oura app settings
  • Ensure your server is accessible (Railway deployed or ngrok running for local)
  • Check OURA_CLIENT_ID and OURA_CLIENT_SECRET are correct
  • Confirm OURA_REDIRECT_URI matches your deployment URL

Token Refresh Failed

  • Verify TOKEN_ENCRYPTION_KEY is set correctly and hasn't changed
  • Check tokens.json file exists and is readable
  • Ensure refresh token hasn't been revoked in Oura account
  • For Railway: Check that persistent storage is enabled

Rate Limit Exceeded

  • Caching is built-in with 5-minute default TTL
  • Reduce polling frequency in your MCP client
  • Check rate limit headers in API responses
  • Monitor usage at /health endpoint

Railway-Specific Issues

Server not starting:

  • Check Railway logs for errors
  • Verify all required environment variables are set
  • Ensure PORT variable is NOT set (Railway auto-assigns)
  • Check build logs for TypeScript compilation errors

OAuth redirect failing:

  • Verify OURA_REDIRECT_URI uses your Railway domain
  • Check that Railway deployment is public (not private networking only)
  • Ensure HTTPS is used in redirect URI (Railway provides this automatically)

Tokens not persisting:

  • Railway provides persistent storage by default for tokens.json
  • Check application logs for file write errors
  • Verify disk usage hasn't exceeded limits

Local Development Issues

ngrok connection issues:

  • Restart ngrok tunnel
  • Update OURA_REDIRECT_URI if ngrok URL changed
  • Verify ngrok authentication token is valid
  • Check ngrok isn't blocked by firewall

Development

Project Structure

oura-mcp-server/
├── src/
│   ├── index.ts              # Main server file
│   ├── oauth/
│   │   ├── handler.ts        # OAuth flow handler
│   │   └── tokens.ts         # Token management
│   ├── mcp/
│   │   ├── server.ts         # MCP protocol implementation
│   │   └── tools.ts          # Tool definitions
│   ├── oura/
│   │   ├── client.ts         # Oura API client
│   │   └── types.ts          # TypeScript types
│   ├── utils/
│   │   ├── encryption.ts     # Token encryption
│   │   ├── cache.ts          # Data caching
│   │   └── validation.ts     # Input validation
│   └── middleware/
│       ├── auth.ts           # Authentication middleware
│       └── errorHandler.ts   # Error handling
├── .env                      # Environment variables (gitignored)
├── tokens.json               # Encrypted tokens (gitignored)
├── package.json
├── tsconfig.json
└── README.md

Running Tests

npm test

Type Checking

npm run typecheck

Linting

npm run lint

Deployment Options

Option 1: Railway (Recommended)

  • Cost: Free tier available, pay-as-you-grow
  • Setup Time: ~5 minutes
  • Benefits:
    • Always available (24/7 uptime)
    • Automatic deployments from GitHub
    • Built-in HTTPS
    • No server management required
    • Persistent storage for tokens
  • Best for: Production use, mobile access, sharing with others

Option 2: Local Development

  • Cost: Free (ngrok free tier)
  • Setup Time: ~10 minutes
  • Benefits:
    • Complete data privacy (tokens stay local)
    • No hosting costs
    • Full control over environment
  • Limitations:
    • Requires computer to be running
    • ngrok URL changes on restart (free tier)
  • Best for: Development, testing, personal use

Option 3: Cloud VM (VPS)

  • Deploy to DigitalOcean, AWS EC2, Google Cloud, etc.
  • Always available with static IP
  • More control but requires server management

Option 4: Docker

docker build -t oura-mcp-server .
docker run -p 3001:3001 --env-file .env oura-mcp-server

Can be deployed to any Docker-compatible platform (Fly.io, Render, etc.)

License

MIT

Support

For issues or questions:

  • GitHub Issues: https://github.com/meimakes/oura-mcp-server/issues
  • Oura API Docs: https://cloud.ouraring.com/docs
  • MCP Protocol: https://modelcontextprotocol.io

Contributing

Contributions are welcome! Please read CONTRIBUTING.md for details.