The database you can hand an agent the keys to.
Quack On Demand is a governed SQL gateway over autoscaling fleets of DuckDB nodes. Agents connect over MCP with scoped, revocable tokens; humans and BI tools over Arrow FlightSQL. Every statement, from either, goes through the same enforcement path: ACLs, row policies, column masks, budgets, and a kill switch.
The agent never holds a database credential. Tokens are minted narrower than their owner: databases, verbs, row ceilings, timeouts, budgets, expiry. Tokens mint tokens, each a strict reduction.
Table-level ACLs, row-level policies, and dynamic data masking enforced on every statement, whether it arrives over MCP or FlightSQL. No "agent mode": same code, same executor.
Every statement is attributed to the acting token, live-killable, and audited. Revoking a token kills its live statements and every child it minted, in one call.
Fleets of DuckDB Quack nodes autoscale on your Kubernetes, or run as one Docker container. Sign-in through your IdP: OIDC SSO (Keycloak, Google, Azure AD, Cognito) with SCIM provisioning.

The agent-ready database
Built for the newest kind of database user.
An agent writes arbitrary SQL like an analyst, issues it at machine speed like an application - and nobody reads it before it runs. Quack On Demand is designed for exactly that caller: the policy lives on the credential, not in the prompt, because grants are the only thing an injected instruction cannot argue with.
MCP and ADBC
Agents connect to POST /mcp with a bearer token and a small tool surface shaped for how agents work: list_tables, describe_table, run_sql, time travel, my_usage. Applications and BI tools connect over ADBC with zero-copy Arrow results. Stateless, so any replica answers any request.
The agent never holds a database credential
It holds a personal access token that resolves to a QoD principal - never the object-store keys or catalog credentials. Stored only as a SHA-256 hash, expiring, revocable in one call without disturbing anyone else.
Delegation is always a reduction
Tokens mint tokens, each strictly narrower: databases, verb ceilings, row caps, timeouts, budgets, expiry. An orchestrator hands each sub-agent its own credential without a human in the loop - and revoking the parent revokes the whole chain, atomically.
One enforcement path - no "agent mode"
A statement arriving over MCP goes through exactly the same validator, per-table grants, row policies, and column masks as one arriving over Arrow FlightSQL. Same code, same executor. A fully compromised agent still cannot exceed the grants on its credential.
Attributable, killable, audited
Every statement carries the owning human and the acting token. Live statements are killable by id, and revocation kills a credentialβs in-flight statements too. Writes stamp their author into the DuckLake snapshot, so lineage is answerable from the data itself.
Budgets and structured refusals
Per-credential rate limits, concurrency caps, byte ceilings, and spend budgets - my_usage tells the agent what remains. Every denial is a machine-readable envelope: a stable code, whether retrying helps, what budget is left. Agents adapt in one turn.
Undo: agents write to branches
Hand an agent a DuckLake snapshot branch, review its work as a diff against the parent, then merge or discard atomically. Pin a session to a snapshot and the world cannot shift under it mid-investigation. Reversible mistakes are what make agent writes possible at all.
Context, so agents stop guessing
Business descriptions on tables and columns, curated agent-facing views, worked query examples, and a schema digest sized to a context window. Wrong SQL is a governance problem too: it costs money and erodes trust in the answers.
Blast radius bounded by architecture
Each database is served by its own pool of processes, isolated per tenant. A runaway cartesian join saturates its own pool - scale, suspend, or kill it without touching anything else. Pools scale to zero when idle. The noisy neighbour is not a neighbour.
And underneath
Everything DuckDB Quack is missing in production.
DuckDB ships Quack as a minimal HTTP endpoint on localhost with a random token, and explicitly recommends a reverse proxy in front of it. Quack On Demand is that proxy - with the multi-tenancy, identity, and observability you need to actually expose it.
Arrow FlightSQL edge
Zero-copy result streaming over Apache Arrow Flight SQL - orders of magnitude faster than JDBC for analytical workloads. TLS is on by default and a self-signed cert is generated on first boot.
Multi-tenant pools
Spin up tenants and pools of DuckDB Quack nodes on demand. Each node is READONLY, WRITEONLY, or DUAL - the router classifies every statement and picks a compatible target.
Pluggable authentication
Database (bcrypt-hashed JDBC), external JWT (HS256/RS256/PEM), and OIDC providers - Keycloak (with ROPC), Google, Azure AD, AWS Cognito. Mix and match per deployment.
Enterprise identity - SSO & SCIM
Per-tenant OIDC single sign-on, and a SCIM 2.0 endpoint so Okta, Entra or Google provision, update and deprovision users and groups automatically - no manual account admin, and deactivation cuts query access, not just the console.
Postgres-relational RBAC
Roles, groups and per-table permissions live in qodstate_* tables next to the DuckLake metadata, with column masking and row-level filters rewritten at the edge. Principals expand to user / group / role at validation time so grants match whichever level of identity is stable.
Live admin console
React dashboard at /ui/ - tenant + pool CRUD, per-tenant ACL editor, live node metrics (inFlight, totalServed, EWMA latency), admin-role gated.
Self-healing on restart
Dead Quack child processes are detected (PID + port probe) and respawned automatically before the edge accepts traffic. Manager restarts no longer strand the fleet.
Deployment
Single binary
REST + React UI + FlightSQL edge in one process. State lives in Postgres next to DuckLake - no extra moving parts.
Configuration
Every key is overridable
Every scalar in application.conf accepts a matching QOD_* env-var. Build the image once, flip behavior per environment.
Runtime
Single container or Kubernetes
Single-node mode runs everything in one Docker container - ideal for single tenants, with Quack child processes on a port range. Kubernetes mode runs them as pods. Same control plane, same admin UI.
Query federation
One SQL surface over every source.
Quack On Demand turns DuckDB's federation into a governed, multi-tenant service. Point a query at your lake, your Iceberg warehouse, and your operational databases at once - and join them in place, without moving a byte.
Query data where it lives
Object storage, Iceberg tables, and operational databases are read in place. No copies, no nightly ETL, no second engine.
Join across sources in one statement
A single SQL query spans Parquet on S3, an Iceberg warehouse, and a Postgres table - DuckDB pushes down filters and streams results back over Arrow.
Governed like everything else
Every federated table reference passes the same per-statement RBAC and table-ref policy checks - federation never bypasses your ACLs.
-- One statement, three sources, zero copies
SELECT o.region,
c.segment,
SUM(o.amount) AS revenue
FROM read_parquet('s3://lake/orders/*.parquet') o
JOIN postgres_scan('crm','public','customers') c
ON c.id = o.customer_id
JOIN iceberg_scan('s3://warehouse/products') p
ON p.sku = o.sku
GROUP BY 1, 2;Bring your own pipeline
Works with any ETL, however you built your data.
QoD is a serving layer. It sits downstream of whatever produced your data. It does not care which tool wrote it, and it never routes your users anywhere.
Your agents are going to query production. Decide the terms.
The organisations that let agents in are the ones that can answer, without hedging: what can this agent see, what can it spend, what did it do, and how do I stop it. QoD answers all four - on the same enforcement path as every human caller. Start with one command: uvx qod start --demo, then point your agent at /mcp with a token and ask it something.