Ask in plain words
The agent reads your schema, writes dialect-correct SQL — T-SQL, PostgreSQL or KQL — and streams every tool call into the chat as it runs. Nothing is hidden behind a spinner.
SELECT date_trunc('month', order_date) AS month, SUM(total) AS revenue FROM orders WHERE order_date >= '2026-01-01' GROUP BY 1 ORDER BY 1;
SELECT date_trunc('month', order_date) … GROUP BY 1UPDATE orders SET total = 0;Same call, same database, fresh rows. The agent isn't in this loop at all.
How it works
The agent reads your schema, writes dialect-correct SQL — T-SQL, PostgreSQL or KQL — and streams every tool call into the chat as it runs. Nothing is hidden behind a spinner.
ReadOnlyGuard parses the statement first. One SELECT or WITH, no batching, no SELECT INTO, nothing on the denylist — or it's refused before a connection is ever opened.
The widget keeps the exact call that produced it. Refresh replays that call against your database — no model, no re-interpretation, the same numbers your SQL would give you.
Inside a widget
{
"tool": "run_readonly_query_json",
"data_source": "northwind",
"sql": "SELECT date_trunc('month', order_date) AS month, SUM(total) AS revenue FROM orders WHERE order_date >= '2026-01-01' GROUP BY 1 ORDER BY 1"
}Result rows are never copied to our servers. The widget knows how to get its data, not the data itself.
What's inside
run_readonly_query_jsonEvery tool call streams into the chat as it runs. The SQL is dialect-correct T-SQL, PostgreSQL or KQL — yours to read, every time.
SourceCallsJsonA pinned widget stores the call that produced it, verbatim — never the rows.
ReadOnlyGuardOne SELECT or WITH, or it's refused before a connection is opened.
ScheduledRefreshServiceSet a cadence; the server replays each widget on time and the dashboard opens on fresh rows.
get_table_relationshipsTables, views and foreign keys as a draggable graph — the map the agent walks.
SchemaDiffDrop csv, Excel or JSON into a bucket and ask; each becomes a typed SQLite table. Replace a file and every widget built on it is re-checked, then refreshed.
anthropic · openai · geminiStart on Klyrova credit, or bring your own key and pick from your provider's live model list. Keys never leave the server.
mssql · postgres · kql · sqliteWarehouses, lakehouse endpoints and KQL databases sit beside your Postgres and your own uploaded files — every connection is read-only by contract.
Security
The guard parses every statement before your database ever sees it. Anything that isn't a single read is refused — no exceptions, no flags to flip. Your credentials are encrypted, bound to your account, and never shown again.
UPDATE orders SET total = 0;
✗ rejected — not a single read-only statement
SELECT 1; DROP TABLE orders;
✗ rejected — batching is not allowed
SELECT month, SUM(total) FROM orders GROUP BY month;
✓ 8 rows · 96 ms