Open sourceApache 2.0

Semantic layer

A semantic layer for AI agents

Last updated

Why agents answer data questions more reliably through named metrics than through raw SQL, what to check before you connect one to your data, and how the main semantic layers expose their models to agents over MCP.

Definition

What is a semantic layer for AI agents?

It is the same semantic layer your dashboards use, exposed to an agent as tools. Instead of reading table schemas and writing SQL, the agent lists the metrics and dimensions you defined, reads their descriptions, and asks for one by name: revenue by country, by month. The layer writes the SQL, applies access rules and returns rows.

Most agents connect through MCP, the Model Context Protocol. What matters is what the tools allow: query by name only, or also run any SQL; tenant set by the server, or chosen by the agent; bounded results, or whatever the agent asks for.

The problem

Why raw text-to-SQL is fragile for agents

Give an agent database credentials and a list of tables, and every question becomes a guess. Which table holds orders? Does revenue include refunds? Which join reaches the customer’s country? A human analyst learns the answers once. An agent works them out again in every conversation, and two conversations can reach different answers to the same question.

In a product, the stakes are higher. If the agent serves your customers, every query must be limited to one customer’s rows, and a prompt should never be able to change which customer that is. With raw SQL, that rule lives in the prompt. With a semantic layer, it lives in code the agent cannot edit.

What to look for

Five things to check before you connect an agent

What to check in a semantic layer for AI agents
CheckWhy it mattersWhat good looks like
Named metrics with descriptionsThe agent picks “revenue” from a list instead of guessing which column and filter make revenue.Labels and descriptions on every dimension and measure, returned by a schema tool.
Query tools, not a SQL consoleAn agent that can run any SELECT can join the wrong tables or read columns you never meant to share.Tools that take metric and dimension names. If a raw SQL tool exists, you can leave it off.
Tenant scope that fails closedIn a multi-tenant product, one missing WHERE clause shows a customer someone else’s data.The tenant comes from the server or the caller’s credential, never from tool arguments, and an unscoped query fails.
Bounded queriesAgents retry and explore. Unbounded result sets cost money and flood the context window.Default and maximum row limits, and caps on dimensions and measures per call.
One definition for every consumerIf the agent’s revenue differs from the dashboard’s, people stop trusting both.The same model serves dashboards, APIs and agents.

An example

Named metrics as MCP tools

In hypequery, a dataset is a TypeScript or Python file in your application repo. The same definition serves your API and React hooks, and @hypequery/mcp turns it into four tools. Nothing outside the published datasets is reachable.

analytics/datasets.ts
// analytics/datasets.ts
import { dataset, dimension, measure } from '@hypequery/datasets';

export const Orders = dataset('orders', {
  source: 'orders',
  tenantKey: 'tenant_id',
  timeKey: 'created_at',
  description: 'One row per order.',
  dimensions: {
    country: dimension.string({ label: 'Country' }),
    status: dimension.string({
      label: 'Status',
      description: 'completed, refunded or pending',
    }),
    createdAt: dimension.timestamp({ column: 'created_at' }),
  },
  measures: {
    revenue: measure.sum('amount', { label: 'Revenue' }),
    orders: measure.count('id', { label: 'Orders' }),
  },
});

export const revenue = Orders.metric('revenue', { measure: 'revenue' });
an agent tool call
// The agent calls a tool; it never writes SQL.
// tools: list_datasets, get_dataset_schema,
//        query_metric, query_dataset
{
  "name": "query_metric",
  "arguments": {
    "dataset": "orders",
    "metric": "revenue",
    "dimensions": ["country"],
    "grain": "month",
    "limit": 12
  }
}

// The server adds the tenant from its own config or the
// caller's verified credential. A tenant filter sent by
// the agent is rejected, and a tenant-keyed dataset
// with no tenant configured refuses to start.

No SQL tool

The tools are list_datasets, get_dataset_schema, query_metric and query_dataset. Generated SQL can be returned for debugging, but the agent cannot send its own.

Tenant fails closed

A stdio server serves one tenant, set when it starts. Over HTTP, each caller’s tenant comes from their verified credential. A tenant-keyed dataset with no trusted tenant refuses to start.

Bounded by default

Calls return 100 rows unless they ask for more, up to a ceiling you set (at most 10,000), with at most 50 dimensions or measures per call. Queries run within one dataset; cross-dataset joins are not exposed to agents yet.

Options

How semantic layers expose metrics to agents

Checked against each vendor’s own docs, repository or pricing page on November 13, 2026. “Not covered” means the sources we read did not say, not that the feature is missing.

