open source · Apache-2.0 · early development

Your business,
compiled.

Define an object once. Ontologiq compiles it into SQL views, governed MCP tools for AI agents, and an explorable catalog. Actions carry policy, approval and audit — declared in YAML, versioned in Git.

See what it compiles →
py ≥ 3.11 duckdb · postgres · mysql · databricks
objects/customer.yml
object: customer
source:
  table: customers
identity: [customer_id]

state:
  active:  last_seen >= now() - 90d
  churned: last_seen < now() - 90d
  else:    prospect

relations:
  orders:
    type: has_many
    target: order
→ 1 SQL view · state computed
→ 3 MCP tools · typed
→ 1 explorable catalog

Semantic layers tell you how much. Ontologiq knows who, in what state, and what may be done.

01
compile
in — objects/order.yml
object: order
source:
  table: orders
identity: [order_id]

state:
  disputed: dispute_opened_at is not null
  open:     fulfilled_at is null
  else:     fulfilled

actions:
  - name: cancel
    requires: state == 'open'
    policy:
      roles: [support]
    approval: required
    effect:
      type: webhook
      url: "{{ env.OPS_API }}/orders/{order_id}/cancel"
out — ontologiq build
views/customer.sql view · computed state
views/order.sql view · computed state
catalog.json objects · relations · actions
mcp/manifest.json propose_order_cancel · policy
compiled 2 views → target/ · 5 data checks passed · build OK: customer, order ready to query
02
govern

Policy

Who may call an action: the roles you already have, and — over HTTP with OIDC — verified actor attributes: region == actor.region. A denied call is recorded in the audit log and never reaches the warehouse.

Approval

Gates that put a human in the loop. The agent proposes; a reviewer signs in the terminal — and the precondition is evaluated again at execution, because approvals age.

Audit

Append-only, written before any effect fires: actor, arguments, decision, outcome. A lost effect response is recorded as unknown — never guessed as failed.

03 — agents

Agents get tools,
not table access.

Every action compiles into an MCP tool with a typed signature, its policy attached and its audit row written. The model never sees a connection string — it sees propose_order_cancel and the records it may read. It can propose, never approve: no approve capability exists on any surface the model can reach.

  • Typed arguments, validated before anything runs
  • Preconditions evaluated at proposal — and again at execution
  • Approval signed in the terminal, outside the model's reach
  • Over the network, identity is verified per request: serve --http requires OIDC, and the audit records the token subject
agent session
▸ tool call
propose_order_cancel({ order_id: "ord_8812" })
▸ serve runtime
requires: state == 'open'
policy: role 'support' allowed
queued — approve in the terminal: ontologiq approvals
audit: intent recorded · pinned to the ontology digest
04 — quickstart
step 01

Install

One package, no service to run. Python 3.11+.

$ pip install ontologiq
step 02

Start from a demo — or from dbt

ontologiq init scaffolds a working shop. Already on dbt? import dbt scaffolds objects from your models, with identity candidates from your tests.

$ ontologiq init shop
step 03

Compile & serve

Views to your warehouse, MCP tools to your agents.

$ ontologiq build && ontologiq serve

One file. Four artifacts.
No platform.

Runs on the warehouse you already have. Nothing leaves your Git repo.

Read the docs