Jacob Matson walks through a working data chat agent he built: MCP tools, an agentic loop, a tuned system prompt, hard-coded read-only guardrails, and telemetry. He demos it live against a real dataset, walks through the actual codebase and PR history, then shows the same backend re-platformed into a Slack bot.
Getting access to data
An agent needs four things: data, a credential to reach it (read-only, so nobody's waiting on a lock or worried about a stray delete), MCP tools so the model can actually query the database instead of just talking about it, and somewhere to run it. The demo, Data Chat Mini, is a Next.js app on Vercel, deployed with a single vercel --prod. The model is Gemini 3 Flash via OpenRouter, chosen for speed and cost, not leaderboard position. Figuring out what a user wants and writing narrow-scope SQL doesn't need a frontier reasoning model.
Making it behave
The loop is a plain while-loop with a hard cap of 40 iterations so a complex question can't spin forever. The system prompt tells the model to explore the schema instead of guessing, flags DuckDB-vs-Postgres quirks it was tripping on, and bans raw HTML output in favor of a strict JSON chart schema. That schema is enforced through mviz, a small charting library Jacob built because every LLM renders visualizations differently. Claude does it inline now, GPT does something else, and so on. The guardrails are read-only access only, a tool allow-list instead of the full MCP surface, and full query logging. Logging is off by default in the public demo but flipped on with a one-line change in production. Build trust by showing your work, not by telling people to trust it.
The live demo
Jacob queried an NBA dataset against the already-running app and got charts back in seconds, walked through the actual pull requests behind it, then showed the same backend running as a Slack bot (Quackbot, running on Kimi via Modal) he'd built ahead of the stream. Once the MCP/loop/prompt pattern exists, wiring it to a new chat surface is fast. Chat history and saved context stay local to the browser in this demo, so it never has to hold or be accountable for anyone's data. MotherDuck Guides is the recommended path when you want context shared across users in production. Full source for Data Chat Mini (and Quackbot, the Slack-bot version) is public at github.com/motherduckdb/labs/tree/main/projects/data-chat-mini.
Why SQL beats a semantic layer here
MotherDuck's own research found that adding a non-SQL query language like DAX, MDX, or similar semantic-layer DSLs makes an agent slower, more expensive, and less accurate than just writing SQL. There are decades of SQL in the training corpora these models learned from, and nowhere near as much in any given semantic-layer language. Jacob's take: a semantic layer is really just an extremely overfit context layer. MotherDuck Guides is where that business context, the joins and metric definitions, actually belongs, separate from execution and display.



