Skip to main content
Glama
MetricBridge (formerly Health Export AI)

MetricBridge (formerly Health Export AI)

get_health_metrics

Read-onlyIdempotent

Retrieve Apple Health metric values over a date range, filter by logged events, and aggregate by day, week, month, quarter, or year. Check coverage and recompute details before trusting long windows.

Instructions

Get values for a metric (or all metrics) over an optional date range, with an aggregate (avg/sum/min/max/latest). The core data-retrieval tool. Every result carries a coverage block giving the metric's real firstDate/lastDate/days: check it before trusting a long window, and note that aggregate is always computed over the full range even when points are rolled up. Single-metric answers also list any logged point events inside the window as segmentBoundaries. For blood_pressure_systolic or blood_pressure_diastolic at day granularity, the individual readings behind the daily mean are attached as readings [{t, systolic, diastolic, source, manual}] when the app exported them (health-readings.json), the most recent 150 in range, with readingsOmitted counting the rest. A day the app rebuilt after samples arrived late (or were deleted) carries recomputed_at, and a metric with rebuilt or possibly stale past days carries a recompute block (backfilled_days, recomputed_at, capped); untouched days carry neither.

Input Schema

NameRequiredDescriptionDefault
endNoYYYY-MM-DD
limitNoMaximum data points to return (default 365, max 3000). The server rolls up rather than truncating.
startNoYYYY-MM-DD
metricNoMetric name, e.g. step_count, heart_rate, sleep_analysis. Omit for all.
filterDaysNoRestrict to days covered by matching logged events (health-events.json and health-events-agent.json): endDate ranges cover every day inclusive, point events cover their single day, negate:true keeps only days NOT covered. The answer states how many days matched. Example: HRV on night-shift blocks vs days off.
aggregationNo
granularityNoRoll daily values up before returning them. 'auto' (default) picks the finest granularity that fits the response budget, so a multi-year range returns monthly points instead of thousands of daily ones.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv1.8.0
    • changedInput schema / properties / filterDays / description
      Previous value: -"Restrict to days covered by matching logged events (health-events.json): endDate ranges cover every day inclusive, point events cover their single day, negate:true keeps only days NOT covered. The answer states how many days matched. Example: HRV on night-shift blocks vs days off."New value: +"Restrict to days covered by matching logged events (health-events.json and health-events-agent.json): endDate ranges cover every day inclusive, point events cover their single day, negate:true keeps only days NOT covered. The answer states how many days matched. Example: HRV on night-shift blocks vs days off."
  2. Changed1 schema field changedv1.4.0
    • addedInput schema / properties / filterDays
      Added value: +{
      +  "description": "Restrict to days covered by matching logged events (health-events.json): endDate ranges cover every day inclusive, point events cover their single day, negate:true keeps only days NOT covered. The answer states how many days matched. Example: HRV on night-shift blocks vs days off.",
      +  "properties": {
      +    "eventTag": {
      +      "description": "Event tag to match, e.g. nights.",
      +      "type": "string"
      +    },
      +    "eventType": {
      +      "description": "Event type to match, e.g. shift, medication, travel.",
      +      "type": "string"
      +    },
      +    "negate": {
      +      "description": "Keep only days NOT covered by matching events.",
      +      "type": "boolean"
      +    }
      +  },
      +  "type": "object"
      +}
  3. Changed2 schema fields changedv1.2.2
    • addedInput schema / properties / granularity
      Added value: +{
      +  "description": "Roll daily values up before returning them. 'auto' (default) picks the finest granularity that fits the response budget, so a multi-year range returns monthly points instead of thousands of daily ones.",
      +  "enum": [
      +    "auto",
      +    "day",
      +    "week",
      +    "month",
      +    "quarter",
      +    "year"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / limit
      Added value: +{
      +  "description": "Maximum data points to return (default 365, max 3000). The server rolls up rather than truncating.",
      +  "type": "integer"
      +}
  4. First observedv1.0.0

TDQS

A3.9/5.0
Behavior5/5

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

Annotations only declare read-only/idempotent; the description adds substantial behavior the agent could not infer: coverage block with firstDate/lastDate/days, aggregate always computed over the full range even when points are rolled up, segmentBoundaries for single-metric answers, readings capped at 150 with readingsOmitted, and recomputed_at/recompute blocks for backfilled days.

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

Conciseness3/5

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

Purpose is front-loaded in the first two sentences, which is good. But the remainder is a dense run-on covering coverage, aggregations, segmentBoundaries, blood-pressure readings, recompute blocks in one paragraph — the readings/recompute detail could be tightened or split so the calling-critical facts stand out.

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

Completeness4/5

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

With no output schema, the description correctly carries the return-shape burden and does so thoroughly for a 7-param tool with a nested filterDays object. It stops short of describing empty-range behavior or what happens when filterDays matches zero days, which a data-retrieval tool's consumers would want.

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 high (86%), so the baseline is 3; the description earns above that by clarifying that aggregate is computed over the full range regardless of rollup, and that multi-year ranges degrade to monthly points rather than truncating. It adds little on filterDays or metric naming beyond the schema, but the rollup/aggregate semantics are genuinely new.

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

Purpose4/5

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

First sentence states a specific verb and resource — get metric values over an optional date range with an aggregate — and the second sentence positions it as 'the core data-retrieval tool'. It never names or contrasts with plausible siblings such as query_health_data, get_trends, get_intraday, or get_structured_export, so an agent can't distinguish them from this text alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

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

Usage is only implied: 'check coverage before trusting a long window' and 'use single-metric to get segmentBoundaries' are hints rather than explicit when/when-not rules. No alternative tool is named, and there is no statement about when to prefer query_health_data or compare_periods over this.

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