Skip to main content
Glama

get_recovery

Read-only

Retrieve a date's Garmin sleep, HRV, Body Battery, stress, resting heart rate, and training readiness in one call to assess recovery.

Instructions

Combine one date's Garmin sleep, HRV, Body Battery, stress, resting HR, and training readiness in a single call.

Use for how recovered you are on one date; use get_recovery_trend for change over several days, get_training_readiness for Garmin's readiness factors alone, or get_training_context to add the past week's training. Every component is Garmin-provided; no recovery score is calculated. A component that cannot be read is listed in availability with the reason (missing, rate-limited, or failed) while the rest is still returned; expired authentication fails the whole call.

Field notes: sleep is the night that ended on date. body_battery.charged/drained are whole-day totals; sleep.body_battery_change is the overnight change. Times such as sleep.sleep_start are ISO 8601 with an explicit UTC offset and already local: never add the offset again.

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
dateNoCalendar date in YYYY-MM-DD format, e.g. 2026-10-09; any past date Garmin still stores. Omit or pass null for today in the server's local timezone.

Output Schema

NameRequiredDescriptionDefault
hrvNo
dateYes
noteNoGarmin-provided metrics only; no derived medical or recovery score.
sleepNo
stressNo
availabilityNo
body_batteryNo
resting_hr_bpmNo
training_readinessNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changedv0.3.1
    • changedInput schema / properties / date / anyOf
      Previous value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / date / description
      Added value: +"Calendar date in YYYY-MM-DD format, e.g. 2026-10-09; any past date Garmin still stores. Omit or pass null for today in the server's local timezone."
    • 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"
      +  },
      +  "BodyBatterySummary": {
      +    "properties": {
      +      "availability": {
      +        "items": {
      +          "$ref": "#/$defs/AvailabilityNotice"
      +        },
      +        "title": "Availability",
      +        "type": "array"
      +      },
      +      "charged": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Charged"
      +      },
      +      "date": {
      +        "title": "Date",
      +        "type": "string"
      +      },
      +      "drained": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Drained"
      +      },
      +      "end_level": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "End Level"
      +      },
      +      "highest_level": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Highest Level"
      +      },
      +      "lowest_level": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Lowest Level"
      +      },
      +      "start_level": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Start Level"
      +      },
      +      "timeseries": {
      +        "anyOf": [
      +          {
      +            "items": {
      +              "$ref": "#/$defs/TimePoint"
      +            },
      +            "type": "array"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Timeseries"
      +      }
      +    },
      +    "required": [
      +      "date"
      +    ],
      +    "title": "BodyBatterySummary",
      +    "type": "object"
      +  },
      +  "HrvSummary": {
      +    "properties": {
      +      "availability": {
      +        "items": {
      +          "$ref": "#/$defs/AvailabilityNotice"
      +        },
      +        "title": "Availability",
      +        "type": "array"
      +      },
      +      "baseline_high_ms": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Baseline High Ms"
      +      },
      +      "baseline_low_ms": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Baseline Low Ms"
      +      },
      +      "date": {
      +        "title": "Date",
      +        "type": "string"
      +      },
      +      "last_night_average_ms": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Last Night Average Ms"
      +      },
      +      "nightly_average_ms": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Nightly Average Ms"
      +      },
      +      "status": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Status"
      +      },
      +      "timeseries": {
      +        "anyOf": [
      +          {
      +            "items": {
      +              "$ref": "#/$defs/TimePoint"
      +            },
      +            "type": "array"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Timeseries"
      +      },
      +      "weekly_average_ms": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Weekly Average Ms"
      +      }
      +    },
      +    "required": [
      +      "date"
      +    ],
      +    "title": "HrvSummary",
      +    "type": "object"
      +  },
      +  "SleepSummary": {
      +    "properties": {
      +      "availability": {
      +        "items": {
      +          "$ref": "#/$defs/AvailabilityNotice"
      +        },
      +        "title": "Availability",
      +        "type": "array"
      +      },
      +      "average_hr_bpm": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Average Hr Bpm"
      +      },
      +      "average_respiration": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Average Respiration"
      +      },
      +      "average_spo2_percent": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Average Spo2 Percent"
      +      },
      +      "average_stress": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "description": "Garmin's average stress during sleep, to one decimal. A different metric from the whole-day average_stress of get_stress and get_daily_summary.",
      +        "title": "Average Stress"
      +      },
      +      "awake_count": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Awake Count"
      +      },
      +      "awake_seconds": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Awake Seconds"
      +      },
      +      "body_battery_change": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Body Battery Change"
      +      },
      +      "date": {
      +        "title": "Date",
      +        "type": "string"
      +      },
      +      "deep_sleep_seconds": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Deep Sleep Seconds"
      +      },
      +      "highest_respiration": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Highest Respiration"
      +      },
      +      "light_sleep_seconds": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Light Sleep Seconds"
      +      },
      +      "lowest_respiration": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Lowest Respiration"
      +      },
      +      "lowest_spo2_percent": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Lowest Spo2 Percent"
      +      },
      +      "nap_seconds": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Nap Seconds"
      +      },
      +      "rem_sleep_seconds": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Rem Sleep Seconds"
      +      },
      +      "restless_moments_count": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Restless Moments Count"
      +      },
      +      "skin_temperature_basis": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Skin Temperature Basis"
      +      },
      +      "skin_temperature_calibration_days": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Skin Temperature Calibration Days"
      +      },
      +      "skin_temperature_deviation_c": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Skin Temperature Deviation C"
      +      },
      +      "sleep_alignment_status": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Sleep Alignment Status"
      +      },
      +      "sleep_end": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "description": "Sleep end: ISO 8601 with an explicit UTC offset, e.g. 2026-10-09T23:18:16+02:00. The wall time is already local; never add the offset again. The offset is the one Garmin recorded for the device at that moment, or this computer's time zone when Garmin gives only UTC.",
      +        "title": "Sleep End"
      +      },
      +      "sleep_need_baseline_minutes": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Sleep Need Baseline Minutes"
      +      },
      +      "sleep_need_feedback": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Sleep Need Feedback"
      +      },
      +      "sleep_need_minutes": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Sleep Need Minutes"
      +      },
      +      "sleep_score": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Sleep Score"
      +      },
      +      "sleep_score_feedback": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Sleep Score Feedback"
      +      },
      +      "sleep_start": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "description": "Sleep start: ISO 8601 with an explicit UTC offset, e.g. 2026-10-09T23:18:16+02:00. The wall time is already local; never add the offset again. The offset is the one Garmin recorded for the device at that moment, or this computer's time zone when Garmin gives only UTC.",
      +        "title": "Sleep Start"
      +      },
      +      "total_sleep_seconds": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Total Sleep Seconds"
      +      }
      +    },
      +    "required": [
      +      "date"
      +    ],
      +    "title": "SleepSummary",
      +    "type": "object"
      +  },
      +  "StressSummary": {
      +    "properties": {
      +      "availability": {
      +        "items": {
      +          "$ref": "#/$defs/AvailabilityNotice"
      +        },
      +        "title": "Availability",
      +        "type": "array"
      +      },
      +      "average_stress": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "description": "Garmin's whole-day average stress (0-100). Sleep stress is a separate metric reported by get_sleep.",
      +        "title": "Average Stress"
      +      },
      +      "date": {
      +        "title": "Date",
      +        "type": "string"
      +      },
      +      "high_duration_seconds": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "High Duration Seconds"
      +      },
      +      "low_duration_seconds": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Low Duration Seconds"
      +      },
      +      "max_stress": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Max Stress"
      +      },
      +      "medium_duration_seconds": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Medium Duration Seconds"
      +      },
      +      "rest_duration_seconds": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Rest Duration Seconds"
      +      },
      +      "stress_duration_seconds": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Stress Duration Seconds"
      +      },
      +      "timeseries": {
      +        "anyOf": [
      +          {
      +            "items": {
      +              "$ref": "#/$defs/TimePoint"
      +            },
      +            "type": "array"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Timeseries"
      +      }
      +    },
      +    "required": [
      +      "date"
      +    ],
      +    "title": "StressSummary",
      +    "type": "object"
      +  },
      +  "TimePoint": {
      +    "properties": {
      +      "timestamp": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "integer"
      +          }
      +        ],
      +        "description": "Reading time: ISO 8601 with an explicit UTC offset, e.g. 2026-10-09T23:18:16+02:00. The wall time is already local; never add the offset again. The offset is the one Garmin recorded for the device at that moment, or this computer's time zone when Garmin gives only UTC. A bare date or number is a Garmin value that could not be parsed as a time.",
      +        "title": "Timestamp"
      +      },
      +      "value": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "integer"
      +          }
      +        ],
      +        "title": "Value"
      +      }
      +    },
      +    "required": [
      +      "timestamp",
      +      "value"
      +    ],
      +    "title": "TimePoint",
      +    "type": "object"
      +  },
      +  "TrainingReadiness": {
      +    "properties": {
      +      "acute_load_factor_feedback": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Acute Load Factor Feedback"
      +      },
      +      "acute_load_factor_percent": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Acute Load Factor Percent"
      +      },
      +      "availability": {
      +        "items": {
      +          "$ref": "#/$defs/AvailabilityNotice"
      +        },
      +        "title": "Availability",
      +        "type": "array"
      +      },
      +      "date": {
      +        "title": "Date",
      +        "type": "string"
      +      },
      +      "feedback": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Feedback"
      +      },
      +      "hrv_factor_feedback": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Hrv Factor Feedback"
      +      },
      +      "hrv_factor_percent": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Hrv Factor Percent"
      +      },
      +      "level": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Level"
      +      },
      +      "recovery_time_change_phrase": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Recovery Time Change Phrase"
      +      },
      +      "recovery_time_factor_feedback": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Recovery Time Factor Feedback"
      +      },
      +      "recovery_time_hours": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "description": "Garmin's remaining recovery time in hours, to one decimal.",
      +        "title": "Recovery Time Hours"
      +      },
      +      "score": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Score"
      +      },
      +      "sleep_history_factor_feedback": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Sleep History Factor Feedback"
      +      },
      +      "sleep_history_factor_percent": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Sleep History Factor Percent"
      +      },
      +      "sleep_score": {
      +        "anyOf": [
      +          {
      +            "type": "integer"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Sleep Score"
      +      },
      +      "sleep_score_factor_feedback": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Sleep Score Factor Feedback"
      +      },
      +      "stress_history_factor_feedback": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Stress History Factor Feedback"
      +      },
      +      "stress_history_factor_percent": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "title": "Stress History Factor Percent"
      +      },
      +      "timestamp": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "default": null,
      +        "description": "When Garmin calculated this readiness: ISO 8601 with an explicit UTC offset, e.g. 2026-10-09T23:18:16+02:00. The wall time is already local; never add the offset again. The offset is the one Garmin recorded for the device at that moment, or this computer's time zone when Garmin gives only UTC.",
      +        "title": "Timestamp"
      +      }
      +    },
      +    "required": [
      +      "date"
      +    ],
      +    "title": "TrainingReadiness",
      +    "type": "object"
      +  }
      +}
    • removedOutput schema / additionalProperties
      Removed value: -true
    • addedOutput schema / properties
      Added value: +{
      +  "availability": {
      +    "items": {
      +      "$ref": "#/$defs/AvailabilityNotice"
      +    },
      +    "title": "Availability",
      +    "type": "array"
      +  },
      +  "body_battery": {
      +    "anyOf": [
      +      {
      +        "$ref": "#/$defs/BodyBatterySummary"
      +      },
      +      {
      +        "type": "null"
      +      }
      +    ],
      +    "default": null
      +  },
      +  "date": {
      +    "title": "Date",
      +    "type": "string"
      +  },
      +  "hrv": {
      +    "anyOf": [
      +      {
      +        "$ref": "#/$defs/HrvSummary"
      +      },
      +      {
      +        "type": "null"
      +      }
      +    ],
      +    "default": null
      +  },
      +  "note": {
      +    "default": "Garmin-provided metrics only; no derived medical or recovery score.",
      +    "title": "Note",
      +    "type": "string"
      +  },
      +  "resting_hr_bpm": {
      +    "anyOf": [
      +      {
      +        "type": "integer"
      +      },
      +      {
      +        "type": "null"
      +      }
      +    ],
      +    "default": null,
      +    "title": "Resting Hr Bpm"
      +  },
      +  "sleep": {
      +    "anyOf": [
      +      {
      +        "$ref": "#/$defs/SleepSummary"
      +      },
      +      {
      +        "type": "null"
      +      }
      +    ],
      +    "default": null
      +  },
      +  "stress": {
      +    "anyOf": [
      +      {
      +        "$ref": "#/$defs/StressSummary"
      +      },
      +      {
      +        "type": "null"
      +      }
      +    ],
      +    "default": null
      +  },
      +  "training_readiness": {
      +    "anyOf": [
      +      {
      +        "$ref": "#/$defs/TrainingReadiness"
      +      },
      +      {
      +        "type": "null"
      +      }
      +    ],
      +    "default": null
      +  }
      +}
    • addedOutput schema / required
      Added value: +[
      +  "date"
      +]
    • changedOutput schema / title
      Previous value: -"get_recoveryDictOutput"New value: +"RecoverySummary"
  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?

