DuckDB sandbox: first metric in five minutes
Stand up a DuckDB sandbox, publish one certified metric, and query it from the console and MCP without a cloud warehouse.
The datahashi team3 min read

You do not need Snowflake or BigQuery to prove a semantic layer. A DuckDB sandbox is enough to connect a local warehouse, author one metric in YAML, publish an immutable model, and get the same number from the console, REST, and MCP. This walkthrough is the five-minute path from empty sandbox to a metric an agent can call.
datahashi stays thin: transforms and files live where you put them; the model maps tables to entities, dimensions, measures, and metrics. Compilation targets DuckDB the same way it targets cloud warehouses. Consumers keep one request shape.
Minute 1: connect DuckDB
Create or open a DuckDB database file that holds a small fact table you trust for demos. Point datahashi at that connection with a read path only. Nothing is copied out into a second store; the layer reads with the access you granted.
Keep production secrets out of the sandbox. A local file or a disposable copy of a few thousand orders is enough. The goal is validating the metric contract, not load-testing warehouse brands.
Minutes 2-3: author a minimal model
Start with one entity, one measure, one metric, and one time dimension. Illustrative shape:
entities:
- name: Order
table: orders
primary_key: id
measures:
- name: revenue
expr: amount
agg: sum
- name: order_count
expr: id
agg: count
dimensions:
- name: ordered_at
expr: ordered_at
type: time
- name: region
expr: region
type: categorical
metrics:
- name: revenue
expr: Order.revenue
- name: orders
expr: Order.order_count
Validate in the app before you publish. Catch wrong grain and missing joins here, not in a wrong agent answer later.
Minute 4: publish and query once as a human
Publish the YAML as an immutable model version. From the console, run a semantic query: metric revenue, dimension region, a short date filter. Confirm the number matches a hand-written DuckDB check for the same filter. That same-number test is the whole point of the sandbox.
REST uses the same shape. You are not learning a DuckDB dialect for APIs; you are learning the semantic triad: metrics, dimensions, filters.
Minute 5: hand the same metric to MCP
Connect an MCP client with a governed credential for the sandbox. The tools are deliberately small:
list_catalogshould showrevenueandordersdescribe_metricshould show grain and allowed dimensionsrun_semantic_queryshould return the same regional revenue the console showed
No SQL in. No SQL out. If the agent invents a join story, refuse it and expand the catalog instead. Prefer a new published metric over a raw query tool “just for demos.”
What you proved
In five minutes you proved portability of meaning, not of files. When you later point the same YAML patterns at Postgres or BigQuery, consumers keep calling run_semantic_query with the same metric names. The DuckDB sandbox was a rehearsal for governance, not a throwaway toy.
Metering still applies in a sandbox: you can see which principal ran which semantic request. Rollups have shipped for repeated questions. They are not a p99 latency target. Correct definitions still come first.
Habits that keep the sandbox useful
Pin a published version for agent demos so prompt experiments do not chase a moving model. Keep sample data boring and documented. Retire any temporary “explore everything” credential before you share the sandbox with a wider team.
A DuckDB sandbox is how you ship your first certified metric quickly. datahashi makes that metric callable by humans and agents through one thin contract, without waiting on a cloud warehouse ticket.
Product notes
An occasional email when we ship something or write something worth reading.