Skip to main content
Glama
README.md
# withings-mcp

A small, local [MCP](https://modelcontextprotocol.io) server that lets Claude (Claude Code, Claude Desktop or any
MCP client) read **your own** Withings health data through the official
[Withings Public API](https://developer.withings.com/developer-guide/v3/withings-solutions/app-to-app-solution):
body measurements from the scale and blood pressure monitor, daily activity from the watch, nightly sleep
summaries from the sleep analyzer, plus the list of paired devices.

Everything runs on your machine: the server talks to `wbsapi.withings.net` with tokens stored locally and
hands the data to the MCP client. No third-party service in between.

| Tool | Returns |
|---|---|
| `withings_status` | connection state, granted scopes, access-token expiry |
| `withings_devices` | paired devices (model, type, battery, last sync) |
| `withings_measurements` | measurement sessions: weight, fat/muscle/bone/water mass, blood pressure, heart rate, SpO2, temperature, PWV, ECG intervals, ... |
| `withings_activity` | daily steps, distance, elevation, active minutes, calories, heart-rate zones |
| `withings_sleep` | nightly time in bed / asleep, light/REM/deep, efficiency, wake-ups, HR/RR, breathing disturbances, snoring, sleep score, HRV |

Ask things like *"how did my blood pressure trend over the last month?"*, *"compare this week's sleep with the
previous one"* or *"plot my weight since January"* and Claude picks the right tool, date range and filters.

## Requirements

- Python 3.13+ and [uv](https://docs.astral.sh/uv/)
- a Withings account with at least one device (or use the Withings demo user, see below)
- a Withings developer application: free, no contract, takes two minutes (step 1)

Works on Windows, macOS and Linux.

## Install

```bash
git clone https://github.com/stefanocaronia/withings-mcp.git
cd withings-mcp
uv sync
```

## 1. Create the Withings application

API credentials are **not** on account.withings.com; they live on the developer dashboard:

1. open <https://developer.withings.com/dashboard/> and pick **Europe Cloud** (the one open to everybody)
2. log in with your normal Withings account
3. **Create an application** with integration type *Public API*
4. set the callback / redirect URL to exactly `http://localhost:8765/callback`
   (another port works too: pass the same value to `auth --redirect-uri`)
5. keep the generated `client_id` and `client_secret`

## 2. Link your account

```bash
uv run withings-mcp auth --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET
```

This opens the Withings consent page in your browser, listens on `localhost:8765` for the redirect, exchanges the
authorization code (it is valid for 30 seconds) and stores the tokens. With a family account Withings first asks
which user's data to share. Re-running `auth` later reuses the saved credentials; add `--demo` to use the Withings
demo user instead of a real account.

Where things are stored: `%LOCALAPPDATA%\withings-mcp\` on Windows, `$XDG_CONFIG_HOME/withings-mcp` or
`~/.config/withings-mcp` elsewhere (`config.json` with the app credentials, `tokens.json` with the OAuth tokens).
Override the directory with `WITHINGS_MCP_DIR`; `WITHINGS_CLIENT_ID` / `WITHINGS_CLIENT_SECRET` take precedence
over `config.json`. Access tokens (3 h) are refreshed automatically; refresh tokens (1 year) rotate on every refresh
and the newest one is always persisted. If a tool ever reports `status 342/343`, run `auth` again.

`uv run withings-mcp status` shows the current state.

## 3. Register the server with your MCP client

**Claude Code**

```bash
claude mcp add --scope user withings -- uv --directory /path/to/withings-mcp run withings-mcp
```

**Claude Desktop** — add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "withings": {
      "command": "uv",
      "args": ["--directory", "/path/to/withings-mcp", "run", "withings-mcp"]
    }
  }
}
```

Any other MCP client: it is a stdio server started with `uv --directory /path/to/withings-mcp run withings-mcp`.

## Notes on the data

- Dates are `YYYY-MM-DD` in local time; without dates the last 30 days are returned.
- Measurement values are decoded into the unit carried by the key (`weight_kg`, `fat_ratio_pct`,
  `systolic_bp_mmHg`, ...); `types` accepts names or Withings type ids (`weight,fat_ratio` or `1,6`), and
  `include_manual=false` drops entries typed by hand in the app.
- Durations are seconds unless the key says otherwise.
- Withings asks partners not to poll more than once every 10 minutes per user; the server tells Claude so.

## Development

```bash
uv run pytest
```

The tests run against `tests/fake_withings.py`, a stand-in for the Withings API (token exchange and rotation, a
one-off 343 to exercise the retry, two-page pagination, the OAuth callback with right and wrong `state`, the tools
in-process and the real server spawned over stdio). No credentials needed.

References: the one-file API summary at <https://developer.withings.com/llms.md> and the OpenAPI spec at
<https://developer.withings.com/openapi.yaml>.

## Disclaimer

Unofficial project, not affiliated with or endorsed by Withings. It only reads data you already own; nothing
here is medical advice.

## License

[MIT](LICENSE)

TDQS

B3.4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool maps to a clearly distinct data domain: connection status, devices, body measurements, activity, and sleep. There is no overlap in purpose, and the descriptions anchor each to a specific resource. An agent can select the right tool unambiguously.

Naming Consistency5/5

All five tools follow the same predictable withings_<noun> pattern (status, devices, measurements, activity, sleep). No verb-style mixing or case inconsistencies. The naming is uniform and readable.

Tool Count4/5

Five tools is well-scoped and each earns its place by covering a major Withings data category. It is slightly thin in that related surfaces (e.g. workouts, user profile) are not exposed, but nothing feels redundant or padded.

Completeness4/5

The set provides solid read coverage across status, devices, measurements, activity, and sleep, covering the core lifecycle of a health-data reader. Minor gaps remain, such as workouts or intraday data, but core agent workflows are supported without dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues