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.
Open-source Postgres extension
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.
Semantic SQL
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, 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');| ticket_id | priority | mood |
|---|---|---|
| 1842 | urgent | angry |
| 1907 | urgent | frustrated |

Why it's different
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.
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.
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
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
);Compose a model call, an MCP tool, a validator, and a flow into one function. Calling it doesn't just compute — it acts.
A trigger fires it on INSERT, pg_cron on a clock, or declare an Alert: condition → action, edge-triggered and fire-and-forget.
Each side effect can leave a receipt — args, sub-calls, latency, cost, errors — so automation stays replayable and reviewable, not a black box.
Receipts
-- 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;
Models & capability packs
means(), about(), extract_pii(), and classify() come from: they work on day one, no prompt-wiring.40+ curated packs: classification, extraction, embeddings, reranking, summarization, web search. Day one, means() and classify() just work.
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.
Register an MCP server and its tools become pseudo-tables or functions — joinable beside your data, audited like everything else.


Semantic functions
Use embeddings, KNN, evidence snippets, and join-back patterns without leaving SQL.
Classify, cluster, dedupe, diff, extract, and score text before you write custom operators.
Extract triples, preserve evidence, merge aliases, and retrieve KG context for RAG.
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
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-SQLMCP as a SQL primitive
GitHub, filesystem, internal HTTP, and custom MCP servers become catalog-backed SQL surfaces instead of hidden application code.
mcp_rows unwraps list-shaped tool responses so they can be filtered, joined, ranked, and aggregated beside real Postgres data.
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;Operators become cascades

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
Authoritative Postgres tables and fallback execution.
Columnar files, layout variants, time travel, hot cache, Lance.
Cheap query-shape decisions plus optional trained profiles.
Capability nodes for semantic and workflow execution.
Metrics & KPIs
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 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?
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.
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 surfaceAcceleration benchmark snapshot
Data Rabbit




Documentation
What RVBBIT is, how the pieces fit, and how to read the docs.
StartWhat RVBBIT is for, what acceleration adds, and where the system should stay boring.
StartStart the Docker ensemble, run semantic SQL, and accelerate your first table.
StartShort SQL examples that show the main RVBBIT ideas without setup noise.
ExamplesA runnable SQL notebook over BFRO sightings using RVBBIT retrieval, semantic classification, extraction, KG, and receipts.
SQL PrimitivesModel-backed operators, embeddings, KG helpers, MCP tools, and cost receipts.
SQL PrimitivesBuilt-in semantic primitives for retrieval, classification, clustering, extraction, and evidence.
SQL PrimitivesMulti-step operator workflows with gates, takes, validators, retries, reducers, and receipts.
SQL PrimitivesEmbeddings, KNN search, materialization, Lance, and SQL patterns for RAG.
SQL PrimitivesRegister MCP servers, discover tools, call them from SQL, and use them inside Cascades.
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.