Skip to main content
Glama
AdamWalt

Oura MCP Server (Python)

by AdamWalt
README.md
# Oura MCP Server (Python)

A Python implementation of a Model Context Protocol (MCP) server for accessing Oura Ring health data with OAuth2 authentication.

## Features

- **OAuth2 Authentication** - Secure authentication with automatic token refresh
- **9 MCP Tools** - Access sleep, readiness, activity, heart rate, workouts, and more
- **Token Encryption** - AES-256 encryption for OAuth tokens at rest
- **Health Insights** - Aggregated health trend analysis
- **Pure Python** - Built with FastMCP and Starlette

## Prerequisites

- Python 3.11 or higher
- Oura Ring with an active Oura account
- Oura API access (OAuth application)

## Installation

### Option 1: Install from source

```bash
# Clone or download this repository
cd oura-mcp-python

# Create virtual environment (recommended)
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install the package
pip install -e .
```

### Option 2: Install with uv (faster)

```bash
cd oura-mcp-python
uv pip install -e .
```

## Configuration

### Step 1: Register an Oura OAuth Application

1. Go to [Oura OAuth Applications](https://cloud.ouraring.com/oauth/applications)
2. Log in with your Oura account
3. Click **"New Application"**
4. Fill in:
   - **Application Name:** `Personal MCP Server`
   - **Redirect URI:** `http://localhost:8000/oauth/callback`
   - **Scopes:** Select all available scopes
5. Save and copy your **Client ID** and **Client Secret**

### Step 2: Create Environment File

```bash
cp .env.example .env   # copy the template
# then edit .env with your credentials
```

> Note: `.env` is gitignored; `.env.example` is the committed template.

### Step 3: Generate Encryption Key

```python
# Run this in Python to generate TOKEN_ENCRYPTION_KEY
import secrets
print("TOKEN_ENCRYPTION_KEY:", secrets.token_hex(32))
```

### Step 4: Configure .env

Edit your `.env` file:

```env
# Oura OAuth Credentials
OURA_CLIENT_ID=your_client_id_here
OURA_CLIENT_SECRET=your_client_secret_here
OURA_REDIRECT_URI=http://localhost:8000/oauth/callback

# Token Encryption
TOKEN_ENCRYPTION_KEY=<generated_encryption_key>

# Server Configuration (optional; defaults shown)
HOST=0.0.0.0
PORT=8000
```

## Running the Server

### Start the Server

```bash
# Using the installed command
oura-mcp

# Or directly with Python
python -m oura_mcp.server

# Or with uvicorn for development
uvicorn oura_mcp.server:create_app --factory --reload --port 8000
```

### Connect Your Oura Account

1. Open your browser to: `http://localhost:8000/oauth/authorize`
2. Log in to your Oura account
3. Approve the requested permissions
4. You'll see a success message when connected

### Verify Connection

Check the health endpoint:
```bash
curl http://localhost:8000/health
```

Expected response:
```json
{
  "status": "healthy",
  "oauth_connected": true,
  "server": "Oura MCP Server (Python)",
  "version": "1.0.0"
}
```

## Connecting to Claude Desktop

Add this to your Claude Desktop config file:

**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "oura": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "http://localhost:8000/mcp"],
      "env": {
        "API_KEY": "YOUR_AUTH_TOKEN_HERE"
      }
    }
  }
}
```

**Alternative: Direct stdio connection** (if running locally)

```json
{
  "mcpServers": {
    "oura": {
      "command": "python",
      "args": ["-m", "oura_mcp.server"],
      "cwd": "/path/to/oura-mcp-python",
      "env": {
        "OURA_CLIENT_ID": "your_client_id",
        "OURA_CLIENT_SECRET": "your_client_secret",
        "OURA_REDIRECT_URI": "http://localhost:8000/oauth/callback"
      }
    }
  }
}
```

Restart Claude Desktop after saving.

## 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_detailed` (optional): Include detailed sleep period data

### 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 (e.g., 2024-01-01T00:00:00)
- `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_tags
Get user-created tags and notes.

**Parameters:**
- `start_date` (required): YYYY-MM-DD
- `end_date` (optional): YYYY-MM-DD

### 8. get_sessions
Get guided and unguided session data.

**Parameters:**
- `start_date` (required): YYYY-MM-DD
- `end_date` (optional): YYYY-MM-DD

### 9. get_health_insights
Get aggregated health insights based on recent data.

**Parameters:**
- `days` (optional): Number of days to analyze (default: 7)

### 10. get_connection_status
Check if the Oura account is connected and tokens are valid.

## API Endpoints

### Health Check
```
GET /health
```

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

### MCP Endpoint
```
POST /mcp                 - MCP JSON-RPC endpoint (Streamable HTTP)
```

## Deployment Options

### Option 1: Local Development
Run on your machine with the server accessible at localhost.

### Option 2: Railway / Cloud Deployment
1. Push to a Git repository
2. Deploy to Railway, Render, or similar
3. Update `OURA_REDIRECT_URI` to your deployed URL
4. Update your Oura OAuth application's redirect URI

### Option 3: Docker

```dockerfile
FROM python:3.11-slim

WORKDIR /app
COPY . .
RUN pip install -e .

EXPOSE 8000
CMD ["oura-mcp"]
```

```bash
docker build -t oura-mcp-python .
docker run -p 8000:8000 --env-file .env oura-mcp-python
```

## Troubleshooting

### "Not authenticated" errors
- Visit `/oauth/authorize` to connect your Oura account
- Check that your OAuth credentials are correct in `.env`

### Token refresh fails
- Ensure `TOKEN_ENCRYPTION_KEY` hasn't changed
- Try disconnecting (`POST /oauth/disconnect`) and reconnecting

### "Invalid redirect URI" from Oura
- Ensure your `OURA_REDIRECT_URI` exactly matches what's configured in your Oura OAuth application
- Include the full path: `http://localhost:8000/oauth/callback`

### Claude Desktop doesn't see the tools
- Verify the server is running: `curl http://localhost:8000/health`
- Check Claude Desktop logs: Help → Open Logs Folder
- Ensure `mcp-remote` is available: `npx -y mcp-remote --help`

## Development

### Running Tests
```bash
pip install -e ".[dev]"
pytest
```

### Code Formatting
```bash
ruff format .
ruff check --fix .
```

## License

MIT

## Credits

- Based on the [meimakes/oura-mcp-server](https://github.com/meimakes/oura-mcp-server) TypeScript implementation
- Built with [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)
- Uses the [Oura API V2](https://cloud.ouraring.com/v2/docs)

Maintenance

ActivityInactive
ResponsivenessNo issues