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:

  1. Calls metric-list to read the catalog, then metric-describe to inspect a candidate's definition
  2. If exactly one approved, non-drifted match exists, runs it with data-catalog-metric-run and opens the answer with "🛡️ From your data catalog", naming who approved the definition and when
  3. If several materially different approved matches exist, asks you which one and stops
  4. 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
  5. 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

ToolWhat it doesConfirmationScopes
metric-listLists 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-describeReturns one metric's full definition, provenance, referenced tables, status, and drift state, addressed by name.–data_catalog:read
data-catalog-metric-runRuns 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-createCreates 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-updateUpdates 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-createRe-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 / -executeBlesses 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 / -executeDeletes 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

ToolWhat it doesConfirmationScopes
data-catalog-certification-proposeProposes 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 / -executeMarks a table or view as certified (prefer this source).Typed "confirm"data_catalog_approval:write, data_catalog:read
data-catalog-certification-deprecate-prepare / -executeMarks a table or view as deprecated (avoid this source).Typed "confirm"data_catalog_approval:write, data_catalog:read

Relationship tools

ToolWhat it doesConfirmationScopes
data-catalog-relationship-proposeProposes 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 / -executePromotes 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 / -executeRejects 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.

Still have questions?

Was this page useful?