AI agents that query your data correctly.
canonic sits between your data stack and your agents: an auto-built, git-versioned description of what your data means and how to query it safely. No guessing. And when it isn't sure, it refuses and asks.
Schema access makes an agent fluent. It doesn't make it correct.
An agent pointed straight at your warehouse sees tables and columns, not meaning. So it guesses, and a confident, well-formatted, wrong number is the worst kind of wrong. Real output from a live run:
Context that lives in your git repo, reviewed like code.
Semantics
"How do I query this safely?" Tables, types, grains, joins, measures: the executable semantic layer.
Knowledge
"What does this mean to the business?" Definitions, caveats, policies: searchable prose a human can trust.
Contracts
"Which definition is canonical, and what must the answer obey?" Metrics, guardrails, assertions.
A knowledge page explains why "amount includes refunds unless filtered." A contract makes the SQL obey it. Documented caveats become enforced guardrails.
Correct definitions, correct aggregation, and the proof attached.
Canonical definitions, enforced
An agent asks for a metric by name. canonic resolves it to the one agreed definition and compiles the SQL. Guardrails such as mandatory filters, required dimensions, source restrictions and minimum trust are part of the contract, so a documented caveat can't be skipped.
The right aggregation
Semi-additive measures, ratios recomputed at the requested grain, distinct counts, percentiles and running totals each get their own strategy. Joins that would fan out a fact table are caught, and when several join paths are valid canonic asks instead of guessing.
Answers carry their trust
Every result ships its definition, the guardrails that fired, freshness, final vs. provisional rows, and a trust tier with the reasons behind it. Assertions gate CI, and confirmed-wrong outcomes lower a metric's trust.
The context builds itself
Ingest drafts semantics from your live schema, a dbt manifest or an Apache Ossie model, and learns from Looker and Metabase usage, Notion pages and web docs. Every change is a reviewable diff, and drift is flagged.
Business knowledge for agents
Definitions, policies and caveats live as Markdown pages. Agents search them, read them with live-rendered definitions, and get the relevant caveats attached to an answer.
Refuse and ask
Ambiguous or unsafe questions come back as a structured reason, such as an ambiguous join path or a blocked guardrail, that the agent can act on. Never as a guess.
The number, and why to believe it.
Real output, abridged, from canonic query --metrics gross_revenue in the saas-analytics example.
- Which definition answered, and the SQL it compiled to.
- Which guardrails shaped the query.
- Why the number is only provisional, so the agent can say so.
Built to never produce a confidently-wrong answer.
Read-only by design
canonic never mutates your warehouse. It reads. There is no write path back.
Propose-only
It never silently edits your context. Every change is a reviewable diff anchored to evidence.
Refuse-and-ask
Ambiguous or unsafe? It returns a structured reason, not a guess.
No LLM in the answer path
Queries compile deterministically: the same question always produces the same SQL. An LLM only drafts context, never computes an answer.
Local-first & air-gapped
Run entirely on your machine with a local model and local embeddings. Nothing has to leave your network.
Measurable trust
A local event log tracks accuracy, freshness, and answer quality. "Trustworthy" is something you can check.
One deployment. Every tenant sees only its own truth.
Multi-tenant isolation and role-based access are opt-in policies, not application code. Add a contract, and every query, yours or an agent's, is scoped before it runs.
Tenancy
Row-level isolation enforced by compiling a tenant predicate into every joined source, not just the table in the query. The tenant comes only from a verified Principal token, never from anything an agent or LLM supplies.
Roles
Role-based access to metrics, dimensions, and knowledge tags, with column-level masking (null, hash, partial). A denied lookup looks identical to a nonexistent one, so there's no existence oracle for an agent to probe.
Enforcement happens inside the deterministic compiler, not as a bolt-on filter, and every answer logs its tenant, roles, and exemptions for audit.
It feeds the stack you already have. It doesn't replace it.
Your warehouse, your modeling, your agent.
Seven ready-to-run projects, no database required for most.
Your first correct answer in minutes.
Point canonic setup at a local SQLite or DuckDB file. It introspects the schema, drafts your semantics, and ends by answering a real question from your data. Then connect Claude, Cursor, or any MCP client, no separate integration to build. canonic needs Python 3.13 or newer, and uv fetches it for you.