Content
# oura-mcp
[](https://github.com/YasuakiOmokawa/oura-mcp/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/@yasuakiomokawa/oura-mcp)
[](LICENSE)
A Model Context Protocol server for the [Oura Ring API v2](https://cloud.ouraring.com/v2/docs). Exposes sleep, activity, readiness, heart rate, and workout data to MCP-compatible clients (Claude Desktop, Claude Code, Cursor, ...) via OAuth.
## Quick start
```bash
npx @yasuakiomokawa/oura-mcp configure
```
The wizard collects your Oura Client ID/Secret, walks through browser OAuth, saves tokens to `~/.config/oura-mcp/`, and adds an `mcpServers.oura` entry to any detected MCP client config. Restart the client and the tools below are available.
Re-running `configure` pre-fills the saved Client ID / port so you only need to press Enter to keep them. Type `--force` to wipe saved state and start from scratch:
```bash
npx @yasuakiomokawa/oura-mcp configure --force
```
## Prerequisites
1. Register an Oura developer app at https://cloud.ouraring.com/oauth/applications
2. **Redirect URI must be exactly**: `http://localhost:54321/callback`
(or `http://localhost:<port>/callback` if you customize `OURA_CALLBACK_PORT`)
3. Enable the read scopes you need (Email, Personal info, Daily activity, Heart rate, Workout, Tag, Session, SpO2, Ring configuration, Stress, Heart health)
4. Note the Client ID and Client Secret — you'll enter them in `npx @yasuakiomokawa/oura-mcp configure`
## Installation
Three paths depending on your client:
**1. MCP Registry (auto-discovery clients)**
Once published to the [official MCP Registry](https://github.com/modelcontextprotocol/registry), supported clients can install `io.github.YasuakiOmokawa/oura-mcp` from their UI. The wizard step still has to run once to obtain OAuth tokens.
**2. Manual config (Claude Desktop / Claude Code / Cursor)**
Run `npx @yasuakiomokawa/oura-mcp configure` — Step 4 of the wizard auto-detects:
- Claude Desktop: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows)
- Claude Code (user): `~/.claude.json`
- Claude Code (project): `./.mcp.json`
- Cursor (user): `~/.cursor/mcp.json`
- Cursor (project): `./.cursor/mcp.json`
Each detected file is backed up to `<file>.bak.<ISO-timestamp>` before an atomic write.
To configure manually, add to your client config:
```json
{
"mcpServers": {
"oura": {
"command": "npx",
"args": ["-y", "@yasuakiomokawa/oura-mcp"]
}
}
}
```
**3. Skill (optional)**
The companion [`oura-api-skill`](skills/oura-api-skill/SKILL.md) ships per-endpoint reference and three workflow recipes (weekly review / sleep trend / recovery check). Bundle it as a Claude Code plugin or import into your skills directory.
## Tools provided
| Tool | Purpose |
|---|---|
| `oura_authenticate` | Start OAuth flow in browser; returns the URL. Used after `refresh_token` expires. |
| `oura_auth_status` | Check current token validity and expiry. |
| `oura_clear_auth` | Wipe stored tokens. |
| `oura_api_list_paths` | List every supported `GET` endpoint with summaries. |
| `oura_api_get` | Generic `GET` to `/v2/...`. Auto-paginates via `max_pages` (1-20) or accepts `next_token` in `params`. |
`oura_api_get` returns `structuredContent` with `{ status, data, next_token, pages_fetched, has_more }`.
## Configuration
Two ways. **The config file (Option A) is the recommended path** — it stores secrets at-rest with `0600` and is self-healing. Environment variables (Option B) are kept for CI / Docker / ephemeral environments where writing a file is impractical, but they leak more easily and are not recommended for daily use.
### Option A — config file (recommended)
Run the wizard once and forget about it:
```bash
npx @yasuakiomokawa/oura-mcp configure
```
This writes:
```
~/.config/oura-mcp/config.json # 0600, contains clientId / clientSecret / callbackPort
~/.config/oura-mcp/tokens.json # 0600, contains the OAuth access / refresh tokens
```
Permissions are re-checked on every load and chmod'd back to `0600` if anything else touched them.
`config.json` schema:
```json
{
"schemaVersion": 1,
"clientId": "...",
"clientSecret": "...",
"callbackPort": 54321
}
```
### Option B — environment variables (CI / Docker only)
```bash
OURA_CLIENT_ID=...
OURA_CLIENT_SECRET=... # must be set together with OURA_CLIENT_ID
OURA_CALLBACK_PORT=54321 # optional; safe to set in env regardless of Option A/B
```
When the server boots and both `OURA_CLIENT_ID` and `OURA_CLIENT_SECRET` are set, it uses them and emits a `config.env_credentials` warning to stderr.
**Why not recommended**:
- `process.env` is readable from `/proc/<pid>/environ` by any process running as the same user.
- Environment is inherited by every child process the server spawns.
- Crash dumps and observability tools that capture `process.env` will leak the secret.
- `OURA_CLIENT_SECRET=... npx ...` typed at the shell ends up in shell history.
`OURA_CALLBACK_PORT` is **not** a secret and is fine to pass via env in either mode.
### Never use `args` for secrets
Process arguments are visible to other users via `ps` / `/proc/<pid>/cmdline`. Use the `env` block of your MCP client config:
```json
{
"mcpServers": {
"oura": {
"command": "npx",
"args": ["-y", "@yasuakiomokawa/oura-mcp"],
"env": { "OURA_CLIENT_ID": "...", "OURA_CLIENT_SECRET": "..." }
}
}
}
```
## Troubleshooting
- **"refresh_token expired"** — run `oura_authenticate` (in chat) or `npx @yasuakiomokawa/oura-mcp configure` (in terminal).
- **Port 54321 already in use** — set `OURA_CALLBACK_PORT=<other port>` and update the redirect URI in your Oura developer app to match.
- **"Path not found"** — verify the path with `oura_api_list_paths`. Common slips: missing `/v2/` prefix, typo in `daily_sleep`.
- **Setup hangs at "Waiting for authorization"** — you haven't approved in the browser yet, or the authorize page was opened in a different browser session than the one with localhost reachability.
- **No log output** — set `OURA_LOG_LEVEL=debug` for verbose stderr logging.
## Development
```bash
git clone https://github.com/YasuakiOmokawa/oura-mcp.git
cd oura-mcp
npm install
npm test
npm run build
```
Useful scripts:
- `npm run lint` / `npm run typecheck` — Biome + TypeScript checks
- `npm run test:coverage` — Vitest with V8 coverage
- `npm run update:docs` — re-fetch the Oura OpenAPI schema and regenerate `skills/oura-api-skill/references/`
## License
[MIT](LICENSE)
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
ScienceClaw
🔬🦞 A self-evolving AI research colleague for scientists. 285 skills, 25+...
ScienceClaw
ScienceClaw is a personal research assistant built with LangChain DeepAgents...
garmin-connect-mcp
MCP server for Garmin Connect — access 61 health, fitness and activity tools...
Train-in-Silence
The first Task-Aware MCP server and automated VRAM calculator for LLM...
stacklit
108,000 lines of code. 4,000 tokens of index. One command makes any repo...
AppClaw
AI-powered mobile automation agent — describe what you want in plain...