Skip to main content
Glama

get_recovery_trend

Read-only

Track Garmin recovery trends for the past 1–28 days, comparing today’s sleep, HRV, resting heart rate, readiness, and Body Battery with prior days to reveal changes over time.

Instructions

Trend Garmin sleep score, sleep HR, skin-temperature deviation, HRV, resting HR, training readiness, and Body Battery for each of the last 1-28 days, comparing today with the preceding days.

Use for change over time, such as the past week or four weeks; use get_recovery for one date or get_training_context to relate one date to recent training. For periods longer than 28 days, call get_recovery for individual dates. Each comparison discloses its baseline dates and sample count; days without data are listed in missing_dates, never filled in.

Readiness is read one day at a time, so a first request for a long window can take longer; later requests reuse the local cache. If Garmin rate-limits partway, the trend is still returned, with an availability notice naming the days whose readiness is unknown.

Field notes: body_battery_charged/drained are whole-day totals, while body_battery_change_during_sleep is the overnight change. hrv_weekly_average_ms is Garmin's rolling 7-day mean and is given no deviation. Skin temperature is a deviation from the personal baseline, not body temperature.

Requires saved local Garmin authentication (garmin-owl-auth). Reads Garmin and may update the local cache; never changes your Garmin account. Garmin failures are not retried automatically.

Input Schema

NameRequiredDescriptionDefault
daysNoWindow length in days, an integer from 1 to 28, ending today inclusive (today is day 1); defaults to 7. Typical values are 7, 14, or 28.

Output Schema

NameRequiredDescriptionDefault
daysYes
pointsYes
metricsYes
availabilityNo
missing_datesYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed8 schema fields changedv0.3.1
    • addedInput schema / properties / days / description
      Added value: +"Window length in days, an integer from 1 to 28, ending today inclusive (today is day 1); defaults to 7. Typical values are 7, 14, or 28."
    • addedInput schema / properties / days / maximum
      Added value: +28
    • addedInput schema / properties / days / minimum
      Added value: +1
    • addedOutput schema / $defs
      Added value: +{
      +  "AvailabilityNotice": {
      +    "properties": {
      +      "field": {
      +        "title": "Field",
      +        "type": "string"
      +      },
      +      "message": {
      +        "title": "Message",
      +        "type": "string"
      +      },
      +      "status": {
      +        "title": "Status",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "field",
      +      "status",
      +      "message"
      +    ],
      +    "title": "AvailabilityNotice",
      +    "type": "object"
      +  },
      +  "DailyRecoveryPoint": {
      +    "properties": {
      +      "average_sleep_hr_bpm": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Average Sleep Hr Bpm"
      +      },
      +      "body_battery_change_during_sleep": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Body Battery Change During Sleep"
      +      },
      +      "body_battery_charged": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Body Battery Charged"
      +      },
      +      "body_battery_drained": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Body Battery Drained"
      +      },
      +      "date": {
      +        "title": "Date",
      +        "type": "string"
      +      },
      +      "hrv_nightly_average_ms": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Hrv Nightly Average Ms"
      +      },
      +      "hrv_weekly_average_ms": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Hrv Weekly Average Ms"
      +      },
      +      "recovery_time_hours": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Recovery Time Hours"
      +      },
      +      "resting_hr_bpm": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Resting Hr Bpm"
      +      },
      +      "skin_temperature_deviation_c": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Skin Temperature Deviation C"
      +      },
      +      "sleep_score": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Sleep Score"
      +      },
      +      "training_readiness": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Training Readiness"
      +      }
      +    },
      +    "required": [
      +      "date"
      +    ],
      +    "title": "DailyRecoveryPoint",
      +    "type": "object"
      +  },
      +  "TrendMetric": {
      +    "properties": {
      +      "baseline_end": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Baseline End"
      +      },
      +      "baseline_start": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Baseline Start"
      +      },
      +      "calculation": {
      +        "default": "Current date compared with the mean of available preceding days.",
      +        "title": "Calculation",
      +        "type": "string"
      +      },
      +      "current": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Current"
      +      },
      +      "current_date": {
      +        "title": "Current Date",
      +        "type": "string"
      +      },
      +      "difference": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Difference"
      +      },
      +      "metric": {
      +        "title": "Metric",
      +        "type": "string"
      +      },
      +      "percent_difference": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Percent Difference"
      +      },
      +      "recent_average": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Recent Average"
      +      },
      +      "sample_days": {
      +        "default": 0,
      +        "title": "Sample Days",
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "metric",
      +      "current_date"
      +    ],
      +    "title": "TrendMetric",
      +    "type": "object"
      +  }
      +}
    • removedOutput schema / additionalProperties
      Removed value: -true
    • addedOutput schema / properties
      Added value: +{
      +  "availability": {
      +    "items": {
      +      "$ref": "#/$defs/AvailabilityNotice"
      +    },
      +    "title": "Availability",
      +    "type": "array"
      +  },
      +  "days": {
      +    "title": "Days",
      +    "type": "integer"
      +  },
      +  "metrics": {
      +    "items": {
      +      "$ref": "#/$defs/TrendMetric"
      +    },
      +    "title": "Metrics",
      +    "type": "array"
      +  },
      +  "missing_dates": {
      +    "items": {
      +      "type": "string"
      +    },
      +    "title": "Missing Dates",
      +    "type": "array"
      +  },
      +  "points": {
      +    "items": {
      +      "$ref": "#/$defs/DailyRecoveryPoint"
      +    },
      +    "title": "Points",
      +    "type": "array"
      +  }
      +}
    • addedOutput schema / required
      Added value: +[
      +  "days",
      +  "points",
      +  "metrics",
      +  "missing_dates"
      +]
    • changedOutput schema / title
      Previous value: -"get_recovery_trendDictOutput"New value: +"RecoveryTrend"
  2. First observedv0.1.0

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/openWorld annotations, the description discloses non-obvious behavior: readiness is fetched one day at a time so first long-window calls are slow, later calls hit a local cache, partial rate-limit results are still returned with an availability notice, days without data appear in missing_dates rather than being filled, and failures are not retried. It also states the auth prerequisite (garmin-owl-auth) and that the account is never modified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and metric list, then usage routing, then caveats, then field notes — a sensible layered structure. It is on the long side and the field-notes paragraph could be tightened, but nearly every sentence carries distinct information an agent would otherwise have to guess.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with an output schema, annotations, and open-world semantics, the description covers everything an agent needs: scope, alternatives, auth requirement, latency/cache behavior, partial-failure handling, missing-data semantics, and interpretation notes for ambiguous fields (body battery totals vs overnight, HRV rolling mean, skin temp as deviation).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the `days` parameter is already well documented in-schema (1-28, default 7, today inclusive). The description reinforces the window semantics ('last 1-28 days') and adds the important framing that the window compares today against preceding days, which the schema does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence names a specific verb (trend over time) and enumerates the exact metrics covered (sleep score, sleep HR, skin temp, HRV, resting HR, training readiness, Body Battery) plus the window (last 1-28 days) and the comparison model. An agent can distinguish this from get_recovery, get_training_context, and the single-metric siblings 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use it ('change over time, such as the past week or four weeks') and names the alternatives with their selecting conditions: get_recovery for a single date, get_training_context for relating one date to recent training, and looping get_recovery for periods beyond 28 days. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.