Skip to content

Releases: proscar87/oura-mcp

v0.3.1 — a cursor you could actually use

Choose a tag to compare

@proscar87 proscar87 released this 10 Aug 05:03

continue_from carried Oura's opaque next_token, and no tool parameter accepts a token back — deliberately, because a cursor parameter hands pagination to the model, which is the failure this package exists to prevent. A truncated response told the model to continue from a value it had nowhere to put.

It is now the last day actually reached, usable with the start parameter that already exists. When no record carries a day, the key is omitted rather than sent as null.

Also: eight retired Spanish key names were still documented in the README and llms.txt. A dead CLI flag fails loudly; a key that never arrives just looks like the condition never happened.

Install: download oura-mcp.mcpb below and double-click it. No terminal, no Python, no Node. Runs on Oura's official sample data out of the box, and every sample response says so.

141 Python tests, 41 TypeScript tests. Neither suite touches the network.

v0.3.0 — one-click install, English throughout

Choose a tag to compare

@proscar87 proscar87 released this 10 Aug 04:54

Install by double-clicking oura-mcp.mcpb below. Claude Desktop does the
rest — no terminal, no Python, no Node install. It works immediately on Oura's
official sample data, and every sample response says so, so nothing here can be
mistaken for your own sleep.

To use your own data, ask it for something: it opens Oura's authorization page
for you and picks up where you left off. Oura requires every application to be
registered, so you paste a client ID and secret once — the extension's settings
spell out the exact redirect, including the trailing slash that otherwise
bounces the registration.

Also on PyPI: uvx --from mcp-oura oura-mcp.

What this release is

Everything in English — documentation, comments, tool parameters and CLI
flags. The parameter rename is breaking against 0.2.0: diaday,
coleccioncollection, iniciostart, finend, campos
fields, ultimolatest, formatoformat. They now match Oura's own
API names.

A TypeScript port, verified against the Python one on the real API: the same
1,231 records in the same order for the two-page heartrate case.

Authorization without a terminal, via MCP URL elicitation.

Sample data announces itself. oura_check said the sandbox data was
synthetic and the queries did not — so a fresh install answered "how did I
sleep?" with a score out of Oura's made-up data and nothing marking whose it
was. Every sandbox response now carries a synthetic key.

Why this exists

Oura's API doesn't error when it can't give you what you asked for. It returns
something different, shaped like a correct answer. One local day of heart rate
is 1,231 samples across 2 pages — a client that doesn't follow next_token
returns 81% of them and says nothing. This server paginates to exhaustion and
reports the page count, fixes the date range Oura applies inconsistently,
rejects latest=true where Oura would silently return the whole collection, and
names field projections Oura ignored.

It deliberately computes nothing: no averages, no correlations, no trends. An
average computed inside the server reaches the model as a number without its
method.

138 Python tests, 40 TypeScript tests. Neither suite touches the network.