fitbit-mcp
The fitbit-mcp server provides an MCP-compliant interface to the Fitbit Web API, enabling local caching, querying, and trend analysis of health and activity data via a local SQLite database.
Core Tools:
fitbit_sync– Sync Fitbit data to a local SQLite cache (initial or incremental). Supports specifying data types and days of history.fitbit_get_heart_rate– Daily resting HR and HR zone breakdowns.fitbit_get_activity– Steps, calories, active minutes, distance.fitbit_get_exercises– Individual workout sessions with duration, calories, HR, and distance. Supports filtering by type.fitbit_get_sleep– Sleep duration, efficiency, start/end times, and stage breakdown (deep, light, REM, wake).fitbit_get_weight– Weight (kg), BMI, and body fat percentage.fitbit_get_spo2– Nightly blood oxygen saturation (avg/min/max). Requires Fitbit Premium.fitbit_get_hrv– Nightly HRV (RMSSD) for overall and deep sleep. Requires Fitbit Premium.fitbit_trends– Aggregated trend analysis (weekly, monthly, quarterly) with optional period comparison.
Additional data available includes Active Zone Minutes, Breathing Rate, Skin Temperature, Cardio Fitness (VO2 Max), Food Log, Paired Devices, Lifetime Stats, and Goals (some live-only).
Key Features:
All query tools support date range filtering and relative dates (e.g.,
30d).Live mode (
live=True) bypasses the cache to fetch directly from the Fitbit API.Tools auto-sync on first use each day.
OAuth 2.0 PKCE authentication with automatic token refresh and rate limit handling.
CLI for OAuth setup, manual sync, and bulk import of existing JSON data.
Configurable paths for credentials and database via environment variables.
Provides tools to sync, query, and analyze Fitbit data including heart rate, activity, sleep, weight, SpO2, and HRV, with local caching for offline access and trend analysis.
fitbit-mcp
Retired. Use google-health-mcp instead.
The Fitbit Web API shuts down on 30 September 2026. Fitbit has also stopped accepting new app registrations, so this package can no longer be set up from scratch: step 2 below needs a registered personal app and there is no longer a way to create one. An existing install keeps working until the shutdown date.
google-health-mcpcovers the same measurements through the Google Health API, and adds ECG and irregular-rhythm notifications. It reads history from Google rather than from this package's cache, so there is nothing to migrate: install it and run one backfill.Not everything carries over. Fitbit's activity goals and its server-side lifetime totals have no equivalent there, and among the fields Google does not serve are heart rate zones, the active-minutes breakdown, VO2 max as a range rather than a single number, sleep efficiency, SpO2 high and low, and BMI. After 30 September this package can no longer fetch them either, so copy your
fitbit.dbbefore then if you want to keep them.
MCP server for the Fitbit Web API with OAuth PKCE, local SQLite cache, and trend analysis.
Designed for Claude Code and other MCP clients. Syncs your Fitbit data to a local database for fast, offline queries - no API calls needed after the initial sync.
Features
OAuth 2.0 PKCE - Secure auth flow, no client secret needed
Local SQLite cache - Sync once, query instantly
Incremental sync - Only fetches new data since last sync
MCP tools - Sync, query (cached data types plus live-only devices/lifetime/goals), and trend analysis
Live mode - Bypass cache and query the API directly
CLI - Auth setup, sync, and JSON import from the command line
Rate limit handling - Activity and food log syncs sleep and retry on 429; other data types report
rate_limitedand resume on the next sync
Related MCP server: Fitbit MCP
Data types
Tool | Data |
| Resting HR, HR zones |
| Steps, calories, active minutes, distance |
| Exercise sessions (name, duration, HR, calories) |
| Duration, efficiency, sleep stages |
| Weight, BMI, body fat % |
| Blood oxygen saturation (avg/min/max) |
| Heart rate variability (RMSSD) |
| Active Zone Minutes with per-zone breakdown |
| Nightly breaths per minute |
| Nightly skin temperature variation (degrees C from baseline) |
| Manually-logged core (body) temperature readings (degrees C) |
| VO2 Max / Cardio Fitness Score |
| Daily food calories + water intake |
| Paired devices, battery level, last sync (live) |
| All-time totals and personal best records (live) |
| User-set daily/weekly activity goals (live) |
| Aggregated averages (weekly/monthly/quarterly) |
Requirements
Python 3.13+ (tested on 3.13 and 3.14 in CI)
A Fitbit developer account with a registered personal app
Setup
1. Install
pip install fitbit-mcpOr run it without installing:
uvx fitbit-mcpFor development from a clone:
pip install -e ".[dev]"2. Register a Fitbit app
Go to dev.fitbit.com/apps and create a new app
Set OAuth 2.0 Application Type to Personal
Set Redirect URL to
http://localhost:8080Note your Client ID (you won't need the client secret - PKCE doesn't use one)
3. Authenticate
fitbit-mcp authThis opens your browser for Fitbit login, exchanges the auth code via PKCE, and saves tokens locally.
Tokens are stored in ~/.config/fitbit-mcp/fitbit_tokens.json with 0600 permissions. Access tokens expire in 8 hours and are refreshed automatically. Refresh tokens expire after 90 days of inactivity.
4. Register with Claude Code
claude mcp add -s user fitbit -- fitbit-mcp5. First sync (optional)
Query tools auto-sync on first use, so you can skip this step. To pre-populate the cache or sync a longer history, run:
fitbit-mcp sync --days 30CLI usage
fitbit-mcp Start the MCP server (stdio transport)
fitbit-mcp -V, --version Print the installed package version
fitbit-mcp auth Interactive OAuth setup
fitbit-mcp doctor Check the setup and report what needs fixing
fitbit-mcp sync Sync data to local cache
--days N Days of history for first sync (default: 30)
--types TYPE,... Data types to sync (default: all)
--since YYYY-MM-DD Backfill from this date, overriding the incremental
resume-from-last-sync cursor and --days
--until YYYY-MM-DD Inclusive end date for a --since backfill; together
they re-fetch exactly that window (e.g. to repair a
gap in the middle of the cache)
fitbit-mcp import Import existing JSON data files
--data-dir PATH Directory containing JSON filesMCP tool reference
Query tools auto-sync on the first query of each day per data type. Use live=True
to bypass the cache entirely and fetch directly from the API.
All query tools accept these common parameters:
start_date- Start date asYYYY-MM-DD,YYYY-MM, or30d(relative). Default: last 30 days.end_date- End date asYYYY-MM-DD. Default: today.live- If true, fetch from Fitbit API instead of cache (bypasses auto-sync).
fitbit_get_exercises also accepts:
exercise_type- Filter by activity name (case-insensitive substring match), e.g."cycling","walk","run". Default: all types.
fitbit_sync
Syncs data from the Fitbit API to the local SQLite cache. Query tools call this automatically on first use of the day, so explicit calls are only needed for longer history or forced refresh.
data_types- What to sync:all,heart_rate,activity,exercises,sleep,weight,spo2,hrv,azm,breathing_rate,skin_temperature,core_temperature,cardio_fitness,food_log. Comma-separated. Default:all.days- Days of history for first sync (default: 30). Subsequent syncs are incremental.since- OptionalYYYY-MM-DD. Backfill from this date regardless of what is already cached, overriding incremental resume anddays.until- OptionalYYYY-MM-DDinclusive end date; requiressince. Together they re-fetch and upsert exactly thesince..untilwindow - use to repair a gap in the middle of the cache without re-pulling everything up to today.
fitbit_trends
Aggregated trend analysis from cached data.
data_type- What to analyse:heart_rate,activity,exercises,sleep,weight,spo2,hrv,azm,breathing_rate,skin_temperature,core_temperature,cardio_fitness,food_log. Default:activity.period- Aggregation:weekly,monthly,quarterly. Default:monthly.start_date- Start date. Default: last 12 months (365 days).end_date- End date. Default: today.compare- Compare two periods:last_30d vs previous_30d,2026-03 vs 2026-02,2026-Q1 vs 2025-Q4. When set,period/start_date/end_dateare ignored.
OAuth scopes
The following Fitbit API scopes are requested during setup:
Scope | Data accessed |
| Steps, calories, active minutes, distance, AZM, lifetime stats, goals |
| Resting HR, HR zones, HRV |
| Sleep duration and stages |
| Weight, BMI, body fat % |
| SpO2 (blood oxygen) |
| User profile (user ID, display name) |
| Nightly breathing rate |
| Skin temperature variation and manually-logged core temperature |
| VO2 Max / Cardio Fitness Score |
| Daily food calorie and water log |
| GPS data on logged exercises |
| Paired devices (battery, last sync) |
These are the scopes needed for all tools. If you only need a subset, edit FITBIT_SCOPES in config.py before setup. After upgrading from a smaller scope set, re-run fitbit-mcp auth to re-authorise.
Configuration
Paths are overridable via environment variables:
Variable | Default | Description |
|
| Directory for OAuth credentials |
|
| SQLite database path |
| unset | If truthy ( |
Offline / cache-only mode
By default the server auto-syncs on demand, so query tools fetch fresh data
without a cron job. Set FITBIT_MCP_OFFLINE=1 to run as a pure cache reader
instead:
No Fitbit credentials are required - the server never touches the token file.
No live API calls are made. Auto-sync is disabled, and
live=True, the live-only tools (fitbit_get_devices,fitbit_get_lifetime_stats,fitbit_get_goals), andfitbit_syncreturn a clear "offline mode" message instead of calling the API.Query tools serve whatever is in the local SQLite cache. Responses are tagged with
"offline_mode": true.
Typical uses:
Multi-device setups - one host runs
fitbit-mcp sync(via cron/systemd) against a shared database; other hosts setFITBIT_MCP_OFFLINE=1and pointFITBIT_MCP_DB_PATHat the same cache, and only read. This keeps the Fitbit OAuth token (single-use, rotating) owned by exactly one host, avoiding refresh collisions.CI and privacy - run queries with no network access and no credentials.
Keeping the cache fresh is then the syncing host's job. Unset
FITBIT_MCP_OFFLINE to return to on-demand auto-sync.
Rate limits
The Fitbit API allows 150 requests per hour. Activity and food log syncs sleep and retry automatically on a 429; the date-range data types instead mark that sync as rate_limited and pick up again on the next run. Be aware:
Activity and food log syncs use 1 API call per day (no date-range endpoint available)
A 30-day initial sync of either uses ~30 of your 150/hour quota
Heart rate, sleep, weight, SpO2, HRV, AZM, breathing rate, skin temperature, core temperature, and cardio fitness use date-range endpoints and are much more efficient
Use live=False (the default) to query from cache and avoid API calls entirely.
Data safety
This project includes a pre-commit hook (scripts/check-no-data.sh) that prevents accidentally committing:
Database files (
*.db,*.db-journal,*.db-wal)Config/credentials (
config/*.json)Large files (>100KB)
Install it after cloning:
ln -sf ../../scripts/check-no-data.sh .git/hooks/pre-commitImporting existing data
If you have existing Fitbit data as JSON files (e.g. from a previous export or script), you can bulk-import them:
fitbit-mcp import --data-dir /path/to/json/files/Expected file names: heart_rate.json, activity.json, exercises.json, sleep.json, weight.json, spo2.json, hrv.json. See src/fitbit_mcp/importer.py for the expected JSON format. Import currently covers these seven types only; the newer types (AZM, breathing rate, skin/core temperature, cardio fitness, food log) are populated via sync, not import.
Contributing
See CONTRIBUTING.md for development setup, the test workflow, and the pre-commit hook. Changes are tracked in CHANGELOG.md.
License
Available Tools
18 toolsfitbit_get_activityA
Get daily activity summaries (steps, calories, active minutes, distance).
Returns data from the local cache by default. Use live=True to fetch from Fitbit API. Run fitbit_sync first to populate the cache.
Note: live=True fetches one API call per day - avoid large ranges to stay within the 150 requests/hour rate limit.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. live: If true, fetch directly from Fitbit API instead of cache.
Returns one entry per day with steps, calories, active minutes, distance. active_minutes = very_active + fairly_active (excludes lightly active).
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries the behavioral transparency burden. It discloses the default cache-backed behavior, the live=True fallback, rate-limit implications, and even the active_minutes aggregation formula (very_active + fairly_active). This is rich, useful context.
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 description is well-structured with a brief summary, a clear note, and parameter breakdown. Each sentence contributes essential information—no redundancy or filler. It is appropriately sized for a data-fetching tool with non-obvious behaviors.
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?
Given the output schema exists, return-value details aren't strictly required, but the description still explains the output shape ('one entry per day') and key metrics. It also covers prerequisites and rate limits, making it complete for a wide range of user intents.
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 schema provides zero descriptions, but the description's 'Args' section compensates thoroughly. It explains start_date acceptable formats ('YYYY-MM-DD', 'YYYY-MM', '30d'), default behavior, end_date default, and the live boolean semantics—far exceeding the schema alone.
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-resource combination: 'Get daily activity summaries' and enumerates key data fields (steps, calories, active minutes, distance). This clearly distinguishes it from sibling tools like fitbit_get_sleep or fitbit_get_food_log.
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?
The description provides clear usage context: it explains the cache-vs-live distinction, instructs users to run fitbit_sync first, and warns about API rate limits. It doesn't explicitly mention when to choose an alternative sibling, but the guidance is practical and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_azmA
Get daily Active Zone Minutes (AZM) - Fitbit's headline cardio metric.
AZM counts minutes spent in heart rate zones at or above Fat Burn intensity. Cardio and Peak zone minutes count double. Returns from local cache by default, auto-syncing if stale. Use live=True to bypass the cache.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. live: If true, fetch directly from Fitbit API instead of cache.
Returns one entry per day with total_minutes plus per-zone breakdown (fat_burn_minutes, cardio_minutes, peak_minutes). Distinct from active_minutes in fitbit_get_activity, which counts wall-clock minutes regardless of intensity.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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 so thoroughly. It discloses the caching behavior ('Returns from local cache by default, auto-syncing if stale'), the option to bypass via live=True, and the exact return shape (per-day total_minutes and per-zone breakdown). It even notes the double-counting rule for Cardio/Peak zones, which is a non-obvious behavioral detail.
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 description is well-organized with a title, a brief explanation, an Args section, Returns section, and a sibling distinction. Every sentence adds value; there is no fluff. It is appropriately sized for the tool's complexity.
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?
The description is complete given the tool's context: it explains the metric, the return format, cache behavior, and the distinction from a similar sibling. An output schema exists, but the description still adds valuable context about the per-zone breakdown. No gaps are apparent.
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?
Despite 0% schema description coverage, the description fully documents all three parameters: start_date (formats and default), end_date (format and default), and live (purpose). It also clarifies the return semantics, which is beyond the schema. This compensates completely for the schema's lack of info.
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+resource: 'Get daily Active Zone Minutes (AZM)' and clearly distinguishes this from the sibling fitbit_get_activity by explaining the difference in what each metric counts (zone minutes vs wall-clock minutes). This makes the purpose unequivocal.
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?
The description provides explicit usage context: when to use live=True vs the default cache, and explicitly contrasts with fitbit_get_activity ('Distinct from active_minutes...'). It also explains the date range defaults, giving clear guidance on when to invoke this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_breathing_rateA
Get nightly breathing rate (avg breaths per minute during sleep).
Sourced during sleep tracking. Useful as an illness/recovery signal: sustained increases of 2-3 bpm above personal baseline can indicate incipient infection or strain. Returns from cache by default, auto-syncing if stale.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. live: If true, fetch directly from Fitbit API instead of cache.
Returns one entry per night with breaths_per_min. Typical adult range: 12-20 bpm at rest.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full transparency burden. It explicitly discloses the cache-first behavior ('Returns from cache by default, auto-syncing if stale'), the 'live' parameter to bypass cache, and the output structure ('one entry per night with breaths_per_min') plus a typical range. This goes beyond most tool descriptions and fully informs the agent about the tool's runtime behavior.
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 description is structured with a clear opening line, a rationale paragraph, an Args block, and a Returns note. Every sentence adds distinct information, and nothing is redundant. Though longer than minimal descriptions, the extra length is justified by the need to compensate for sparse schema info. It remains highly readable and front-loaded.
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?
Given the tool has no annotations and no schema descriptions, the description covers all essential facets: what it returns, when to use it, how it behaves (cache vs live), parameter formats, and output shape. The presence of an output schema means return details are not a burden, but the description still adds interpretive guidance. It is complete enough for an agent to select and invoke the tool correctly without 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?
The input schema provides zero descriptions (0% coverage), but the description compensates fully by documenting all three parameters: start_date (with allowed formats and default), end_date (with format and default), and live (explaining its effect). It also adds contextual meaning (e.g., '30d' accepted as a relative date), which is essential for correct invocation.
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 begins with a specific verb+resource: 'Get nightly breathing rate (avg breaths per minute during sleep)' which precisely states the metric and measurement context. It clearly differentiates from sibling tools by focusing on breathing rate, a unique health metric among the listed getters.
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?
The description provides strong usage context by framing the data as an 'illness/recovery signal' with a concrete threshold ('sustained increases of 2-3 bpm above personal baseline'). This tells the agent when the tool is relevant. However, it does not explicitly mention when not to use it or compare to alternative metrics (e.g., heart rate), so it stops short of full exclusion/alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_cardio_fitnessA
Get Cardio Fitness Score (VO2 Max estimate).
Fitbit estimates VO2 Max from resting HR, HR during walks/runs, and demographics. Updates roughly weekly. Returns from cache by default, auto-syncing if stale.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. live: If true, fetch directly from Fitbit API instead of cache.
Returns entries with vo2_max_low and vo2_max_high (mL/kg/min). Fitbit reports as a range (e.g. 39-43); when a single value is given, low and high are equal. Higher = better cardiorespiratory fitness.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses behavioral traits: the source of the estimate, weekly update frequency, default cache behavior with auto-sync, and the live parameter for direct API fetch. It also explains the return format (vo2_max_low/high range) and semantics (equal when single value, higher is better).
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 description is well-structured with a clear purpose statement, brief explanatory notes, and an organized Args/Returns format. Every sentence adds value, and the length is appropriate for the complexity of the tool.
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?
Given the tool's simplicity and the presence of an output schema (noted but not detailed here), the description covers inputs, outputs, cache behavior, and update frequency. It provides enough context for an agent to select and invoke the tool correctly without needing additional information.
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?
Despite 0% schema description coverage, the description explicitly explains all three parameters: start_date formats ('YYYY-MM-DD', 'YYYY-MM', or '30d') and default, end_date format and default, and the live boolean's meaning. This fully compensates for the schema's lack of descriptions.
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 clearly states 'Get Cardio Fitness Score (VO2 Max estimate)' with a specific verb and resource, and distinguishes from sibling tools by focusing on cardio fitness rather than other metrics. It further explains what the score estimates (from resting HR, HR during walks/runs, demographics), making the tool's purpose unambiguous.
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?
The description provides clear context for usage: updates roughly weekly, returns from cache by default, and auto-syncs if stale, which implies when to use the 'live' parameter. It does not explicitly mention alternatives or when-not conditions, but the context is enough to guide the agent on typical use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_core_temperatureA
Get manually-logged core (body) temperature readings (degrees Celsius).
These are absolute body temperatures the user enters by hand - e.g. a forehead/thermometer reading saved to Fitbit - and are the right source for fever / body-temperature questions. They are NOT the device-derived nightly skin-temperature variation from fitbit_get_skin_temperature. A single day can hold several readings (each timestamped), useful for tracking a fever over time.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. live: If true, fetch directly from Fitbit API instead of cache.
Returns one entry per logged reading with datetime (YYYY-MM-DDThh:mm:ss) and temp_celsius.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that readings are manually logged, absolute body temperatures, distinct from skin temperature variation, and may appear multiple times per day. It also describes the return structure with datetime and temp_celsius. It does not discuss rate limits or error behavior, but for a read-only data retrieval tool the provided context is substantial.
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?
Well-organized and front-loaded with the core purpose. The distinction from skin temperature is concise but essential. The Args section is clear and compact, and every sentence serves a purpose without redundancy.
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?
Given no annotations and 0% schema coverage, the description is exceptionally complete. It covers what the data is, when to use it, how parameters work, and what the return values look like. The presence of an output schema is noted, but the description still adds useful return-value context.
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%, but the description compensates fully by explaining all three parameters: start_date formats and default, end_date format and default, and the live cache-bypass behavior. This goes well beyond the raw schema, giving an agent everything needed to set parameters correctly.
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 starts with a specific verb and resource: 'Get manually-logged core (body) temperature readings' in degrees Celsius. It clearly differentiates from fitbit_get_skin_temperature by emphasizing absolute manually-logged temperatures versus device-derived skin variation.
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?
Explicitly states when to use this tool: for fever/body-temperature questions using manually-logged readings. It also explicitly names the alternative (fitbit_get_skin_temperature) and explains why that tool is not appropriate for this use case, plus notes that multiple readings per day can be expected.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_devicesA
List paired Fitbit devices with battery level and last sync time.
Live-only (no caching) - reflects current device state. Useful for monitoring tracker health, knowing which device produced data, and spotting sync gaps.
Returns one entry per paired device with id, type, device_version, battery (e.g. "High"), battery_level (0-100), last_sync_time, mac, and features list.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
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. It discloses the live-only (no caching) behavior, reflects current device state, and specifies the return structure (one entry per device with listed fields). This goes beyond a simple statement and adds useful operational context, though it doesn't cover auth or error conditions.
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 description is three well-structured sentences: first states the main function, second adds behavioral context and use cases, third details the output fields. Every sentence adds value with no repetition or filler, making it appropriately sized and front-loaded.
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?
This is a simple no-parameter tool with an output schema, and the description covers all necessary aspects: purpose, behavior, use cases, and return format. It effectively differentiates from the many sibling tools and provides enough context for an agent to select and invoke it 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 has zero parameters, so the baseline is 4. The description correctly implies that no filtering is possible (lists all paired devices), which aligns with the empty input schema. No parameter details are missing because there are none.
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 clearly states the tool lists paired Fitbit devices with battery level and last sync time, using a specific verb and resource. This distinguishes it from sibling tools like fitbit_get_activity or fitbit_get_sleep, which target different data domains.
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?
The description provides explicit use cases (monitoring tracker health, knowing which device produced data, spotting sync gaps) and notes the live-only behavior, implying when to use this tool. However, it doesn't name alternative tools or state when not to use it, leaving some room for interpretation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_exercisesA
Get exercise log entries (individual tracked activities).
Returns exercise sessions from the local cache by default. Use live=True to fetch from Fitbit API. Run fitbit_sync first to populate the cache.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. exercise_type: Filter by activity name (case-insensitive substring match), e.g. "cycling", "walk", "run". Default: all types. live: If true, fetch directly from Fitbit API instead of cache.
Returns exercise entries with name, duration, calories, avg heart rate, distance, and source (auto-detect vs manual). Note: HR data from cycling may be unreliable (optical sensor vs handlebar grip).
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No | ||
| exercise_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries the burden. It discloses the cache-by-default behavior, the live fetch option, the need for prior sync, return fields including source, and a data-quality caveat about cycling HR. This is rich, honest behavioral context.
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 description is well-structured with a summary, parameter details, return info, and a caveat. Every sentence serves a purpose, and the length is appropriate for a tool with four parameters.
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?
Even though an output schema exists, the description adds essential behavioral detail: cache vs live source, prerequisite sync, return field list, and a data-quality note. It is fully complete for a cache-backed fetch tool.
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. The Args section thoroughly documents all four parameters with types, formats, defaults, and examples (e.g., 'YYYY-MM-DD', '30d', case-insensitive substring match), adding meaning far beyond 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?
The description uses a specific verb 'Get' with a clear resource 'exercise log entries' and adds 'individual tracked activities' to clarify scope. This distinguishes it from sibling tools like fitbit_get_activity, which likely returns summary 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?
It clearly states when to use the tool (fetching exercise log entries), mentions the cache/default behavior, the live=True alternative, and the prerequisite to run fitbit_sync. It does not explicitly name alternative tools for exclusion, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_food_logA
Get daily food and water log summary.
Returns calories consumed and water intake (in mL) per day. Only populated if the user logs food/water in the Fitbit app. Returns from cache by default, auto-syncing if stale.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. live: If true, fetch directly from Fitbit API. Uses one API call per day.
Returns one entry per day with calories_in and water_ml. Days with no logging are omitted.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses valuable behavior: caching with auto-sync, 'live' mode using one API call per day, and the omission of days with no logging. These details go beyond a basic read operation, but still missing auth requirements or error handling.
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 description is broken into clear sections: purpose, return summary, behavioral notes, and parameter explanations. Every sentence contributes value, with no redundancy or filling 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?
The tool has only 3 simple parameters and an existing output schema, yet the description still covers return shape, cache behavior, live mode, and data availability rules. This is more than sufficient for an agent to select and invoke it 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?
Schema coverage is 0%, but the description fully explains all three parameters: date formats for start_date, defaults for end_date, and the semantic and cost implication of live. This precisely compensates for the schema's lack of parameter descriptions.
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 'Get daily food and water log summary' – a specific verb, resource, and scope. It clearly differentiates from sibling tools like fitbit_get_activity or fitbit_get_sleep by naming the exact data domain (food/water).
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?
The description implies when to use the tool (for food/water data) and gives important context about data being only present if the user logs in the Fitbit app. However, it does not explicitly name alternatives or exclusion conditions, so it stops short of full 'when not to use' guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_goalsA
Get user-set activity goals for steps, distance, calories, etc.
Live-only (no caching). Use to compare actuals (from fitbit_get_activity) against the targets the user set in the Fitbit app.
Args: period: "daily" or "weekly". Default: "daily".
Returns goals dict with keys like steps, distance, calories_out, active_minutes, active_zone_minutes, floors. Weekly omits some fields.
| Name | Required | Description | Default |
|---|---|---|---|
| period | No | daily |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It discloses 'Live-only (no caching)' and 'Weekly omits some fields', which are meaningful behavioral traits beyond the schema. It doesn't cover error handling or authentication, but for a read operation it is sufficiently transparent.
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?
Each sentence earns its place: purpose, usage context, parameter definition, return keys, and a caveat. It is front-loaded with the core action and avoids any fluff or repetition.
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?
Despite its simplicity, the tool has one optional param and an output schema. The description covers purpose, usage, parameters, and output shape, and even ties it to a sibling tool for comparison. This is a complete, self-contained definition for an agent.
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%, but the description compensates fully: it states period accepts 'daily' or 'weekly', defaults to 'daily', and explains the behavioral effect ('Weekly omits some fields'). This adds value well beyond the bare 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 'Get user-set activity goals' with specific fields like steps, distance, calories, and explicitly contrasts with fitbit_get_activity for actuals. The verb-resource pair is specific and distinguishes this from the 17 sibling tools.
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?
Explicitly says 'Use to compare actuals (from fitbit_get_activity) against the targets the user set' and mentions 'Live-only (no caching)'. This gives clear when-to-use context and names a specific alternative tool, satisfying the dimension fully.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_heart_rateA
Get daily resting heart rate and heart rate zones.
Returns resting HR and zone breakdown (Out of Range, Fat Burn, Cardio, Peak) from the local cache by default, auto-syncing if stale. Use live=True to bypass the cache entirely.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. live: If true, fetch directly from Fitbit API instead of cache.
Returns one entry per day with resting_hr and zones array. Zone data: name, minutes, caloriesOut, max/min HR for each zone.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses that data comes 'from the local cache by default, auto-syncing if stale' and that live=True fetches directly from Fitbit, plus it outlines the daily return structure. It doesn't mention auth/rate limits, but the key behavioral traits are well covered.
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 description is well-structured and front-loaded with a one-sentence summary followed by cache/live details, Args, and return format. Every sentence adds value; no fluff or repetition.
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?
Despite having an output schema, the description still explains the return shape (one entry per day, resting_hr, zones array with name/minutes/caloriesOut/min/max). It provides all needed context for dates, caching, and live mode, making this a fully self-contained description.
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%, and the description fully compensates. It explains start_date formats ('YYYY-MM-DD', 'YYYY-MM', or '30d'), defaults, end_date default, and the live flag's effect, adding meaning far beyond the bare schema 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 description opens with a specific verb+resource: 'Get daily resting heart rate and heart rate zones.' It clearly distinguishes this tool from siblings like fitbit_get_hrv or fitbit_get_breathing_rate by naming the exact data returned (resting HR and zone breakdown).
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?
The description clearly explains cache behavior and when to use live=True ('Use live=True to bypass the cache entirely'), plus date format options. It does not explicitly mention alternatives among sibling tools, but the cache-vs-live guidance provides clear contextual usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_hrvA
Get nightly HRV (heart rate variability) data.
Returns data from the local cache by default. Use live=True to fetch from Fitbit API. Run fitbit_sync first to populate the cache.
HRV data is sparse: only nights with on-wrist sleep tracking produce readings. Requires Fitbit Premium for access to this endpoint.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. live: If true, fetch directly from Fitbit API instead of cache.
Returns one entry per night with daily_rmssd and deep_rmssd (ms). RMSSD = root mean square of successive RR interval differences. Higher values generally indicate better recovery and parasympathetic activity.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, disclosing default cache reads, the need for a prior sync, data sparsity, the Premium requirement, and the specific output fields. It also explains the meaning of RMSSD, adding interpretive context beyond a simple fetch.
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 description is well-structured: a one-line summary, followed by cache behavior, caveats, parameter docs, and output explanation. Every section adds necessary value with no redundancy.
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?
The description is comprehensive for a three-parameter tool, explaining the data source, prerequisites, limitations, and output format. Even with an output schema present, it clearly states the fields returned, and the sync instruction mitigates potential empty-cache confusion.
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 Args section provides detailed semantics for all three parameters, including accepted formats for start_date ('YYYY-MM-DD', 'YYYY-MM', or '30d'), defaults for start/end dates, and the boolean `live` flag. Since the schema has no property descriptions (0% coverage), this fully compensates.
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 'Get nightly HRV (heart rate variability) data' uses a specific verb and resource, clearly distinguishing it from sibling tools like fitbit_get_heart_rate and fitbit_get_sleep. The cache/live explanation further reinforces its unique role.
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?
The description explicitly instructs to 'Run fitbit_sync first to populate the cache' and offers the alternative of 'Use live=True to fetch from Fitbit API', giving clear when-to-use and prerequisite guidance. It also notes the Premium requirement, which helps the agent decide applicability.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_lifetime_statsA
Get all-time activity totals and personal best records.
Live-only (no caching). Returns lifetime totals (steps, distance, floors, calories, active score) and personal bests (best day for steps, distance, floors), each with the date the record was set.
Useful for long-term context that the daily activity table can't easily answer (e.g. "what's my best step day ever?").
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses 'Live-only (no caching)' and specifies the exact data returned (lifetime totals and personal bests with dates). It doesn't cover edge cases or failure modes, but for a zero-parameter read operation this is adequate.
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 description is three sentences, front-loaded with the main purpose. Each sentence adds value: purpose, return details, and usage context. There is no redundancy or filler.
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?
Given the tool's simplicity (no params, well-defined return categories) and the existence of an output schema, the description provides sufficient context. It explains what the tool returns and gives a practical use case, making it complete for an AI agent.
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 has zero parameters, so the schema is trivially 100% covered. The description doesn't need to explain parameters, and adds no parameter-related info. Baseline for 0 params is 4, which is appropriate.
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 clearly states it 'Get all-time activity totals and personal best records,' with a specific verb and resource. It distinguishes itself from the daily activity sibling by noting it answers long-term context questions like 'what's my best step day ever?'.
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?
The description provides a clear use case: 'Useful for long-term context that the daily activity table can't easily answer.' This implies when to use it and contrasts with daily activity, but it doesn't explicitly name alternative tools or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_skin_temperatureA
Get nightly skin temperature variation (degrees Celsius from personal baseline).
This is the device-derived RELATIVE deviation recorded during sleep, NOT an absolute body temperature - for fever / body-temperature readings use fitbit_get_core_temperature instead. Fitbit needs ~3 nights to establish a baseline before values appear. Useful as an illness/cycle/recovery signal.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. live: If true, fetch directly from Fitbit API instead of cache.
Returns one entry per night with nightly_relative (degrees C, can be negative) and log_type (e.g. "dermal").
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses that values are relative deviations, not absolute temperature, and that baseline takes ~3 nights. It also describes the return structure (one entry per night with nightly_relative and log_type). Lacks details on error conditions or rate limits, but sufficient for most use cases.
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?
Efficiently structured: summary line, critical clarification, usage note, then parameter list. No redundant information; every sentence adds value.
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?
Despite having an output schema, the description explains the return format (nightly_relative and log_type). It also provides baseline establishment information and use-case context, making the tool well-understood.
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%, but the description fully compensates by explaining each parameter: start_date format options ('YYYY-MM-DD', 'YYYY-MM', or '30d'), end_date format, and the live parameter for cache bypass, including defaults.
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 clearly states the tool retrieves 'nightly skin temperature variation (degrees Celsius from personal baseline)', identifies it as a relative measurement, and distinguishes it from the sibling tool for absolute core temperature. It also lists use cases (illness/cycle/recovery signal).
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?
Explicitly states when to use (relative skin temp) and when not to (use fitbit_get_core_temperature for fever/body temp). Also notes that Fitbit needs ~3 nights to establish a baseline, guiding the agent on data availability.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_sleepA
Get nightly sleep data (duration, stages, efficiency).
Returns sleep data from the local cache by default. Use live=True to fetch from Fitbit API. Run fitbit_sync first to populate the cache.
Sleep data is sparse: only nights with watch-tracked sleep are present. Travel, off-wrist nights, or manual logs may be missing.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. live: If true, fetch directly from Fitbit API instead of cache.
Returns one entry per night with total_minutes, efficiency, start/end times, and stage breakdown (deep, light, REM, wake minutes).
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden for behavioral disclosure. It reveals that data comes from local cache by default, that live=True fetches from the API, that fitbit_sync must be run first, and that data is sparse (missing travel/off-wrist/manual logs). This is rich, honest context beyond the basic function.
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 description is appropriately sized for the tool's complexity, with a clear 'Args:' section. It is front-loaded with the main purpose and usage caveats. A few sentences could be tightened, but every sentence adds value.
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?
The description covers the tool's behavior (cache vs. live, sync dependency), input formats, data sparsity, and return fields (total_minutes, efficiency, start/end times, stage breakdown). With an output schema present, it doesn't need to detail return types further, making it complete for a 3-parameter tool with no annotations.
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 fully explain parameters. It does: start_date formats ('YYYY-MM-DD', 'YYYY-MM', or '30d') and default (last 30 days), end_date format and default (today), live boolean default false. It also explains the return structure, compensating entirely for the missing schema descriptions.
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 clearly states 'Get nightly sleep data (duration, stages, efficiency)', using a specific verb and resource. It differentiates from sibling Fitbit tools by focusing on sleep and describing cache vs. live data. The tool name and description align perfectly.
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?
The description provides explicit guidance: 'Run fitbit_sync first to populate the cache' and 'Use live=True to fetch from Fitbit API.' It also warns about data sparsity for nights without watch-tracked sleep. However, it doesn't explicitly state when not to use this tool versus other sleep-related siblings, though the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_spo2A
Get nightly SpO2 (blood oxygen saturation) data.
Returns data from the local cache by default. Use live=True to fetch from Fitbit API. Run fitbit_sync first to populate the cache.
SpO2 data is sparse: only nights with on-wrist sleep tracking produce readings. Requires Fitbit Premium for access to this endpoint.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. live: If true, fetch directly from Fitbit API instead of cache.
Returns one entry per night with avg, min, max SpO2 percentage. Normal range: 95-100%. Below 90% may indicate sleep apnea.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavioral traits: default local cache, live fetching option, dependency on sync, data sparsity, and Premium requirement. It also explains normal range and health implications, exceeding basic transparency.
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 description is well-structured with a clear first sentence, then bullet points and parameter details. It is moderately concise; a minor reduction in health background could tighten it slightly, but overall it is efficient.
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?
Given the tool's moderate complexity (3 parameters, health context), the description covers purpose, behavior, parameter semantics, output format (one entry per night with avg/min/max), and prerequisites. The output schema exists, so return details are adequately supplemented.
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%, yet the description adds significant meaning: it specifies date formats (YYYY-MM-DD, YYYY-MM, 30d), defaults (last 30 days for start_date, today for end_date), and the boolean live parameter. This thoroughly compensates for the schema's lack of descriptions.
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 clearly states the tool retrieves nightly SpO2 data, distinguishing it from sibling tools that handle other health metrics (e.g., heart rate, sleep). The verb 'Get' and resource 'nightly SpO2 data' are specific and unambiguous.
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?
The description explains when to use live=True vs default cache, and prerequisites (run fitbit_sync first). It notes data sparsity and Premium requirement. Although it does not explicitly contrast with alternatives, the unique SpO2 focus makes context clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_get_weightA
Get weight log entries (weight, BMI, body fat percentage).
Returns data from the local cache by default. Use live=True to fetch from Fitbit API. Run fitbit_sync first to populate the cache.
Weight data is sparse: only days with weigh-in entries are present.
Args: start_date: Start date as "YYYY-MM-DD", "YYYY-MM", or "30d". Default: last 30 days. end_date: End date as "YYYY-MM-DD". Default: today. live: If true, fetch directly from Fitbit API instead of cache.
Returns one entry per weigh-in with weight_kg, bmi, fat_pct.
| Name | Required | Description | Default |
|---|---|---|---|
| live | No | ||
| end_date | No | ||
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden. It discloses that data comes from a local cache by default, requires a sync first, is sparse (only days with weigh-ins), and returns one entry per weigh-in with specific fields. This is valuable behavioral context beyond 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 description is well-structured with a brief introduction, a note on cache and sparse data, and a clear Args list. Every sentence adds value—no redundancy or irrelevant details. The format is easy to scan and understand.
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?
The description is complete for the tool's complexity: it covers parameters, return format, cache behavior, and prerequisites. Some minor missing details like error handling or timezone considerations, but these are not essential for selection and invocation. The output schema also lessens the need to describe return values.
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%, but the description's Args section fully explains each parameter: start_date format and default, end_date format and default, and live flag meaning. This compensates entirely for the schema's lack of descriptions, adding critical format details like 'YYYY-MM-DD', 'YYYY-MM', or '30d'.
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 clearly states 'Get weight log entries (weight, BMI, body fat percentage)', specifying the verb, resource, and scope. It distinguishes from sibling tools like fitbit_get_food_log and fitbit_get_activity by focusing on weight-specific data, and the mention of cache vs. live modes further clarifies its role.
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?
The description provides explicit guidance: 'Run fitbit_sync first to populate the cache' and 'Use live=True to fetch from Fitbit API instead of cache.' It also clarifies default behavior (cache) and data sparsity. It does not explicitly contrast with alternative tools, but the prerequisites and mode selection are clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_syncA
Sync Fitbit health data to the local cache.
Fetches data from the Fitbit API and stores it in SQLite for fast offline queries. Run this before using other fitbit_get_* tools.
Syncs incrementally: only fetches data newer than the most recent entry in each table. First sync fetches the specified number of days.
Args: data_types: What to sync. Options: "all", "heart_rate", "activity", "exercises", "sleep", "weight", "spo2", "hrv", "azm", "breathing_rate", "skin_temperature", "core_temperature", "cardio_fitness", "food_log". Comma-separated for multiple, e.g. "sleep,hrv". Default: "all". days: Days of history for first sync (default: 30). Ignored on subsequent syncs (uses last synced date). since: Optional "YYYY-MM-DD" backfill date. When set, fetches from this date regardless of what is already cached - use to pull history older than the current cache. Overrides incremental resume and days. until: Optional "YYYY-MM-DD" inclusive end date; requires since. Together they re-fetch and upsert exactly the since..until window - use to repair a gap in the middle of the cache without re-pulling everything from the gap to today.
Returns summary of records synced per data type. Not for querying data - use fitbit_get_heart_rate, fitbit_get_activity, fitbit_get_sleep, etc. instead.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | ||
| since | No | ||
| until | No | ||
| data_types | No | all |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and excels: it explains incremental sync, first-sync behavior, the role of 'since'/'until' for backfill and gap repair, and the return summary. This goes beyond basic semantics and provides operational context.
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 description is lengthy but well-structured: a one-line summary, a brief context statement, a clear argument section, and a closing note on return value. Every sentence adds information, and the structure makes it scannable.
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?
Given the tool's complexity (four parameters, incremental logic, special backfill scenarios) and the empty schema/annotations, the description covers all necessary ground: purpose, usage, parameter semantics, and return behavior. It is complete enough for an agent to invoke correctly without additional clarification.
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 input schema has no descriptions (0% coverage), so the description is entirely responsible for parameter meaning. It thoroughly explains data_types with options and default, days with its behavior, and since/until with precise usage examples. This fully compensates for the schema gap.
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+resource statement: 'Sync Fitbit health data to the local cache.' It clearly distinguishes itself from the fitbit_get_* tools by stating it fetches data from the Fitbit API into SQLite, not for querying.
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?
Explicitly instructs to 'Run this before using other fitbit_get_* tools' and provides a clear exclusion: 'Not for querying data - use fitbit_get_heart_rate, fitbit_get_activity, fitbit_get_sleep, etc. instead.' This leaves no ambiguity about when to use versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fitbit_trendsA
Analyse trends in cached Fitbit data.
Computes averages and totals over time from the local cache, auto-syncing if stale.
Args: data_type: What to analyse. Options: "heart_rate", "activity", "exercises", "sleep", "weight", "spo2", "hrv", "azm", "breathing_rate", "skin_temperature", "core_temperature", "cardio_fitness", "food_log". Default: "activity". period: Aggregation period. Options: "weekly", "monthly", "quarterly". Default: "monthly". start_date: Start date as "YYYY-MM-DD" or "365d". Default: last 12 months. end_date: End date as "YYYY-MM-DD". 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 per period. For activity: steps, distance, active minutes. For exercises: sessions, duration, calories. For sleep: duration, efficiency, stage breakdown. For heart_rate: resting HR min/avg/max. For weight: weight, fat%, BMI. For spo2: avg/min/max oxygen saturation. For hrv: daily and deep RMSSD. Not for raw data - use fitbit_get_* tools instead.
| Name | Required | Description | Default |
|---|---|---|---|
| period | No | monthly | |
| compare | No | ||
| end_date | No | ||
| data_type | No | activity | |
| start_date | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations available, the description carries the full burden of behavioral disclosure. It discloses that the tool auto-syncs from the local cache if stale, implying potential network or cache side effects. It also details return values per data type and notes that compare ignores other date parameters. It lacks error-handling or permission details, but overall it is transparent.
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 description is longer than a typical two-sentence summary but is well-structured with a one-line overview, an Args section, a Returns section, and a final note. Every sentence adds value, especially the detailed parameter options and per-data-type outputs. It is front-loaded with the core purpose and uses clear formatting, though it could be slightly tightened.
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 tool with 5 optional parameters, a complex compare feature, and 13 data types with varied output fields, the description covers parameter semantics, return values, and cache-sync behavior. It even provides examples for compare and date formats. It omits edge cases like invalid dates or empty data, but the presence of an output schema and the description's thoroughness make it sufficiently complete.
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 input schema provides zero parameter descriptions (0% coverage), so the description's 'Args' section is essential and fully compensates. It defines data_type and period options with defaults, start/end date formats, and the compare format with examples. Every parameter is semantically described, including the behavior that compare overrides others.
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, 'Analyse trends in cached Fitbit data,' then elaborates on computing averages and totals over time. It clearly distinguishes itself from sibling fitbit_get_* tools by explicitly stating it is not for raw data and by listing supported data types. This makes its purpose unambiguous.
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?
The description provides clear guidance on when to use the tool for aggregated trends and explicitly notes 'Not for raw data - use fitbit_get_* tools instead,' naming the alternative. It also explains the compare feature and how it overrides period/start_date/end_date, giving users context. However, it stops short of describing specific scenarios beyond the raw-data exclusion, so it is not a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool clearly targets a distinct Fitbit data type (activity, sleep, heart rate, etc.). The only potential confusion between skin and core temperature is explicitly disambiguated in the descriptions, and other similar metrics (e.g., activity vs. AZM vs. exercises) are clearly differentiated.
All tools follow a consistent `fitbit_<verb>_<noun>` pattern with snake_case throughout. Retrieval tools uniformly use `fitbit_get_*`, and the two non-retrieval tools (`fitbit_sync`, `fitbit_trends`) are named with distinct, appropriate actions that do not break the overall pattern.
With 18 tools, the server is slightly above the typical 3-15 tool range, but the count is justified by the breadth of Fitbit's health data metrics. Each tool serves a unique, non-redundant purpose, so the set feels comprehensive rather than bloated.
The tool set provides broad coverage of Fitbit's data ecosystem, including activity, sleep, heart rate, HRV, SpO2, breathing, temperature, weight, food, exercise, plus device info and goals. No obvious missing operations for a read-only health data retrieval server; the sync tool ensures offline caching is fully supported.
Maintenance
Related MCP Connectors
MCP server for Withings health data — sleep, activity, heart, and body metrics.
Remote MCP server for training, nutrition, wellness, and performance data with OAuth 2.0.
Hosted MCP server with managed OAuth for 15+ toolkits: Google Workspace, Fitbit, Oura, Kalshi, etc.
Multi-tenant hosted MCP server for Oura Ring — 21 read-only tools, OAuth per user.
Related MCP Servers
- AlicenseAqualityCmaintenanceA Model Context Protocol server that bridges LLMs (like Claude) with the Fitbit API, allowing the LLM to request and retrieve user health and fitness data through defined tools.132233MIT
- AlicenseAqualityAmaintenanceLocal-first MCP server that connects AI agents to your Fitbit activity, sleep, heart-rate, HRV, SpO2 and weight data.331631MIT
- AlicenseAqualityCmaintenanceMCP server for the Oura Ring API v2, providing access to sleep, activity, readiness, heart rate, and workout data via OAuth.51881MIT
- AlicenseNot gradedqualityDmaintenanceA local MCP server providing read-only access to WHOOP fitness data via direct OAuth, with a local SQLite cache for offline queries.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/partymola/fitbit-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server