Refresh and freshness

Re-fetch data, check how stale it is, and explore live values.

Contents

  1. Tools
  2. check_freshness
  3. refresh
  4. explore_dashboard

Tools

Reading cached rows with get_widget_data costs nothing and is usually enough. Reach for a refresh only when the user needs data fresher than the last run.

Tool What it does
check_freshness Check freshness Read-only
refresh Refresh Destructive write
explore_dashboard Explore dashboard Additive write

check_freshness

Read-only

Answer "how stale is this actually?" for a dashboard (dashboardId) or one widget (widgetId) — a cheap read that runs nothing and publishes nothing. A SUCCESSFUL REFRESH DOES NOT MEAN RECENT DATA, and this is where both facts sit side by side. Per widget: lastRefreshedAt (when the fetch last ran) beside latestPeriod (the newest period in the cached rows; latestPeriodSource 'fetched' means it was read from the raw fetch because the transform dropped the column), and windowPinned — true when the argumentTemplate hard-codes a literal END bound or a literal period (year: 2025), with pinnedBy naming the stage, argument and role. A widget refreshed 5 minutes ago with latestPeriod 2020 and end_year 2020 will never become current: unpin the bound (update_widget's pipelineArguments removeArguments, or a relative parameter default) and refresh. A literal single period may be an intentional snapshot, so confirm before changing it. selection is the period the fetch REQUESTS (fixed, parameter, rolling, open or unknown, plus selectedPeriod) — never coverage; compare it with latestPeriod. dataState says whether rows are cached: populated, empty (zero rows is a real result), never_materialized, missing or no_pipeline; the summary counts dataUnavailable and latestPeriodUnknown charts, and neither is fresh. The response also carries the scheduled-refresh cadence (enabled, interval, paused/suspended): a schedule keeps the FETCH current, never a pinned WINDOW. Use it before promising a dashboard is up to date, to sweep for literal date bounds, and to diagnose a frozen chart. latestPeriod is best-effort and absent when no field reads as time — an absent value is never evidence of freshness. Any dashboard role may read it.

refresh

Destructive write · Reaches outside Vistazo

Re-fetch NOW and publish the result as the baseline every viewer sees, on your own MCP credentials at the dashboard's default parameter values. Synchronous. One scope per call: dashboardId (every widget), pipelineId or widgetId (one widget), or pipelineId + invocationId (one stage, re-stitched with the others' stored results). ok:true is NOT data: rowCount 0 with a warning means the fetch matched nothing, so check rowCount before reporting success. Nor is a refresh recent DATA: a literal end bound (end_year 2020) re-fetches the same window forever; latestPeriod shows the newest period, and for "make it current" call check_freshness first. skipped widgets were already refreshing (nothing billed; not an error). Declined with nothing fetched: no usable connection to a source (callerConnectionGaps — connect first), or usage (usageBlocked; retrying will not help). A removed widget's pipeline refuses. Requires edit access.

explore_dashboard

Additive write · Reaches outside Vistazo

Run every widget pipeline on a dashboard, or only the ones pipelineIds names, EPHEMERALLY under your own credentials, optionally overriding parameter values, and return the chart-ready rows in the result. Changes no data: the published baseline, the stored transform, and the parameter defaults are all untouched — this is the slice-and-dice lane, while refresh is the publish lane. params maps parameter keys to override values (same shapes as set_parameter's value, including relative date expressions); omitted keys use the dashboard defaults; unknown/invalid overrides are dropped and reported. Reuses each widget's cached transform only — a data-shape change surfaces as a per-widget stale_transform error meaning an editor must run a real refresh, and it files a broken-chart alert to the dashboard's editors (editorsTold). A selection the source has no data for (a year it does not cover, a cleared filter) is NOT a broken transform: that widget returns rows: [] with noData { reason: 'source_returned_no_rows', stages, emptyParameters } — pick another value rather than asking an editor. Cascading filters: pass changed (the keys this call moves relative to the view you are updating) and only the sources and charts reading them re-run; omit it for a full run. A sourced select whose source reads a changed key comes back with fresh options in parameterOptions (never persisted; stale: true means the source produced no rows and these are the last-good options), selections the fresh coverage no longer holds are removed and reported in pruned with a one-line note, and effectiveOverrides is the overrides the view actually ran with after pruning. Free: the run is recorded at zero cost, and capped at 300 data fetches per hour per MCP connection (per person in the app); past the cap every widget reports a rate_limited error. Any dashboard role of a member with a license may explore; a guest is refused.