{
  "markdown": "# oura-mcp\n\n[![CI](https://github.com/YasuakiOmokawa/oura-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/YasuakiOmokawa/oura-mcp/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/@yasuakiomokawa/oura-mcp.svg)](https://www.npmjs.com/package/@yasuakiomokawa/oura-mcp)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\nA 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.\n\n## Quick start\n\n```bash\nnpx @yasuakiomokawa/oura-mcp configure\n```\n\nThe 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.\n\nRe-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:\n\n```bash\nnpx @yasuakiomokawa/oura-mcp configure --force\n```\n\n## Prerequisites\n\n1. Register an Oura developer app at https://cloud.ouraring.com/oauth/applications\n2. **Redirect URI must be exactly**: `http://localhost:54321/callback`\n   (or `http://localhost:<port>/callback` if you customize `OURA_CALLBACK_PORT`)\n3. Enable the read scopes you need (Email, Personal info, Daily activity, Heart rate, Workout, Tag, Session, SpO2, Ring configuration, Stress, Heart health)\n4. Note the Client ID and Client Secret — you'll enter them in `npx @yasuakiomokawa/oura-mcp configure`\n\n## Installation\n\nThree paths depending on your client:\n\n**1. MCP Registry (auto-discovery clients)**\n\nOnce 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.\n\n**2. Manual config (Claude Desktop / Claude Code / Cursor)**\n\nRun `npx @yasuakiomokawa/oura-mcp configure` — Step 4 of the wizard auto-detects:\n\n- Claude Desktop: `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\\Claude\\claude_desktop_config.json` (Windows)\n- Claude Code (user): `~/.claude.json`\n- Claude Code (project): `./.mcp.json`\n- Cursor (user): `~/.cursor/mcp.json`\n- Cursor (project): `./.cursor/mcp.json`\n\nEach detected file is backed up to `<file>.bak.<ISO-timestamp>` before an atomic write.\n\nTo configure manually, add to your client config:\n\n```json\n{\n  \"mcpServers\": {\n    \"oura\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@yasuakiomokawa/oura-mcp\"]\n    }\n  }\n}\n```\n\n**3. Skill (optional)**\n\nThe 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.\n\n## Tools provided\n\n| Tool | Purpose |\n|---|---|\n| `oura_authenticate` | Start OAuth flow in browser; returns the URL. Used after `refresh_token` expires. |\n| `oura_auth_status` | Check current token validity and expiry. |\n| `oura_clear_auth` | Wipe stored tokens. |\n| `oura_api_list_paths` | List every supported `GET` endpoint with summaries. |\n| `oura_api_get` | Generic `GET` to `/v2/...`. Auto-paginates via `max_pages` (1-20) or accepts `next_token` in `params`. |\n\n`oura_api_get` returns `structuredContent` with `{ status, data, next_token, pages_fetched, has_more }`.\n\n## Configuration\n\nTwo 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.\n\n### Option A — config file (recommended)\n\nRun the wizard once and forget about it:\n\n```bash\nnpx @yasuakiomokawa/oura-mcp configure\n```\n\nThis writes:\n\n```\n~/.config/oura-mcp/config.json   # 0600, contains clientId / clientSecret / callbackPort\n~/.config/oura-mcp/tokens.json   # 0600, contains the OAuth access / refresh tokens\n```\n\nPermissions are re-checked on every load and chmod'd back to `0600` if anything else touched them.\n\n`config.json` schema:\n\n```json\n{\n  \"schemaVersion\": 1,\n  \"clientId\": \"...\",\n  \"clientSecret\": \"...\",\n  \"callbackPort\": 54321\n}\n```\n\n### Option B — environment variables (CI / Docker only)\n\n```bash\nOURA_CLIENT_ID=...\nOURA_CLIENT_SECRET=...        # must be set together with OURA_CLIENT_ID\nOURA_CALLBACK_PORT=54321      # optional; safe to set in env regardless of Option A/B\n```\n\nWhen 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.\n\n**Why not recommended**:\n\n- `process.env` is readable from `/proc/<pid>/environ` by any process running as the same user.\n- Environment is inherited by every child process the server spawns.\n- Crash dumps and observability tools that capture `process.env` will leak the secret.\n- `OURA_CLIENT_SECRET=... npx ...` typed at the shell ends up in shell history.\n\n`OURA_CALLBACK_PORT` is **not** a secret and is fine to pass via env in either mode.\n\n### Never use `args` for secrets\n\nProcess arguments are visible to other users via `ps` / `/proc/<pid>/cmdline`. Use the `env` block of your MCP client config:\n\n```json\n{\n  \"mcpServers\": {\n    \"oura\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@yasuakiomokawa/oura-mcp\"],\n      \"env\": { \"OURA_CLIENT_ID\": \"...\", \"OURA_CLIENT_SECRET\": \"...\" }\n    }\n  }\n}\n```\n\n## Troubleshooting\n\n- **\"refresh_token expired\"** — run `oura_authenticate` (in chat) or `npx @yasuakiomokawa/oura-mcp configure` (in terminal).\n- **Port 54321 already in use** — set `OURA_CALLBACK_PORT=<other port>` and update the redirect URI in your Oura developer app to match.\n- **\"Path not found\"** — verify the path with `oura_api_list_paths`. Common slips: missing `/v2/` prefix, typo in `daily_sleep`.\n- **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.\n- **No log output** — set `OURA_LOG_LEVEL=debug` for verbose stderr logging.\n\n## Development\n\n```bash\ngit clone https://github.com/YasuakiOmokawa/oura-mcp.git\ncd oura-mcp\nnpm install\nnpm test\nnpm run build\n```\n\nUseful scripts:\n\n- `npm run lint` / `npm run typecheck` — Biome + TypeScript checks\n- `npm run test:coverage` — Vitest with V8 coverage\n- `npm run update:docs` — re-fetch the Oura OpenAPI schema and regenerate `skills/oura-api-skill/references/`\n\n## License\n\n[MIT](LICENSE)\n",
  "bytes": 6774,
  "sha": "3e66a402fd81f0fb8497a55e5aae9e01ffd84a7811f161967dcc57249b3bef21",
  "repo_slug": "yasuakiomokawa/oura-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_yasuakiomokawa_oura_mcp_8a253775/readme"
}