Open-source Postgres extension

Keep Postgres boring. Put the exciting parts around it.

RVBBIT keeps Postgres as the source of truth while routing analytical queries across specialized engines, exposing models and tools through SQL, and writing down every decision it makes.

Route queries. Call models. Rewind tables. Keep receipts.

Your hardware · your data · no lock-in.

  • GPU query routing
  • time-travel tables
  • a router that learns
  • LLMs in a WHERE clause
  • distributed read fleet
  • every call receipted

Semantic SQL

Call a model from inside a SELECT.

Classify a column, filter a WHERE by meaning, even file a ticket — with retries, validation, and a cost receipt. We call these operators, and you can build (or deploy) your own.
your operators + a built-in semantic filter
-- your operators + a built-in semantic filter, one query
SELECT ticket_id,
       triage(body)    AS priority,   -- your classifier
       sentiment(body) AS mood        -- another operator
FROM   support_tickets
WHERE  created_at > now() - interval '1 day'
  AND  rvbbit.means(body, 'a customer about to cancel');
2 matchessemantic filterreceipts logged ✓
ticket_idprioritymood
1842urgentangry
1907urgentfrustrated
Data Rabbit — a desktop over any Postgres, lit up on an RVBBIT database: adaptive routing, model deploys, the operator canvas, the knowledge graph, and live receipts.
Data Rabbit — point it at any Postgres to browse and query; point it at an RVBBIT database and it lights up. Everything here is plain SQL underneath.

Why it's different

Not a fixed menu of AI functions — a layer you program.

Cortex and Databricks hand you a sealed set of AI SQL calls on their cloud. RVBBIT hands you the building blocks: compose hosted models, your own Hugging Face deployments, tools, retries, and receipts into operators you define — open source, on Postgres, over your own data.

You build the operators

Not a sealed list of AI functions. Compose model calls, your own validators, retries, and tool calls into one typed SQL function — your operator, your logic.

Bring your own models

Spin up a Hugging Face specialist or your own model on your own GPU and call it from SQL like any other function — or use the 40-plus packs that ship in the box. Not a vendor's frontier-model menu.

Open, local, no lock-in

It's a Postgres extension you run yourself. Heap stays the source of truth — drop the extension and your data is still ordinary rows.

SQL that acts

A SELECT can file the ticket — and leave a receipt.

An operator is an ordinary SQL function, but inside it can call models, MCP tools, and flows. So Postgres's own machinery — triggers, pg_cron, Alerts — becomes an automation engine. SELECT do_stuff() actually does stuff: opens tickets, posts messages, kicks off analysis — with trackable SQL as the glue.
-- A plain Postgres trigger that now reaches the outside world:
-- analyze the incident with your operator, file a Linear ticket.
CREATE FUNCTION on_critical_incident() RETURNS trigger AS $$
BEGIN
  PERFORM rvbbit.mcp_call('linear', 'create_issue', jsonb_build_object(
    'title',       'SEV1 · ' || NEW.service,
    'description', summarize_incident(NEW.logs)   -- your LLM operator
  ));
  RETURN NEW;
END $$ LANGUAGE plpgsql;

CREATE TRIGGER incident_to_linear
  AFTER INSERT ON incidents
  FOR EACH ROW WHEN (NEW.severity = 'critical')
  EXECUTE FUNCTION on_critical_incident();
-- Or declare it: a condition → an action, swept on a clock, edge-triggered.
SELECT rvbbit.define_alert(
  'revenue_drop',
  '{"kind":"sql","metric_name":"daily_revenue"}'::jsonb,
  '{"operator":"mcp_call","server":"linear","tool":"create_issue"}'::jsonb
);

Operators have side effects

Compose a model call, an MCP tool, a validator, and a flow into one function. Calling it doesn't just compute — it acts.

Triggers, schedules, alerts

A trigger fires it on INSERT, pg_cron on a clock, or declare an Alert: condition → action, edge-triggered and fire-and-forget.