Goes well beyond the annotations: it discloses partial-failure semantics (unreadable components appear in availability with reason missing/rate-limited/failed while the rest still returns), that expired auth fails the whole call, that failures are not retried, and that it may update the local cache but never modifies the Garmin account. It also states no recovery score is computed, which prevents a wrong expectation about the payload.

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 sibling routing, then failure semantics, then field notes — a sensible order. It is longer than typical for a one-parameter tool, but nearly every sentence carries actionable information; only the field-note section is dense enough to risk skimming.

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?

With an output schema present, return values need not be explained, and the description still covers the gaps that matter: auth prerequisite, partial vs. total failure, retry behavior, cache side effect, and how to read the time fields. Nothing an agent needs to call this correctly is missing.

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 single date parameter is fully documented there, so the baseline is 3. The description adds genuine meaning by clarifying what the date refers to ("sleep is the night that ended on date") and the timezone/ISO-8601 handling of nested timestamps, which the schema does not cover.

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 opening sentence names the specific resource (Garmin sleep, HRV, Body Battery, stress, resting HR, training readiness) and the scope (one date, single call). It explicitly distinguishes itself from get_recovery_trend, get_training_readiness, and get_training_context, so an agent can route without opening a 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?

Explicit when-to-use ("how recovered you are on one date") plus three named alternatives with the condition that selects each: trend for change over days, training_readiness for Garmin's factors alone, training_context to add the past week's training. 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.