Open a clinical glucose chart in the browser
get_chart_htmlGenerates a color-coded glucose chart with target-range band, bolus markers, and stats, saves it as HTML, and opens it in the patient's browser.
Instructions
Generates a clinical-report-style glucose chart for a window (or several separate windows via ranges) — line trace colour-coded in-range/low/high, a shaded target-range band, a min/max spread band, bolus markers (hoverable in their own right for that bolus's units/ carbs/type, in addition to the aligned CGM reading's own tooltip), a header stat row (time in range, average glucose, time low, time high), a legend, and hover tooltips — saves it to a file, and opens it directly in the patient's default web browser. USE THIS instead of get_chart_series whenever the patient wants to SEE a chart.
Multi-day charts open with a Chronological/Overlay toggle: chronological is the usual continuous timeline; overlay re-plots every calendar day on a shared 0-24h axis (colour-coded per day, with a day legend) so days can be compared directly. Use ranges instead of start/end when the patient wants to compare specific, possibly non-contiguous dates together (e.g. "the 20th, 23rd and 30th") — every requested day gets equal width on the axis regardless of the calendar gap between them. The page also has a day-filter chip per day (in both views) so the patient can hide/show individual days themselves, with the header stats recalculating for whichever days are still visible — you never need a new call just to compare a subset of the days already shown.
The page also includes a "Day details" panel per calendar day (open by default for a single day, collapsed for multiple), with that day's full glucose control (average, GMI, TIR/low/high, std dev, CV), extremes (highest/lowest with times), best/worst hour, insulin (bolus units/count/ avg, basal units, bolus-basal split), bolus type counts, carbs, and the settings in force — the SAME figures get_diabetes_summary would return for that single day, computed by the identical aggregator so the two never disagree. Hiding a day's filter chip hides its detail panel too.
DATA RESOLUTION: a routine call (no resolution/maxPoints given) already plots every single CGM reading with NO smoothing for a typical window (a day, a week, a full month) — the point budget only kicks in on wider windows, where it keeps each bucket's true min/max so no low or high excursion is ever smoothed away, only the moment-to-moment trace between them is thinned. When a call DOES get thinned this way, the result includes a downsample object naming the raw vs plotted reading counts — treat that as an invitation to offer the patient a choice, not as data that has become unavailable: mention it in plain terms ("I plotted a lightly smoothed version of this wide a window — want the full-detail version instead? It may take a little longer to load") and, if they want more detail, re-call with resolution set to how much of the real data to use — 1 for every single reading, 2 for every other one, 3 for every third, and so on. Never decide this smoothing tradeoff silently on the patient's behalf beyond the routine default.
CRITICAL — how to respond after calling this, this is what keeps it fast: this tool does the displaying itself. Do NOT copy, re-type, rebuild, or paste the chart as an artifact/code block/canvas yourself — reproducing a large HTML page as your own output is exactly the slow path this tool exists to avoid, and it is unnecessary work since the browser window is already open by the time you respond. If the JSON result has openAttempted: true, just tell the patient in one short sentence that the chart has opened in their browser — do not describe or restate its contents in detail, do not emit any HTML/code, and treat the tool call as already complete. If openAttempted: false, the auto-open could not be launched from this machine (e.g. no recognised default-browser command) — tell the patient to open the file at the returned filePath themselves; only in that fallback case, or if embedHtml was explicitly requested, does the response also include a full html field. Do NOT reach for a quick/built-in "auto-visualize this data" shortcut either — this tool already produces the real chart.
Times are plain wall clock time (device-local), not UTC.
Returns: ranges (the resolved windows actually used), dayCount, unit, pointCount, bolusCount, filePath (where the page was saved), openAttempted (whether the browser launch was attempted without an immediate error), downsample (only present when the plotted points were thinned from the raw CGM readings — see DATA RESOLUTION above), and — only as a fallback — html.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | Required. Window end as an ISO 8601 timestamp, e.g. 2026-06-20T00:00:00.000Z — plain wall clock time, same caveat as start (the "Z" is a format artifact, not a UTC claim). Treated as inclusive and must be after start. All timestamps returned by this API are likewise plain wall clock time, unconverted. Omit this (and start) when passing `ranges` instead for several separate windows. | |
| lower | No | Optional. Low (hypo) boundary in the chosen unit; readings below it count as time-low. Omit to use the server default (OMNI_LOWER). Pass only to override for this one call, e.g. to ask about time under a different threshold. | |
| start | No | Required. Window start as an ISO 8601 timestamp, e.g. 2026-06-19T00:00:00.000Z. IMPORTANT: despite the trailing "Z", this is plain WALL CLOCK time, not true UTC — Glooko records only the literal date/time the patient's device showed, with no timezone attached. Use the patient's own wall-clock digits directly (no conversion): resolve "yesterday" or "last 3 weeks" straight into the matching wall-clock date and time. Treated as inclusive. Omit this (and end) when passing `ranges` instead for several separate windows. | |
| units | No | Optional. Glucose unit for this call. Omit to use the unit configured on the server (OMNI_UNITS). One of: "mmol" (mmol/L) or "mgdl" (mg/dL). Pass only to override the configured unit for this one call. | |
| upper | No | Optional. High (hyper) boundary in the chosen unit; readings above it count as time-high. Omit to use the server default (OMNI_UPPER). Pass only to override for this one call. | |
| ranges | No | Optional. Use this INSTEAD OF start/end to show several separate, possibly non-contiguous windows on ONE chart -- e.g. "the 20th, 23rd and 30th of June" is ranges: [{start:"2026-06-20T00:00:00.000Z", end:"2026-06-21T00:00:00.000Z"}, {start:"2026-06-23T00:00:00.000Z", end:"2026-06-24T00:00:00.000Z"}, {start:"2026-06-30T00:00:00.000Z", end:"2026-07-01T00:00:00.000Z"}] (each entry is that day's own midnight to the next day's midnight). Ranges can be single days or multi-day spans, do not need to be contiguous, and do not need to be given in order -- the chart always lays them out chronologically and gives every calendar day equal width on the axis, so a 10-day gap between two selected dates does not waste space. The combined span across all ranges is still capped like a normal window. The chart itself also lets the viewer hide/show individual days afterward without a new call. | |
| embedHtml | No | Optional (default: false). Force the full HTML page to also be included in the response even when the browser auto-open succeeded. Leave this false in normal use — including it costs exactly the slow, large-response-body path this tool is designed to avoid. Only set true if the patient explicitly asks to see the raw page/markup. | |
| maxPoints | No | Optional, advanced. A precise total-point-budget alternative to `resolution` (20-50000), shared across all ranges when `ranges` is used; ignored if `resolution` is also given. Omit both in normal use: the routine default is up to 12000 points, which covers a full month at native cadence with no downsampling -- see DATA RESOLUTION above. | |
| resolution | No | Optional. The simple, patient-facing way to control chart detail: a plain divisor for how much of the real CGM data to plot, applied to each range independently. 1 = ALL readings (full native ~5-minute resolution, no downsampling at all, however wide the window -- use this whenever the patient wants full detail and is fine with a larger/slower-to-load file). 2 = every 2nd reading (roughly half), 3 = every 3rd (roughly a third), and so on. Omit this in normal use -- see DATA RESOLUTION above for when to offer it as a choice. Overrides `maxPoints` when both are given. |