Drafts first
An agent creates and edits visualizations and dashboards over MCP, and everything it writes is a draft. A person opens the draft in the application, checks it and releases it.
SQL dashboards
A dashboard here is built from the SQL pipelines you already review: charts, tables and KPI cards bound to pinned pipeline versions, with filters a viewer can change. It runs on your own server, an agent drafts it, a person releases it, and your product can show it to customers without the key ever reaching their browser.
How it is built
A dashboard pins exact pipeline versions as its sources. Every source must pass the read-only rule, checked at save, at release and again before each refresh, so a pipeline with a write node is never a source.
A Plotly chart, a table or a KPI card, bound to named inputs rather than to one pipeline. The same release can appear on several dashboards. Bar, line and scatter, pie, histogram, box and heatmap are supported, with three 3D trace types loaded only when a dashboard uses one.
It maps source results onto each visualization's inputs, places them on a 12-column grid, groups them, and adds parameter controls from one pinned parameter set and the refresh actions a viewer presses.
{
"display_name": "Revenue overview",
"parameter_set": { "name": "finance/parameters/reporting_period", "version": 1 },
"sources": [
{ "name": "revenue_source",
"pipeline": { "name": "finance/pipelines/monthly_revenue", "version": 7 },
"parameters": { "year": { "parameter": "year" }, "currency": { "value": "USD" } } }
],
"visualizations": [
{ "name": "revenue_chart", "type": "visualization",
"visualization": { "name": "finance/visualizations/monthly_revenue", "version": 3 },
"inputs": { "revenue": { "source": "revenue_source" } } }
],
"layout": { "grid": [ { "name": "revenue_chart", "x": 0, "y": 0, "w": 6, "h": 4 } ], "columns": 12 }
}
An excerpt of the dashboard document from the contract: every reference names an exact version.
Review and run
An agent creates and edits visualizations and dashboards over MCP, and everything it writes is a draft. A person opens the draft in the application, checks it and releases it.
A visualization declares test cases, and it releases only with a passing run for its exact content plus the server's own mechanical check. A change after the run makes the evidence stale.
A released dashboard requires released dependencies, and every reference is an exact version. Editing a chart opens a new draft; the board that pinned the old one keeps it.
Configured refresh actions run the sources and stream each chart's result as it arrives. An action can run when the board opens, from a refresh button or from a bound filter control; changing an unbound filter marks charts stale. Two charts reading the same source and values share one run, and a viewer can abort a refresh.
Every admitted refresh is recorded and closed however it ends, with one audit row per refresh. Its source runs appear among the person's executions.
Each source's rows are counted against a byte cap, a refresh reserves its execution slots all at once or waits, and a full instance answers with a retry time instead of queueing without limit.
Embedding
Your backend holds a dashboard key and relays the four runtime routes: the configuration, the
parameter evaluation, the refresh stream and the abort. The browser talks only to your backend: the proxy
attaches the key server-side and strips cookies and CSRF headers. The source includes a dependency-free
reference proxy and a test that fails if a proxy buffers the stream or forwards a cookie.
Your backend decides who your user is: the reference proxy is an example you place behind your own sign-in. Every viewer behind one key shares that key's identity and budget, so the key does not separate one customer's data from another's. If a viewer may only see their own rows, your backend checks the values it forwards, and the source pipeline filters on them.
Current limits
Try it
Start the server with the tutorial and release a pipeline an agent authored and you reviewed. Ask your agent for a visualization over its result and a dashboard that pins both, then review the draft in the application's Dashboards workspace and release it. For filters, define a parameter set first; for an API instead of a chart, see published endpoints.
Asked before
Yes, through your backend. Your application holds a dashboard key and relays the four runtime routes, so the key never reaches the browser; a dependency-free reference proxy ships with the source. Your backend signs your own user in first. Every viewer behind one key shares that key's identity and budget, so which customer's values a viewer may submit is decided in your backend, not by the key. The contract is docs/dashboards.md §6.5.
No. A schedule runs a pipeline. Configured refresh actions run its pinned sources: an action can run when the dashboard opens, from a button or from a bound filter control. Changing an unbound filter marks charts stale. A refresh streams each chart's result as it arrives. No MCP tool refreshes a dashboard. The contracts are docs/dashboards.md §5.5 and docs/dashboards.md §5.8.
An AI agent authors visualizations and dashboards over MCP, and everything it writes lands as a draft. A person reviews it in the application and releases it; a visualization releases only with passing test evidence for its exact content. There is no drag-and-drop editor: the layout is a 12-column grid in the dashboard document (docs/dashboards.md §2.2). The contract is docs/dashboards.md §3.1.