Every action is audited

Each side effect can leave a receipt — args, sub-calls, latency, cost, errors — so automation stays replayable and reviewable, not a black box.

Read about reactive Alerts

Receipts

Every model call and side effect is logged, costed, replayable.

Each operator and action can write a receipt — its inputs, the model, the sub-calls it fanned out to, tokens, cost, latency, and any error. Governance isn't a bolt-on: it's a row in a table you can query, join, and audit like anything else.
  • operator
  • model
  • inputs
  • sub-calls
  • tokens in / out
  • cost · USD
  • latency · ms
  • error
  • take / verdict
  • query_id
-- what did the last day of AI + actions cost, and where?
SELECT operator,
       model,
       count(*)                                  AS calls,
       round(sum(cost_usd)::numeric, 4)          AS cost_usd,
       round(avg(latency_ms))                    AS avg_ms,
       count(*) FILTER (WHERE error IS NOT NULL) AS errors
FROM   rvbbit.receipts
WHERE  invocation_at > now() - interval '1 day'
GROUP  BY operator, model
ORDER  BY cost_usd DESC;
Data Rabbit receipts and costs view showing operator and model rollups for calls, tokens, cost, latency, errors, and recent activity.
Receipts cockpit - live operator/model rollups for calls, tokens, cost, latency, errors, and last-call recency.
Read about receipts and costs

Models & capability packs

Ships with 40+ model packs. Add any Hugging Face model in a paste.

Every operator is backed by a model, and RVBBIT comes with a catalog of curated packs — local specialists (GLiNER, DeBERTa, BGE rerankers), embeddings, summarizers, even MCP servers like Brave and Apollo — each exposing ready-made SQL operators. That's where means(), about(), extract_pii(), and classify() come from: they work on day one, no prompt-wiring.

Batteries included

40+ curated packs: classification, extraction, embeddings, reranking, summarization, web search. Day one, means() and classify() just work.

Paste a model, get a function

Pick a model in Data Rabbit; a scaffold → build → register → smoke pipeline turns it into rvbbit.your_operator(...). Local or managed runtime, CPU or CUDA.

MCP servers are packs too

Register an MCP server and its tools become pseudo-tables or functions — joinable beside your data, audited like everything else.

Deploy from Hugging Face in Data Rabbit — paste a model ID, inspect it, and run a scaffold → build → register → operator → smoke pipeline that turns it into a typed SQL operator, deployed local or to a managed runtime.
Deploy from Hugging Face — paste a model ID, get a typed SQL operator.
The capability catalog in Data Rabbit — 40+ curated packs mixing local specialist models, API embeddings, and MCP servers, each card exposing a set of ready-made SQL operators with call counts, latencies, and test status.
The capability catalog — 40+ packs, each exposing ready-made SQL operators.
Browse the capability catalog

Semantic functions

Retrieval, classification, and graph memory — built-in SQL functions.

RVBBIT ships built-in semantic primitives for retrieval, classification, clustering, extraction, evidence, graph memory, and audit receipts. Use them directly or as steps inside Cascades.

Semantic retrieval

Use embeddings, KNN, evidence snippets, and join-back patterns without leaving SQL.

Built-in primitives

Classify, cluster, dedupe, diff, extract, and score text before you write custom operators.

Graph memory

Extract triples, preserve evidence, merge aliases, and retrieve KG context for RAG.

Bring your own operators

When the built-ins aren't enough, compose your own from models, tools, and validators — same SQL call shape.

WITH hits AS (
  SELECT value, score
  FROM rvbbit.knn_text(
    'tickets'::regclass,
    'body',
    'renewal risk after late shipments',
    20
  )
)
SELECT t.ticket_id,
       h.score,
       rvbbit.semantic_case(
         t.body,
         ARRAY['billing issue', 'shipping delay', 'renewal risk'],
         ARRAY['billing', 'shipping', 'renewal'],
         'other',
         0.0
       ) AS bucket
