withings-mcp
MCP server for the Withings Health API that syncs and queries personal health data using a local SQLite cache and live API access.
Sync body, sleep, activity, and workout data incrementally into a local cache.
Query body composition metrics such as weight, fat percentage, muscle, bone, blood pressure, SpO2, and more.
Retrieve nightly sleep summaries or detailed minute-by-minute sleep phases.
View daily activity totals and individual workout sessions with type/date filters.
Access ECG/AFib recordings and connected device battery/firmware information live.
Analyze weekly, monthly, or quarterly trends and compare periods.
Fetch cache-backed data live from Withings when needed, with automatic OAuth token refresh.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@withings-mcpshow my weight trends for the last 3 months"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
withings-mcp
MCP server for the Withings Health API with OAuth, local SQLite cache, and trend analysis.
What makes this different from other Withings MCP servers:
Local SQLite cache for fast offline queries and historical trend analysis
Incremental sync - only fetches new data since last sync
Broad Withings coverage: 17 body-composition metrics plus sleep, daily activity, workouts, and ECG/AFib
Automatic OAuth token refresh (access tokens: 3h, refresh tokens: 1 year)
Zero dependencies beyond
mcp(HTTP via stdlib)Python 3.13+ (tested on 3.13, 3.14 and 3.15, on Linux, macOS and Windows, in CI)
Tools
Tool | Description | Data source |
| Sync data from Withings API to local cache | Live API -> SQLite |
| Body composition (weight, fat%, muscle, bone, BP, SpO2) | Local cache (auto-syncs if stale) |
| Sleep summaries, or detailed phase time-series with | Cache (summary) / live (detail) |
| Daily steps, distance, calories, active time | Local cache (auto-syncs if stale) |
| Workout sessions with type, duration, HR | Local cache (auto-syncs if stale) |
| ECG recordings and AFib detection | Live API (always) |
| Connected devices with battery status | Live API (always) |
| Period averages, weekly/monthly/quarterly trends, comparisons | Local cache (auto-syncs if stale) |
The cache-backed query tools auto-sync when their data is stale, and accept live=True to bypass the cache and fetch straight from the Withings API. withings_get_heart and withings_get_devices are always live. withings_get_sleep(detail=True) returns minute-by-minute sleep phases (live, up to 7 days per request).
Related MCP server: Withings MCP Server
Prerequisites
Python 3.13+ (tested on 3.13, 3.14 and 3.15, on Linux, macOS and Windows, in CI)
uv (recommended) or pip
A Withings developer account and registered application
Installation
pip install withings-mcpOr run it without installing with uvx withings-mcp. For development from a clone:
git clone https://github.com/partymola/withings-mcp.git
cd withings-mcp
uv venv --python 3.13 .venv
uv pip install -e .Setup
1. Register a Withings app
Create a new application
Set the callback URL to
http://localhost:8585Note your Client ID and Client Secret
2. Authenticate
.venv/bin/withings-mcp authThis opens your browser for Withings authorization. After approving, tokens are saved locally in config/.
3. Register with Claude Code
claude mcp add -s user withings -- /path/to/withings-mcp/.venv/bin/withings-mcp4. First sync
In Claude Code, say: "Sync my Withings data"
This runs withings_sync to populate the local cache. Subsequent syncs only fetch new data.
If anything does not work - no data where you expect it, a sync that stops happening - run withings-mcp doctor. It reports the paths and credentials actually in use and what needs fixing, without making an API call.
You can also sync from the command line without an MCP client:
.venv/bin/withings-mcp sync # all data types, last 30 days
.venv/bin/withings-mcp sync --types body,sleep # a subset
.venv/bin/withings-mcp sync --days 90 # deeper history on first syncCLI
withings-mcp Start the MCP server (stdio transport)
withings-mcp auth Interactive OAuth setup (opens the browser)
withings-mcp sync Sync data to the local cache (--types, --days)
withings-mcp doctor Check the setup and report what needs fixing
withings-mcp --version Print the installed package versionConfiguration
Environment Variable | Default | Description |
|
| Directory for credentials and tokens |
|
| SQLite database path |
Example Prompts
"Sync my Withings data"
"Show my weight for the last 3 months"
"How has my sleep changed this year?"
"Compare my body composition this month vs last month"
"What workouts did I do in March?"
"What Withings devices do I have connected?"
"Show my sleep trends quarterly"
Development
# Install with dev dependencies
uv pip install -e . && uv pip install pytest
# Run tests (all use in-memory SQLite with fictional data)
.venv/bin/python -m pytest tests/ -v # .venv\Scripts\python on WindowsSecurity
Read-only: No tools modify data on Withings servers
Local storage: Health data stays in your local SQLite database
Token storage: OAuth tokens stored in
config/(gitignored; created 0600 on POSIX - Windows ignores the mode and governs access by ACLs)Error messages: Never contain health data values - only status codes
Pre-commit hook: An optional hook (
scripts/check-no-data.sh) blocks database files, files underconfig/and large files from commits. It does not read file contents. Install it with the one-liner in CONTRIBUTING.md
Contributing
See CONTRIBUTING.md for development setup, the test workflow, and the pre-commit hook. Changes are tracked in CHANGELOG.md.
License
GPL-3.0-or-later
Available Tools
8 toolswithings_get_activityA
Get daily activity summaries (steps, distance, calories, active time).
Returns one entry per day from the local cache by default. Run withings_sync first to populate the cache.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: 30 days back from the end date or today, whichever is earlier. end_date: End date as "YYYY-MM-DD", "YYYY-MM" (its last day), or "Nd". Default: today. live: If true, fetch from Withings API instead of cache.
Returns daily activity data sorted by date, with steps, distance in km, calories, and active minutes by intensity level. Not for workout sessions -- use withings_get_workouts instead.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the cache-vs-live data source, the sync dependency, the sort order, and the units (distance in km, active minutes by intensity). It does not cover auth requirements, rate limits, or what happens when the cache is empty, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded, then source behavior, then Args, then Returns, then the sibling exclusion — a sensible order. The Args block is slightly verbose relative to a 3-parameter tool, but every line adds usable information rather than restating the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by naming the returned fields, units, and sort order. For a simple read tool with zero required parameters this is nearly complete; only edge-case behavior (empty cache, large-range limits) is left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, and it does: each of the three parameters gets accepted formats ("YYYY-MM-DD", "YYYY-MM", "30d", "Nd"), interpretation of partial dates (month resolves to its last day), and default resolution rules. This is meaning well beyond the bare typed properties.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening line names a specific verb and resource ("Get daily activity summaries") and enumerates the metrics returned (steps, distance, calories, active time). The closing line explicitly distinguishes it from the workout-session sibling, so an agent can route without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states a prerequisite ("Run withings_sync first to populate the cache"), a default data source (local cache), and an explicit exclusion with the correct alternative ("Not for workout sessions -- use withings_get_workouts instead"). When-to-use, when-not-to-use, and the alternative are all present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
withings_get_bodyA
Get body composition measurements (weight, fat, muscle, etc.).
Returns measurements from the local cache by default. Use live=True to fetch directly from Withings API. Run withings_sync first to populate the cache.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d" for relative days. Default: 30 days back from the end date or today, whichever is earlier. end_date: End date as "YYYY-MM-DD", "YYYY-MM" (its last day), or "Nd". Default: today. metrics: Comma-separated metric filter, e.g. "weight_kg,fat_pct". Default: all available metrics. Names match exactly and are case-sensitive; one that is not on this list is refused, naming them. Options: weight_kg, height_m, lean_mass_kg, fat_pct, fat_mass_kg, muscle_mass_kg, hydration_kg, bone_mass_kg, heart_rate, systolic_bp, diastolic_bp, spo2_pct, temperature_c, body_temperature_c, pulse_wave_velocity, visceral_fat_index, basal_metabolic_rate.
live: If true, fetch from Withings API instead of cache.Returns measurements sorted by date, one entry per measurement group. Not for sleep or activity data -- use withings_get_sleep or withings_get_activity instead.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| metrics | No | ||
| end_date | No | ||
| start_date | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and mostly succeeds: it discloses cache-vs-live sourcing, the sync prerequisite, date-sorted results with one entry per measurement group, and that an unrecognized metric name is refused by naming the valid options. It omits auth requirements and rate-limit behavior for the live path, keeping it below 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core behavior and the sibling exclusion are front-loaded in the first and last paragraphs, with parameters grouped in a conventional Args block. The 16-item metric enumeration is long but earns its place because names are case-sensitive and invalid ones are rejected.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter, zero-annotation, no-output-schema read tool, the description covers sourcing, prerequisites, filtering, and ordering. The one residual gap is the shape of each returned measurement group, which no output schema documents either.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the schema titles ('Start Date', 'Metrics', 'Live') provide almost no meaning, yet the description fully compensates. It documents accepted date formats (YYYY-MM-DD, YYYY-MM, '30d'), default windows, comma-separated metric filtering with case sensitivity and failure behavior, and the live flag's exact effect.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'Get body composition measurements (weight, fat, muscle, etc.)'. It also explicitly distinguishes itself from siblings, stating it is 'Not for sleep or activity data -- use withings_get_sleep or withings_get_activity instead.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit operating guidance: cache is the default, live=True hits the Withings API, and withings_sync must be run first to populate the cache. It also names concrete alternatives for out-of-scope data (withings_get_sleep, withings_get_activity), so the when-to-use decision is fully determined.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
withings_get_devicesA
Get connected Withings devices with battery and firmware info.
Always fetched live from the Withings API.
Returns device type, model name, battery level (high/medium/low), and last session date for each connected device.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It does add real value by disclosing 'Always fetched live from the Withings API', signalling no caching and potential latency/freshness implications, but it omits auth/permission requirements and error behavior for a tool that must hit an external API.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, front-loaded sentences with no filler; the core purpose leads and details follow. A small inconsistency: it advertises 'firmware info' but the enumerated return fields include no firmware version, so that phrase is slightly wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description usefully documents the return fields, which is exactly what the agent needs. For a zero-parameter read tool the only real gap is the absence of auth/permission context, otherwise it is complete enough to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; the 4 baseline applies. The return-field enumeration is extra but belongs to output rather than parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Get') and a distinct resource ('connected Withings devices') and enumerates what is returned (type, model, battery, last session). This clearly separates it from the data-fetching siblings (activity, workouts, body, heart, sleep), though it never names those siblings explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer it should call this when it needs device connection status, battery, or firmware. There is no explicit when-to-use guidance, no mention of prerequisites (e.g., an active Withings account/OAuth), and no routing to or from sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
withings_get_heartA
Get ECG recordings and atrial fibrillation detection results.
Always fetched live from the Withings API (not cached due to large signal data). Requires a Withings device with ECG capability (ScanWatch, BPM Core).
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: 30 days back from the end date or today, whichever is earlier. end_date: End date as "YYYY-MM-DD", "YYYY-MM" (its last day), or "Nd". Default: today.
Returns ECG recording list with timestamps, AFib classification (negative/positive/inconclusive), and heart rate. Does not include raw signal waveforms. For resting heart rate trends, use withings_get_body or withings_get_sleep instead.
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | No | ||
| start_date | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does well: it discloses that data is always fetched live rather than cached (with the reason: large signal data), which implies latency, and it warns that raw signal waveforms are not included. It does not address authentication requirements or rate limits, which is the main remaining gap for a live-API read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then behavioral context, then parameter docs, then an explicit exclusion and alternative. Every sentence carries information the schema or annotations do not — nothing is restated from structured fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by describing the return shape (ECG recording list with timestamps, AFib classification categories, heart rate) and explicitly stating what is excluded (raw waveforms). For a two-parameter read tool this leaves no meaningful ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate entirely, and it does: both start_date and end_date are documented with accepted formats ("YYYY-MM-DD", "YYYY-MM", "30d"/"Nd"), month-to-last-day interpretation, and defaults. An agent could construct correct values without ever seeing the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: fetch ECG recordings and atrial fibrillation detection results from Withings. This is immediately distinguishable from siblings like withings_get_body and withings_get_sleep, which the description explicitly names as being for resting heart rate instead.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides the prerequisite (a Withings device with ECG capability, naming ScanWatch and BPM Core) and explicitly redirects the agent to withings_get_body or withings_get_sleep when the goal is resting heart rate trends rather than ECG/AFib data. That is a concrete when-to-use versus when-to-use-something-else routing rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
withings_get_sleepA
Get sleep data (summaries or detailed phases).
Summary mode (default): nightly totals with duration, sleep score, HR, respiratory rate, and snoring. From local cache unless live=True.
Detail mode (detail=True): minute-by-minute sleep phases (awake, light, deep, REM) with HR and respiratory rate. Always fetched live. Maximum 7 days per request (Withings API limit).
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "7d". Default: 7 days (detail) or 30 days (summary) back from the end date or today, whichever is earlier. end_date: End date as "YYYY-MM-DD", "YYYY-MM" (its last day), or "Nd". Default: today. detail: If true, return minute-by-minute sleep phases instead of nightly summaries. Always live, max 7 days. live: If true, fetch summaries from API instead of cache. Ignored when detail=True (always live).
Returns nightly sleep data sorted by date. Not for body composition -- use withings_get_body instead.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| detail | No | ||
| end_date | No | ||
| start_date | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and does so well: it discloses that summaries come from a local cache unless live=True, that detail mode is always fetched live and ignores the live flag, and that the Withings API caps requests at 7 days. These are non-obvious operational traits an agent could not infer from the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The structure is strong — mode behavior is front-loaded, parameters follow in a clean Args block, and a closing line handles the return and the sibling exclusion. Minor cost: the closing line 'Returns nightly sleep data sorted by date' is misleading for detail mode, which returns minute-level phases rather than nightly rows.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-parameter tool with no annotations and no output schema, the description covers everything an agent needs to call it correctly: mode semantics, caching behavior, API limits, date format options, and defaults. The only light gap is the precise shape of the detail-mode return, but the summary of fields (phases, HR, respiratory rate) is sufficient to decide whether to request it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must define all four parameters, and it does: accepted date formats ('YYYY-MM-DD', 'YYYY-MM', '7d', 'Nd'), what 'YYYY-MM' expands to (its last day), and the asymmetric defaults (7 days back for detail, 30 for summary). It also explains the interaction between detail and live, which the schema cannot express.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Get sleep data') and immediately splits it into two named modes (summary vs. detail phases), each described with its actual contents. It also names a sibling to avoid ('Not for body composition -- use withings_get_body'), so an agent can distinguish it from the surrounding Withings tools without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit mode selection guidance ('detail=True' for minute-by-minute phases, default summary for nightly totals) plus a hard constraint ('Maximum 7 days per request') and a sibling redirect for body data. What's missing is guidance on when a caller should prefer live over cache beyond the implicit default, and no mention of the other siblings (heart, trends, activity) that might overlap with sleep-adjacent queries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
withings_get_workoutsA
Get workout sessions (type, duration, HR, calories).
Returns individual workout sessions from the local cache by default. Run withings_sync first to populate the cache.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "90d". Default: 90 days back from the end date or today, whichever is earlier. end_date: End date as "YYYY-MM-DD", "YYYY-MM" (its last day), or "Nd". Default: today. category: Filter by workout type, case-insensitive partial match. A value matching none of the categories below is refused, naming the ones your cache holds. Options: badminton, baseball, basketball, bmx, bodyboard, boxing, calisthenics, climbing, cycling, dancing, elliptical, fencing, football, golf, handball, hiking, hockey, horse_riding, ice_hockey, ice_skating, indoor_cycling, indoor_running, indoor_walk, kitesurfing, martial_arts, multi_sport, other, pilates, rowing, rugby, run, skating, skiing, snowboarding, soccer, squash, surfing, swimming, table_tennis, tennis, volleyball, walk, waterpolo, weightlifting, windsurfing, wrestling, yoga, zumba.
live: If true, fetch from Withings API instead of cache.Returns workout sessions sorted by date with type, duration, calories, distance, and heart rate data. Not for daily step/activity totals -- use withings_get_activity.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| category | No | ||
| end_date | No | ||
| start_date | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does most of it: it discloses the cache-first default, the live flag as an override, sort order, and that an unrecognized category is refused with the valid options named. It omits auth requirements, rate limits, and whether the cache is ever stale beyond the sync hint, which keeps it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and cache/sync caveat are front-loaded before the Args block, and the trailing sibling redirect is well placed. The 46-item category enumeration is long but functional; it is the one element that could be deferred to the schema enum instead.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by listing returned fields and sort order. Combined with the sync prerequisite and date-format guidance, an agent has everything needed to call this correctly on the first try.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, yet the description fully compensates: start_date and end_date document accepted formats (YYYY-MM-DD, YYYY-MM with last-day semantics, relative forms like "90d"/"Nd") and their defaults, category explains case-insensitive partial matching plus the full option list, and live explains cache-vs-API behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ("Get workout sessions") and immediately enumerates the returned fields (type, duration, HR, calories). The closing line explicitly excludes daily step/activity totals and names withings_get_activity as the sibling to use instead, so the tool is distinguishable at a glance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit prerequisite ("Run withings_sync first to populate the cache"), states the default data source (cache vs live), and redirects to a named alternative for activity totals. Both when-to-use and when-not-to-use are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
withings_syncA
Sync Withings health data to the local cache.
Fetches data from the Withings API and stores it in SQLite for fast offline queries. Run this before using other withings_get_* tools.
Syncs incrementally: only fetches data newer than the last sync. First sync fetches the specified number of days of history.
Args: data_types: What to sync. Options: "all", "body", "sleep", "activity", "workouts". Comma-separated for multiple, e.g. "body,sleep". Default: "all". days: Days of history for first sync (default: 30). Ignored on subsequent syncs (uses last sync timestamp).
Returns summary of records synced per data type. Not for querying data - use withings_get_body, withings_get_sleep, withings_get_activity, or withings_get_workouts instead.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | ||
| data_types | No | all |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses incremental sync semantics (only data newer than last sync), that 'days' is ignored after the first sync, that data lands in a SQLite cache, and that it returns a per-type summary. It does not mention authentication requirements or what happens to existing cached rows on re-sync, which keeps it from a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then sync behavior, then args, then exclusions — a logical order. Minor waste in restating the schema defaults ('default: 30', 'default: "all"'), but the surrounding explanation of those params earns the space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-param sync tool with no output schema and no annotations, it covers purpose, sequencing, incremental behavior, param semantics, and return shape. The one meaningful omission is any mention of credential/auth prerequisites for the Withings API before a sync can succeed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate entirely, and it does: data_types enumerates the five valid values plus comma-separated multi-value syntax with a default, and days is explained as first-sync-only history depth with the subsequent-sync override called out.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Sync Withings health data to the local cache') plus the mechanism (Withings API into SQLite). It is unmistakably distinct from every withings_get_* sibling, which only read cached data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit ordering guidance ('Run this before using other withings_get_* tools') and an explicit exclusion naming four alternative tools ('Not for querying data - use withings_get_body, withings_get_sleep...'). Both when-to-use and when-not-to-use are stated with alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
withings_trendsA
Analyse trends in cached health data.
Computes averages, min/max, and changes over time from the local cache. Auto-syncs if the cache is stale (no sync today).
Args: data_type: What to analyse. Options: "body", "sleep", "activity". period: Aggregation period. Options: "weekly", "monthly", "quarterly". Default: "monthly". start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "365d" for relative days. Default: 365 days back from the end date or today, whichever is earlier. end_date: End date as "YYYY-MM-DD", "YYYY-MM" (its last day), or "Nd". Default: today. compare: Compare two periods. Format: "last_30d vs previous_30d", "2026-03 vs 2026-02", "2026-Q1 vs 2025-Q4". When set, period/start_date/end_date are ignored.
Returns aggregated averages with change indicators. For body data: weight, fat%, muscle trends. For sleep: duration, score, HR trends. For activity: steps, distance, calorie trends. Not for raw data -- use withings_get_body/sleep/activity instead.
| Name | Required | Description | Default |
|---|---|---|---|
| period | No | monthly | |
| compare | No | ||
| end_date | No | ||
| data_type | No | body | |
| start_date | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full burden and does disclose meaningful behavior: results come from a local cache, and the tool auto-syncs when the cache is stale (no sync today). It also describes the return shape (aggregated averages with change indicators, broken out per data_type). It stops short of stating that the operation is read-only/non-mutating or describing failure behavior when a sync fails or no cached data exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then behavior, then a per-parameter breakdown, then return contents and the sibling exclusion. The Args: docstring formatting is slightly verbose but every line carries information; nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description fills that gap by enumerating the metrics returned for each data_type (weight/fat%/muscle, duration/score/HR, steps/distance/calories). Combined with cache/auto-sync behavior and full parameter documentation, an agent has everything needed to call this correctly against the seven siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does so for all five parameters: `data_type` and `period` enumerations, `start_date` accepted formats (YYYY-MM-DD, YYYY-MM, 365d) plus default semantics, `end_date` last-day-of-month and Nd handling, and the `compare` string grammar with three concrete examples plus its precedence over the other date parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource ("Analyse trends in cached health data") and immediately narrows to what is computed: averages, min/max, and change over time. It also explicitly separates itself from the raw-data siblings with "Not for raw data -- use withings_get_body/sleep/activity instead."
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use guidance (trend/aggregate analysis) and explicit when-not-to-use guidance pointing at three named sibling tools. It also documents interaction rules between parameters, stating that when `compare` is set, `period`/`start_date`/`end_date` are ignored.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.11.0- Changed
withings_get_activity1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "result": { - "title": "Result", - "type": "string" - } - }, - "required": [ - "result" - ], - "title": "withings_get_activityOutput", - "type": "object" -}New value: +null
- Changed
withings_get_body1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "result": { - "title": "Result", - "type": "string" - } - }, - "required": [ - "result" - ], - "title": "withings_get_bodyOutput", - "type": "object" -}New value: +null
- Changed
withings_get_devices1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "result": { - "title": "Result", - "type": "string" - } - }, - "required": [ - "result" - ], - "title": "withings_get_devicesOutput", - "type": "object" -}New value: +null
- Changed
withings_get_heart1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "result": { - "title": "Result", - "type": "string" - } - }, - "required": [ - "result" - ], - "title": "withings_get_heartOutput", - "type": "object" -}New value: +null
- Changed
withings_get_sleep1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "result": { - "title": "Result", - "type": "string" - } - }, - "required": [ - "result" - ], - "title": "withings_get_sleepOutput", - "type": "object" -}New value: +null
- Changed
withings_get_workouts1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "result": { - "title": "Result", - "type": "string" - } - }, - "required": [ - "result" - ], - "title": "withings_get_workoutsOutput", - "type": "object" -}New value: +null
- Changed
withings_sync1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "result": { - "title": "Result", - "type": "string" - } - }, - "required": [ - "result" - ], - "title": "withings_syncOutput", - "type": "object" -}New value: +null
- Changed
withings_trends1 field changed- changed
Output schema / (root)Previous value: -{ - "properties": { - "result": { - "title": "Result", - "type": "string" - } - }, - "required": [ - "result" - ], - "title": "withings_trendsOutput", - "type": "object" -}New value: +null
1 tool update
v0.8.0- Changed
withings_trends2 fields changed- added
Input schema / properties / data_type / enumAdded value: +[ + "body", + "sleep", + "activity" +] - added
Input schema / properties / period / enumAdded value: +[ + "weekly", + "monthly", + "quarterly" +]
8 tool updates
v0.1.0- First observed
withings_get_activity - First observed
withings_get_body - First observed
withings_get_devices - First observed
withings_get_heart - First observed
withings_get_sleep - First observed
withings_get_workouts - First observed
withings_sync - First observed
withings_trends
TDQS
Scored across 8 tools
Each tool targets a clearly distinct data domain or action: sync, devices, body, sleep, activity, workouts, heart/ECG, and trends. Descriptions explicitly cross-reference each other and clarify boundaries such as activity vs workouts, body vs heart, and trends vs raw data.
All tools share the withings_ prefix and mostly follow a verb_noun pattern (get_body, get_sleep, get_activity). However, withings_sync and withings_trends deviate from the get_* pattern, which is a minor inconsistency.
Eight tools is well-scoped for a health data server, covering each major data type with dedicated query tools plus sync and trends. No tool appears redundant or unnecessary.
The surface covers the core Withings health domains: devices, sync, body composition, sleep, activity, workouts, ECG, and trend analysis. Minor gaps exist around user profile/goals or device settings, but these are not essential for the apparent read-focused purpose.
Maintenance
Related MCP Connectors
Read-only Apple Health data synced from your iPhone: sleep, heart rate, HRV, workouts and trends.
Read wearables and lab health data — sleep, activity, workouts, timeseries, lab tests and orders.
MCP server for Withings health data — sleep, activity, heart, and body metrics.
Read sleep, readiness, activity, stress, heart rate and workouts from the Oura Ring.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables retrieval of health data from Withings smart scales including weight measurements and comprehensive body composition metrics like fat mass, muscle mass, and hydration levels. Supports multiple users, unit preferences, and OAuth authentication for secure access to personal health data.2ISC
- AlicenseAqualityCmaintenanceEnables access to Withings Health API data including body measurements, activity tracking, sleep analysis, workouts, and heart rate monitoring through OAuth2 authentication.81MIT
- AlicenseNot gradedqualityDmaintenanceRead-only Model Context Protocol server for Withings weight and body-composition history, providing normalized measurements, weight history, and latest measurements via OAuth 2.0.MIT
- FlicenseNot gradedqualityDmaintenanceRead access to Withings scale data, including weight and body composition metrics, through a local MCP server.-