MCP for warehouse data without raw table access
How agents can query governed metrics through MCP without seeing raw warehouse tables or writing SQL.
The datahashi team3 min read

Giving an agent a warehouse connection is easy. Governing what it can mean by “revenue” is harder. Raw table access invites invented joins, leaked columns, and SQL that almost matches last quarter’s dashboard.
datahashi approaches MCP the other way around. Agents do not get a SQL sandbox. They get the same metric contract humans use: YAML definitions, immutable publish, and one request shape shared by REST, the console, and MCP. The MCP tools are deliberately small. Six of them: list_catalog, describe_metric, run_semantic_query, drill_down, refine_semantic_query, and list_dimension_values. No SQL in. No SQL out.
Why raw tables are the wrong agent interface
Warehouses are optimized for storage and compute, not for conversational semantics. Table names drift. Columns mean different things in different domains. A join that is safe in one mart is explosive in another. An agent with SELECT privilege will improvise, and improvisation is how you get three conflicting answers to one business question.
Even read-only access is not enough. Read-only still allows fishing through schemas, reconstructing sensitive attributes, and producing numbers that were never reviewed. Governance needs a higher-level object: the metric.
What governed MCP looks like
With datahashi, an agent first lists the catalog to see published metrics and dimensions. It describes a metric to learn definition, grain, and allowed slices. It runs a semantic query with the same shape a service would send over REST or a person would use in the console.
That sameness matters. If MCP accepted freeform SQL while the console used governed metrics, you would recreate the two-source-of-truth problem inside your agent stack. Thin layer means one definition path, not a special agent dialect.
Humans and agents share product truth
The product promise is simple: the same metric for humans and agents, without hallucinated SQL. YAML is reviewed and published as an immutable version. Consumers call that version. Metering exists so you can observe usage. Rollups have shipped for repeated questions. They are not a p99 latency target. Agents should be given correct definitions, not a speed promise.
What you gain by withholding raw access
- Stable meaning. Metrics change through review and publish, not through prompt cleverness.
- Smaller blast radius. Agents cannot wander into every staging table.
- Comparable outputs. A Slack answer and a dashboard tile can cite the same metric version.
- Clearer audits. You inspect semantic queries against a catalog, not arbitrary SQL strings.
Withholding raw tables is not about distrusting models in the abstract. It is about putting business meaning in a contract the model can call but not rewrite.
Fit with the rest of the stack
Keep the warehouse thick: facts, history, row-level policy, heavy transforms. Keep datahashi thin: metric definitions and a governed query surface. MCP sits on that surface. It is not a second warehouse API and not a pass-through to information_schema.
If your agent platform needs context, feed it metric descriptions and allowed dimensions from describe_metric, not DDL dumps. If it needs numbers, call run_semantic_query. If it needs to discover what exists, call list_catalog.
Ship the constraint on purpose
Teams sometimes add “just one” raw query tool for edge cases. That edge case becomes the default path under deadline pressure. Prefer expanding the metric catalog over opening table access. When a new question appears often, publish a metric for it.
MCP for warehouse data does not require exposing warehouse tables. It requires exposing governed metrics. datahashi is built for that narrower, safer interface.
Product notes
An occasional email when we ship something or write something worth reading.