Oura MCP Server
Enables AI assistants to access Oura Ring health data including sleep, readiness, activity, heart rate, and workouts through OAuth2-authenticated API calls with automatic token refresh and smart caching.
README
Oura MCP Server
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.
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
- Clone the repository:
git clone https://github.com/meimakes/oura-mcp-server.git
cd oura-mcp-server
- Install dependencies:
npm install
- Copy the example environment file:
cp .env.example .env
- 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
- Click the button below to deploy to Railway:
Or manually:
- Go to Railway
- Create new project from GitHub repo
- Connect your fork of this repository
- Generate required secrets locally:
# Generate AUTH_TOKEN
openssl rand -hex 32
# Generate TOKEN_ENCRYPTION_KEY
openssl rand -hex 32
-
In Railway dashboard, add environment variables:
AUTH_TOKEN- Your generated auth tokenTOKEN_ENCRYPTION_KEY- Your generated encryption keyNODE_ENV- Set toproductionCORS_ORIGIN- Set to*or your specific domainPORT- Leave unset (Railway will auto-assign)
-
Wait for deployment to complete and note your Railway URL (e.g.,
https://your-app.up.railway.app)
Step 2: Register Oura OAuth Application
- Go to https://cloud.ouraring.com/oauth/applications
- Click "Create New Application"
- 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
- 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 IDOURA_CLIENT_SECRET- Your Oura client secretOURA_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
- Install and authenticate ngrok:
ngrok config add-authtoken YOUR_NGROK_TOKEN
- Start ngrok tunnel:
ngrok http 3001
- 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
- Build the TypeScript code:
npm run build
- Start the server:
npm start
For development with auto-reload:
npm run dev
Connecting Your Oura Account
- Open your browser to your server's
/oauth/authorizeendpoint:- Railway:
https://your-app.up.railway.app/oauth/authorize - ngrok:
https://your-domain.ngrok.dev/oauth/authorize - Local:
http://localhost:3001/oauth/authorize
- Railway:
- Log in to your Oura account
- Approve the requested permissions
- You'll be redirected back with a success message
Connecting to MCP Clients
Poke
- Open Poke app
- Go to Settings → Integrations → Add Integration
- Select "Model Context Protocol (MCP)"
- Enter:
- Name: Oura
- Server URL:
https://your-app.up.railway.app/sse(or your deployment URL) - API Key: Your
AUTH_TOKENfrom environment variables
- 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_TOKENfrom 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-DDend_date(optional): YYYY-MM-DDinclude_hrv(optional): boolean
3. get_readiness_score
Get daily readiness scores.
Parameters:
start_date(required): YYYY-MM-DDend_date(optional): YYYY-MM-DD
4. get_activity_summary
Get activity data for a date range.
Parameters:
start_date(required): YYYY-MM-DDend_date(optional): YYYY-MM-DD
5. get_heart_rate
Get heart rate data in 5-minute intervals.
Parameters:
start_datetime(required): ISO 8601 formatend_datetime(optional): ISO 8601 format
6. get_workouts
Get workout sessions.
Parameters:
start_date(required): YYYY-MM-DDend_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-DDend_date(optional): YYYY-MM-DD
8. get_tags
Get user-created tags and notes.
Parameters:
start_date(required): YYYY-MM-DDend_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 errorsinfo- 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_IDandOURA_CLIENT_SECRETare correct - Confirm
OURA_REDIRECT_URImatches your deployment URL
Token Refresh Failed
- Verify
TOKEN_ENCRYPTION_KEYis set correctly and hasn't changed - Check
tokens.jsonfile 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
/healthendpoint
Railway-Specific Issues
Server not starting:
- Check Railway logs for errors
- Verify all required environment variables are set
- Ensure
PORTvariable is NOT set (Railway auto-assigns) - Check build logs for TypeScript compilation errors
OAuth redirect failing:
- Verify
OURA_REDIRECT_URIuses 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_URIif 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.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。