FROM hits h
JOIN tickets t ON t.body = h.value
ORDER BY h.score DESC;
SELECT *
FROM rvbbit.triples_rows(
  'Acme delayed renewal after repeated fulfillment misses.',
  'customer risk'
);

SELECT receipt_id, operator, model, latency_ms, error
FROM rvbbit.receipts
ORDER BY invocation_at DESC
LIMIT 10;

Text-to-SQL

Ask in English, get one grounded SELECT over your real schema.

Plain text-to-SQL is tame in 2026. The interesting part: rvbbit.synthreads your catalog and writes ONE read-only SELECT against your actual tables and foreign keys — and it's the same operator + receipts machinery as everything else here, so the generated SQL is grounded, validated read-only, cached, and inspectable.
-- Ask in English; get ONE grounded, read-only SELECT over your real schema.
SELECT rvbbit.synth_sql('bigfoot sightings in California since 1990');

  SELECT s.id, s.state, s.classification, s.reported
  FROM   bigfoot.sightings AS s
  WHERE  s.state = 'California' AND s.reported >= DATE '1990-01-01'
  ORDER  BY s.reported DESC
  LIMIT  100;

-- Same machinery as every operator: catalog-grounded, validated, cached, replayable.
Read about text-to-SQL

MCP as a SQL primitive

Call any tool from SQL — as a data source, or an action.

Register MCP servers in Postgres and discover their tools. Read them as JSON or row sources to join beside your data — or call them to make something happen. Every invocation is cataloged and audited, and any tool can be a node inside a Cascade.

Tool ecosystems, not app glue

GitHub, filesystem, internal HTTP, and custom MCP servers become catalog-backed SQL surfaces instead of hidden application code.

Rows when you need rows

mcp_rows unwraps list-shaped tool responses so they can be filtered, joined, ranked, and aggregated beside real Postgres data.

Observable by default

Discovery, health, caching, usage, latency, and invocation history live in RVBBIT tables and views for SQL-native UIs.

SELECT rvbbit.register_mcp_server(
  server_name       => 'github',
  server_transport  => 'stdio',
  server_command    => 'npx',
  server_args       => ARRAY['-y', '@modelcontextprotocol/server-github'],
  server_env        => '{"GITHUB_PERSONAL_ACCESS_TOKEN":"${GITHUB_TOKEN}"}'::jsonb
);

SELECT rvbbit.refresh_mcp_server('github');
SELECT a.account_id,
       a.company_name,
       repo->>'full_name' AS matching_repo,
       (repo->>'stargazers_count')::int AS stars
FROM accounts a
JOIN LATERAL rvbbit.mcp_rows(
  'github',
  'search_repositories',
  jsonb_build_object(
    'query', a.company_name || ' postgres',
    'perPage', 3
  )
) repo ON true
WHERE a.tier = 'strategic'
ORDER BY stars DESC;
Read the MCP SQL surface

Operators become cascades

Multi-step model logic, called like SQL.

A Cascade is the execution plan inside a semantic operator — guards, model calls, validators, retries, tool calls, and a receipt — still exposed as a single typed Postgres function.
An operator's cascade on the canvas in Data Rabbit — its steps (input, a specialist model node, output parser) wired together, a Try-It panel that runs the operator for real, and a live receipt with latency, tokens, and execution history.
One operator's cascade on the canvas — every step, with a live receipt.

The workflow lives next to the data

Instead of scattering model orchestration across application code, RVBBIT keeps it in the database — observable in SQL, versioned, and callable from an ordinary query.

SELECT ticket_id,
       rvbbit.review_risk(body, account_tier) AS risk
FROM support_tickets
WHERE created_at >= now() - interval '1 day';

Architecture

Heap is the source of truth; fast paths are optional and earn their place.

