Open context layer · MCP-native

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.

Get started → View on GitHub
uv tool install canonic
The problem

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:

✗ WITHOUT CANONIC: THE GUESS
$ canonic sql "SELECT SUM(amount) FROM fct_orders"

  sum
 ─────────
  4050.50
Includes two refunded orders ($260). Refunds are reversals, not revenue. This number is off by 6.4%.
✓ WITH CANONIC: THE TRUTH
$ canonic query --metrics revenue

  total_revenue
 ───────────────
  3790.50

  ▸ resolved: revenue → orders.total_revenue
  ▸ guardrail: revenue-excludes-refunds
"revenue" resolves to its canonical definition; the guardrail is compiled into the SQL either way. Zero guessing.
Three layers, plain files

Context that lives in your git repo, reviewed like code.

semantics/**/*.yaml

Semantics

"How do I query this safely?" Tables, types, grains, joins, measures: the executable semantic layer.

auto-maintained
knowledge/**/*.md

Knowledge

"What does this mean to the business?" Definitions, caveats, policies: searchable prose a human can trust.

auto-maintained
contracts/**/*.yaml

Contracts

"Which definition is canonical, and what must the answer obey?" Metrics, guardrails, assertions.

human-owned

A knowledge page explains why "amount includes refunds unless filtered." A contract makes the SQL obey it. Documented caveats become enforced guardrails.

What you can rely on

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.

Why canonic, not something else

It feeds the stack you already have. It doesn't replace it.

Alternative
What goes wrong
With canonic
Raw schema / SQL access for the agent
Fluency without correctness; it guesses definitions and picks the wrong tables.
Resolved canonical definitions, enforced guardrails, never a silent wrong number.
Hand-building a semantic layer
Months of modeling before any value.
Context auto-drafted from your live schema on day one; you review, not author from zero.
Adopting yet another metrics platform
Definitions you already wrote in dbt / MetricFlow get re-modeled by hand.
canonic ingests existing semantic layers as evidence. Your dbt models become context, not a rebuild.
A hosted "AI analytics" SaaS
Your data and definitions leave your environment.
Local-first, fully air-gapped-capable: nothing has to leave your machine.
In one line: canonic builds the context for you, keeps it honest, and refuses to lie when it isn't sure.
Quick start

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.

Read the docs → GitHub ↗
uvx canonic --version   # ephemeral, no install
uv tool install canonic # persistent, global

canonic setup           # point at a .db / .duckdb file
canonic query --metrics revenue
read-only · local-first · air-gapped-capable