SkillTide Submit
Official description7 sourcesMCP servers8d ago
proscar87/oura-mcp

proscar87/oura-mcp

Raw access to all Oura Ring API v
View on GitHub ↗Direct link · no redirect page
Config template (adjust for your client)
claude mcp add oura-mcp -- npx -y oura-mcp
A pasteable skeleton generated from the repository name. Check the project README for the exact package and arguments.
Star count
0 ★ · proscar87/oura-mcp · read from the repository page · (checked 2026-10-16 20:00:20)
Source
collected from the punkpeye/awesome-mcp-servers list · type: MCP server
Harvest history
first seen 2026-10-09 · last seen 2026-10-16 · seen 32× · listed by 7 sources
Score
score 703 · 7 sources · mcp
FAQ (answers come from our records)
How do I install it?
We did not find an install command for this repository (our install coverage is only about 4%). Check its README or releases page.
Who is it for?
We filed it under these tags: MCP 服务. The tags come from the entry itself, not a taxonomy we imposed.
Who maintains it?
repository proscar87/oura-mcp;first catalogued 2026-10-09;last seen 2026-10-16。There is no official certification or quality rating here — we record sources and dates only.
Third-party quality signals

oura-mcp

以下摘录自该仓库的 README(片段) · 在 GitHub 读完整 README →

English | 简体中文 | 한국어 | Español
The Oura v2 API as an MCP
server. All 19 collections, six tools, no dependencies beyond the MCP SDK.
One local day of heart rate is 1,231 samples across 2 pages
A client that doesn't follow Oura's next_token returns **1,000 of them — 81%,
looking complete, with nothing saying otherwise.** Measured against the real API
on 9 August 2026, one person, one ring, 24 hours.
**The test to apply to any Oura MCP server, including this one:** does it take
next_token — or a cursor, or a limit — as a tool parameter? If it does,
pagination is the model's job, and a model that forgets to ask again produces a
confident answer off partial data. This server paginates to exhaustion before it
returns, and tells you how many pages it took.
That's one of **four** ways Oura under-delivers without saying so. All four are
measured below, and all four are corrected here.
Install
Download **oura-mcp.mcpb** from the
latest release and
double-click it. Claude Desktop does the rest — no terminal, no Python, no Node.
It runs on Oura's official sample data out of the box, and every sample response
says so, so nothing can pass for your own sleep.
Prefer the command line? uvx --from mcp-oura oura-mcp.
Prefer no Python on your machine at all?
-i is not optional: an MCP server speaks over stdin and stdout, not over a
port. Without it the container has no stdin, the handshake never arrives, and
the client reports a server that doesn't show up.
In **claude.ai** or **ChatGPT**, in a browser? Those connect by URL, so the
server has to live somewhere public: deploy it as a Worker on your own
Cloudflare account — free, about ten minutes, yours alone. See
Remote: claude.ai and ChatGPT.
---
The problem, measured
Oura does not return errors when it can't give you what you asked for. It
returns something different, shaped like a correct response. These are the four
we found by measuring against the real API on 9 August 2026:
1. Skip the pagination and you get a fraction
If next_token comes back and you don't follow it, you receive the first page
and **nothing warns you**. One local day of heartrate — one person, one ring,
24 hours — is **1,231 samples across 2 pages**. A client that doesn't paginate
gets 1,000 of 1,231: 81%, looking complete. A month is ~37,000.
2. Asking for a single day returned zero records
end_date **does not behave the same across collections**:
| Exclude the last day requested | Include it |
|---|---|
| daily_activity, sleep, workout | daily_sleep, daily_readiness, daily_stress, daily_spo2, daily_resilience, daily_cardiovascular_age, sleep_time |
And on top of that, **workout filters by UTC date while reporting day in
local time**: at -06:00, asking for July 16–18 returned records from the 15th
and 16th — *before* the requested start.
Here the range is inclusive on both ends, always. Two extra days are requested
on each side and then trimmed, which is correct whichever way a given collection
behaves — and stays correct when Oura changes it.
3. latest=true is ignored where it doesn't apply
Only heartrate and ring_battery_level honor it. In the other seventeen Oura
doesn't error: it **returns the entire collection**. You ask for the latest
record, you get ten, and you believe it's one. Here it's rejected before the
request goes out.
4. A field that doesn't exist is silently ignored
fields=does_not_exist returns the **complete** record — the projection never
happens — and fields=score,does_not_exist applies the good one and drops the
bad one without a word. Here, fields that never appeared are reported under
ignored_fields.
**The pattern is always the same:** you ask for one thing, you get another, and
nothing warns you. That's why this package would rather shout than quietly
under-deliver.
Installation
Try it with no credentials
The sandbox is official — it's in Oura's OpenAPI spec, with 34 mirror routes —
and serves synthetic data without authentication. 18 of the 19 collections work
there: personal_info doesn't, which makes sense, since it's the one returning
email, age, weight and height.
This is the right order: first you watch the server work and learn the shape of
the data, then you go get credentials.
With your own data
**Oura stopped issuing Personal Access Tokens in December 2025.** Existing ones
still work; new ones can't be created. So there are two paths:
**a) OAuth2 — the one that works today.** Register an application at
cloud.ouraring.com/oauth/applications
with the redirect http://localhost:9876/callback/ — **the trailing slash is
Source
awesome · https://github.com/proscar87/oura-mcp
Browse by field
MCP servers
added
yesterday

More in MCP servers

All 5,525 in MCP servers →

Filed under

Every tag opens the full list for that filter. Counts are the live catalogue figures.

Browse all fields →

← Back to index