Semantic layers and their MCP servers, checked November 13, 2026
How agents connectToolsRaw SQLAccess scopingDatabasesLicence or plan
hypequery@hypequery/mcp (TypeScript) or the Python package: stdio, or HTTP with your app’s authlist_datasets, get_dataset_schema, query_metric, query_datasetNoneTenant from server config or the caller’s verified credential; tenant filters from the agent are rejectedClickHouse onlyApache 2.0
CubeHosted MCP server in Cube Cloud30 tools, including tools that edit the data modelNot covered in sources checkedViewer role or higher; tools shown by role; tokens can be limited to named toolsMany sources, including ClickHouseAll Cube Cloud plans
dbt Semantic Layerdbt MCP serverlist_metrics, get_dimensions, query_metrics and other Semantic Layer tools, plus dbt CLI, Discovery and Admin API toolsYes: execute_sql, text_to_sql and the CLI show tool; each can be switched off or left out of an allowlistPer-tool enable and disable settingsSnowflake, BigQuery, Databricks, Redshift, Postgres, Trino (no ClickHouse)Server Apache 2.0; Semantic Layer needs a paid dbt plan
AtScaleRemote MCP serverlist_models, explore_columns, run_query and othersTools are read-only; every request is checked against the modelChecked against the AtScale modelSnowflake, Databricks, BigQuery, Redshift, PostgreSQL and more (no ClickHouse)Commercial
Snowflake semantic viewsSnowflake-managed MCP serverCortex Analyst over semantic views, Cortex Search, Cortex Agents, UDFs and proceduresOptional SYSTEM_EXECUTE_SQL tool, read-only by default; Snowflake advises keeping it off a governed agent’s serverSnowflake privileges per tool; Snowflake OAuth or an external IdPSnowflakeCommercial
Boring Semantic LayerBuilt-in MCP server (MCPSemanticModel)list_models, get_model, get_time_range, query_model, compare_periodsNone listedNot covered in its docsIbis backends such as DuckDB, Snowflake, BigQuery and PostgreSQLMIT
GoodDataMCP server30+ toolsNot covered in sources checkedNot covered in sources checked23 sources, including ClickHouseEnterprise plan only

For the models themselves, see the guides to dbt MetricFlow, Snowflake semantic views and Databricks metric views, and open-source semantic layer tools compared.

An honest answer

When another option fits better

  • Your data is in Snowflake and the agent serves internal users: Snowflake semantic views and Cortex Analyst keep the model, the data and the permissions in one place.
  • Your metrics already live in dbt on a supported warehouse: the dbt MCP server reuses them, with the Semantic Layer tools on a paid dbt plan. For a governed agent, switch off its SQL and CLI tools.
  • One model must serve many databases and BI tools as well as agents: Cube covers more sources and more client APIs than a library inside one app.

Use hypequery when the data is in ClickHouse and the agent is part of your product: the metric definitions, tenant rules and MCP server ship with the application that already knows who each user is.

Questions

Semantic layer for AI agents FAQ

Why do AI agents need a semantic layer?

Without one, an agent writes SQL from table and column names. It has to guess which tables to join, how a metric like revenue is calculated, and which rows a user may see. A semantic layer gives it named metrics and dimensions with descriptions, so it asks for revenue by country and the layer writes the SQL the same way every time.

Is text-to-SQL enough for an analytics agent?

For an analyst exploring a warehouse they already have access to, often yes. For an agent inside a product, it is risky: the agent can read any table its credentials reach, compute a metric differently from your dashboard, or leave out a tenant filter. Query tools over named metrics remove those choices from the agent.

What is an MCP server for a semantic layer?

MCP, the Model Context Protocol, is how agents such as Claude, Cursor and Codex discover and call tools. A semantic layer’s MCP server turns its model into tools: one to list datasets or metrics, one to describe them, and one or more to query them by name.

How do I stop an agent from seeing another customer’s data?

Take the tenant out of the agent’s hands. The server should get the tenant from its own configuration or from the caller’s verified credential, apply it to every query, and fail when it is missing. In hypequery, a dataset with a tenant key cannot be served over MCP without a trusted tenant, and tenant filters sent by the agent are rejected.

Which semantic layers have an MCP server?

Of the tools on this page: hypequery (@hypequery/mcp and the Python package), Cube (a hosted MCP server on all Cube Cloud plans), dbt (the dbt MCP server), AtScale (a remote MCP server with read-only tools), Snowflake (a managed MCP server that can call Cortex Analyst over semantic views), Boring Semantic Layer (built in) and GoodData (on its Enterprise plan). Malloy Publisher and Wren AI, covered in the open-source tools guide, also serve MCP.

Sources

Vendor pages used for this page, all read on November 13, 2026.

hypequery
github.com/hypequery/hypequery/tree/main/packages/mcp-server
hypequery.com/docs/mcp/safety
hypequery.com/docs/mcp/tools
Cube
github.com/cube-js/cube/blob/master/docs-mintlify/docs/integrations/mcp-server.mdx
github.com/cube-js/cube/blob/master/docs-mintlify/admin/connect-to-data/data-sources/clickhouse.mdx
dbt Labs
github.com/dbt-labs/dbt-mcp/blob/main/README.md
docs.getdbt.com/docs/use-dbt-semantic-layer/sl-faqs
AtScale
www.atscale.com/use-cases/semantic-context-ai-mcp/
www.atscale.com/integrations/
Snowflake
docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp
docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst
Boring Semantic Layer
github.com/boringdata/boring-semantic-layer
github.com/boringdata/boring-semantic-layer/blob/main/docs/md/doc/query-agent-mcp.md
GoodData
www.gooddata.ai/pricing/
www.gooddata.ai/docs/cloud/connect-data/

Next step

Define a semantic layer in your own codebase

hypequery datasets are TypeScript or Python files: dimensions, measures, joins and a tenant key, served to your API, React hooks and AI agents over MCP. Open source, for ClickHouse.

Get early access to hypequery cloud.

Cloud hosts the same model you run in your backend, with a managed API and MCP server, versions, and rollback. We're letting teams in a few at a time. Join the waitlist and we'll reach out when your project can go live.

How do you want to build your analytics layer? (Optional)
What features do you most need? (Optional)

Pick as many as you like.

Only your email is required. All other questions are optional.