Semantic layer MCP tools
Contents
The PostHog MCP server is how agents work with the semantic layer. This page is the reference for the semantic layer's tools – they're also listed under Data catalog in the general MCP tools list, alongside every other PostHog tool.
This works in any MCP client – Claude Code, Claude Desktop, Cursor, Codex, Windsurf, VS Code, and others. Install with the AI wizard (npx @posthog/wizard mcp add) – see the MCP server docs for full setup instructions.
Catalog-first routing
With the semantic layer enabled, the MCP server changes how agents answer metric questions. The agent checks the catalog first when a question asks for:
- A count, sum, or amount over time
- A rate, average, or percentile
- A cost per unit
- A conversion between two events
- A breakdown, ranking, or comparison of any of these
That covers anything your product records, from revenue to sessions, tickets, or tool calls, not only named KPIs. One-off exploration and debugging skip the catalog. For one of these questions, the agent:
- Calls
metric-listto read the catalog, thenmetric-describeto inspect a candidate's definition - If exactly one
approved, non-drifted match exists, runs it withdata-catalog-metric-runand opens the answer with "🛡️ From your data catalog", naming who approved the definition and when - If several materially different approved matches exist, asks you which one and stops
- If the match is only
proposed, uses it when its definition fits the question, opens the answer with "📝 Proposed definition in your data catalog" and a link to review it, and says why it used it - Otherwise writes the query itself, tells you the number is a one-off calculation and not a saved definition, and offers to save a reusable measure as a proposed metric
This routing takes precedence over the agent's generic query-writing behavior, typed query tools, and any skill's query recipe. The effect: governed definitions win by default, and you always know when a number is a one-off derivation instead.
How confirmations work
Every promoting or vetoing action ships as a pair of tools. The -prepare half validates the arguments and returns a signed confirmation_hash along with a message to show you. You reply with the literal word "confirm". The -execute half verifies that hash and your typed word, then performs the action.
Your agent makes both calls – you read the message and type "confirm". The split is what keeps the moment of promotion a separate human step that an agent can't autocomplete. In the tables below, these pairs are listed as -prepare / -execute.
Metric tools
| Tool | What it does | Confirmation | Scopes |
|---|---|---|---|
metric-list | Lists the catalog's metrics a page at a time, with each one's name, description, status, drift state, unit, and definition kind. Leaves out metrics that read a table you can't access. | – | data_catalog:read |
metric-describe | Returns one metric's full definition, provenance, referenced tables, status, and drift state, addressed by name. | – | data_catalog:read |
data-catalog-metric-run | Runs a governed metric. Executable metrics return results, the compiled query, and a posthog_url deep link; markdown metrics return calculation steps in instructions. Accepts date_from/date_to/interval overrides (rejected for HogQLQuery metrics) and a refresh cache option. | – | data_catalog:read, query:read |
data-catalog-metric-create | Creates a metric, which lands proposed. The definition is an executable query or a MarkdownDefinition. If a live metric already holds the name, the call fails with a 409 metric_name_taken error and that metric stays unchanged. The agent asks you before calling again with overwrite: true, which writes the new fields over the existing metric. Overwriting an approved metric's definition, description, or unit resets it to proposed. | – | data_catalog:write |
data-catalog-metric-update | Updates a metric's fields, including renaming it via new_name (which frees the old name and breaks references to it). Editing an approved metric's definition, name, description, or unit resets it to proposed. | – | data_catalog:write |
data-catalog-metrics-refresh-from-insight-create | Re-snapshots the linked insight's current query into the metric to clear drift. If the snapshot changes an approved metric's definition, the metric resets to proposed. Requires the metric to have a source_insight_short_id. | – | data_catalog:write, insight:read |
data-catalog-metric-approve-prepare / -execute | Blesses a metric as canonical. Blocked while the metric is drifted from its source insight – refresh or unlink it first. | Typed "confirm" | data_catalog_approval:write, data_catalog:read |
data-catalog-metric-delete-prepare / -execute | Deletes a metric and frees its name, so anything that referenced the old name stops resolving. Agents delete only a metric that shouldn't exist, and update one that's wrong, stale, or badly named instead. | Typed "confirm" | data_catalog:write |
The SQL reference covers reading the same catalog with execute-sql over system.information_schema.metrics.
Certification tools
| Tool | What it does | Confirmation | Scopes |
|---|---|---|---|
data-catalog-certification-propose | Proposes a trust mark on a warehouse table or view. Address the target by ID or by name – an ambiguous name returns the candidate IDs to pick from. Pass proposed_status (certified by default, or deprecated) to say whether the proposal asks to trust the source or to avoid it. | – | data_catalog:write |
data-catalog-certification-certify-prepare / -execute | Marks a table or view as certified (prefer this source). | Typed "confirm" | data_catalog_approval:write, data_catalog:read |
data-catalog-certification-deprecate-prepare / -execute | Marks a table or view as deprecated (avoid this source). | Typed "confirm" | data_catalog_approval:write, data_catalog:read |
Relationship tools
| Tool | What it does | Confirmation | Scopes |
|---|---|---|---|
data-catalog-relationship-propose | Proposes a reviewed join between two warehouse tables, with confidence and sampling evidence (match rates, sample values). Proposals are deduped regardless of direction. | – | data_catalog:write |
data-catalog-relationship-accept-prepare / -execute | Promotes a proposal to a real warehouse join, after re-validating and probing it. | Typed "confirm" | data_catalog_approval:write, data_catalog:read, query:read, warehouse_view:write |
data-catalog-relationship-reject-prepare / -execute | Rejects a proposal. Permanent – the pair is never re-proposed. | Typed "confirm" | data_catalog_approval:write, data_catalog:read |
Example prompts
Try these with your MCP-enabled agent:
What governed metrics do we have around revenue?Run the mrr metric for the last 6 months, monthly.Create a semantic layer metric named weekly_active_teams from the "Active teams" insight.Show me the compiled query for weekly_active_teams, then approve it.Certify stripe_charges as the source of truth for payments, and deprecate payments_backup with a note that it's stale.Propose a relationship between orders and stripe_customers on customer_id, with sampling evidence.List every proposed metric waiting for review.