One extension, multiple execution paths. A semantic layer and an optional storage/routing engine sit beside the Postgres heap — which stays authoritative, with fallbacks for correctness and pg_dump/restore.
01

Heap

Authoritative Postgres tables and fallback execution.

02

Accelerate

Columnar files, layout variants, time travel, hot cache, Lance.

03

Route

Cheap query-shape decisions plus optional trained profiles.

04

Warren

Capability nodes for semantic and workflow execution.

Metrics & KPIs

A versioned BI layer — built in, never required.

A metric is a name and a SELECT. Add one more SELECT that returns a boolean and it is a KPI. Every definition is versioned, so you can re-run exactly the rule you shipped last quarter. It is all plain RVBBIT tables and your own data: no metric store, no DSL, no lock-in.

Versioned definitions

Every metric is an append-versioned row. The definition — including the KPI threshold — is part of the record, so you can re-run exactly the rule you shipped last quarter, or apply today's definition going forward.

A KPI is a versioned threshold

A check is one SELECT returning a boolean. Because the threshold is versioned too, you can ask: was this green under the rule we believed in then?

Durable, verdict-stamped history

Observations are written when the data changes — compaction is the trigger — and outlive generation reaping. One immutable row per snapshot: value, verdict, and the threshold it ran against.

Parameterized and composable

Inject params and reference other metrics inline — {param}, {metric:NAME} — so one definition builds on another instead of copy-pasted SQL.

-- a metric is a name + SELECT; the 8th arg makes it a KPI
SELECT rvbbit.define_metric(
  'daily_revenue',
  'SELECT sum(amount) AS total FROM orders',
  '{"target": 1000000}'::jsonb, 'all', 'Revenue must clear target', 'analytics',
  '{}'::jsonb,
  'SELECT total >= {target} AS ok, total AS value FROM metric');

-- evaluate it under the exact definition we shipped on 2025-01-01
SELECT rvbbit.check_metric('daily_revenue', '{}'::jsonb,
  def_as_of => '2025-01-01');
-- => {"ok": true, "value": 1180000, "status": "pass"}
Read the Metrics & KPIs surface

Acceleration benchmark snapshot

When a fast path fits, the router takes it.

Work-in-progress runs compare the default RVBBIT router against Postgres, Hydra, Citus, AlloyDB, and ClickHouse. Not final, audited numbers — but real end-to-end measurements, and directionally honest.
ClickBench 5M rows

46.2ms geomean

Suite time3.87s
Wins22/43
Route mix16 GPU GQE
TPC-H SF1

165ms geomean

Suite time8.97s
Wins7/22
Route mix12 Duck/Vortex
Query-by-query results

Data Rabbit

A Postgres desktop that gets superpowers on RVBBIT.

Data Rabbit is a fast desktop for any Postgres — browse, query, explore. Point it at an RVBBIT database and it lights up: watch the planner pick an engine, deploy a specialist model, build operators on a canvas, and read live receipts. Works without the extension; unmissable with it.
The Adaptive Routing cockpit in Data Rabbit — the planner choosing among native, DataFusion, Duck, and heap per query shape, with live timings.
Adaptive Routing — watch the planner pick an engine per query.
Model Studio in Data Rabbit — spinning up a Hugging Face specialist model and wiring it to a SQL operator.
Model Studio — spin up a specialist model, call it from SQL.
Scry in Data Rabbit — a graph explorer over the data knowledge graph, spidering from a table to its columns and related entities.
Scry — explore your data's knowledge graph.
Data Search in Data Rabbit — free-text semantic search over the catalog, ranking tables and columns by what their data is about.
Data Search — find tables by what their data is about.

Documentation

Start with one SQL snippet. Go as deep as you want.

docker compose up -d

One compose file brings up the whole thing — Postgres 18 with the extension preinstalled, the query workers, Data Rabbit, and a Warren agent. Start with a single SQL snippet and go as deep as you want — heap stays the source of truth.