SereneDB
> use case

Database for AI Agents with SereneDB

One Postgres-compatible SQL endpoint for your agents' tools: BM25, vector and hybrid search plus aggregations over native tables and remote sources.

Each agent logs in as its own role, and GRANT decides which tables and columns it reads. ai_embed() embeds the agent's question inside the query.

agent → one sql endpoint
Agenttool call · search_tickets('resets')
Role support_agentselect (id, product, body, emb)
SereneDBbm25 · ivf · group by · :7890
▼ one sql namespace
ticketsnative table
orders.public.*postgres_fdw
s3://…/*.parquetview · index
A tool call runs as the login role support_agent, which may select four columns, over a native table, a PostgreSQL server and Parquet on S3.
> overview

What Is a Database for AI Agents?

An AI agent is a model that calls tools in a loop. A database for AI agents sits behind its data tools and gets unreviewed queries one at a time: exact (tickets that mention error E1234), fuzzy (tickets like this one), aggregate (how many per product), often across several stores.

The label is loose — agentic database, AI-native database, AI database — and covers vector databases, per-agent database copies and text-to-SQL tools. Here it means a SQL database over structured data and text, with search built in and access enforced by the database. Agent context rarely lives in one place, the argument of search where your data lives.

one tool call
questionpassword tickets, by product?
SELECT product, count(*)
FROM   tickets_idx
WHERE  body @@ 'password'
GROUP  BY product;
▼ into the context window
1auth2 tickets
A full-text match and a GROUP BY in one statement; one row comes back: auth, 2 tickets.
> the problem

Why AI Agents Change What a Database Must Do

A traditional database serves a few reviewed queries from one application. An agent sends many unreviewed ones to whatever its tools reach.

01 · sources

Four stores, four tools

Tickets in one database, orders in PostgreSQL, events in ClickHouse, Parquet on S3: each store is one more tool, credential and dialect for the model. In SereneDB all four are one SQL namespace.

02 · context

Every result lands in the context window

Handing the model every matching ticket to count costs tokens. BM25 for the exact term, vector distance for the meaning and GROUP BY for the count return the answer, not the evidence.

03 · access

The scope has to hold without the prompt

A model that writes SQL will write a query you did not plan for. Privileges are checked on every query: SELECT on the columns it needs, USAGE on the servers it reads through. File readers and COPY follow the instance-wide enable_external_access setting instead, so give the model fixed statements.

> architecture

How SereneDB Works as a Database for AI Agents

A PostgreSQL-protocol driver, a role that decides which tables, columns and servers each statement may touch, and one engine running search and SQL over every catalog the role sees.

agent
Tool call
fixed sql
%s parameters
driver
A pg driver
wire protocol v3.0
port 7890
role
support_agent
grant select (cols)
usage on servers
serenedb
One engine
bm25 · ivf · sql
ai_embed()
catalogs
Tables · servers · files
postgres · clickhouse
s3 · disk
Fixed SQL goes through a PostgreSQL driver as support_agent, with column-level SELECT and USAGE on servers; one engine runs BM25, IVF and SQL over every catalog.

Search tools written in SQL

A search tool is a parameterized SELECT against an inverted index: @@ matches text and BM25 ranks it, a distance operator orders by similarity, and ai_embed() embeds the question on any OpenAI-compatible endpoint, a local Ollama included. IVF is covered on the vector search database page.

sql
SELECT id, title
FROM   kb_idx
WHERE  product @@ 'billing'
ORDER  BY emb <=> ai_embed($1, 'all-minilm', 'local_ai')::FLOAT[384]
LIMIT  5;
Filtered ANN: billing articles by cosine distance to the embedded question.
create server

Remote sources as catalogs

CREATE SERVER names a remote PostgreSQL or ClickHouse, queried as server.schema.table by roles holding USAGE. With no user mappings, one connection with the server's credentials serves every role: give it a read-only remote user. Files join through views, as in zero-ETL search.

sql
CREATE SERVER orders FOREIGN DATA WRAPPER postgres_fdw
  OPTIONS (host 'pg.internal', port '5432', database 'shop',
           user 'reader', password 'secret');

GRANT USAGE ON FOREIGN SERVER orders TO support_agent;

SELECT status, count(*) FROM orders.public.orders GROUP BY status;
The remote database becomes the catalog orders; the agent's role gets USAGE on it.
create role · hba

A login role per agent

In a multi-agent system, each agent gets its own LOGIN role with column grants; VALID UNTIL expires its password and an HBA rule pins it to the agent host's network. Avoid one privileged connection that runs SET ROLE per agent: the agent's SQL can RESET ROLE.

sql
SET hba = '
host  all support_agent 10.0.4.0/24 scram-sha-256
host  all support_agent 0.0.0.0/0   reject
host  all support_agent ::0/0       reject
local all all                       scram-sha-256
host  all all           0.0.0.0/0   scram-sha-256
host  all all           ::0/0       scram-sha-256';

ALTER ROLE support_agent PASSWORD 'rotated' VALID UNTIL '2027-04-01';
support_agent connects over TCP only from 10.0.4.0/24; other roles keep the default rules. ALTER ROLE rotates the password and sets an expiry.
> build it

Step-by-Step: Give an AI Agent Scoped SQL Access in 5 Minutes

01

Run SereneDB

One container on port 7890; POSTGRES_PASSWORD sets the superuser's password. Run steps 2 to 4 as postgres.

shell
docker run -d --name serenedb -p 7890:7890 -e POSTGRES_PASSWORD=change-this serenedb/serenedb
Step 1: Run SereneDB.
02

Create the table and its index

One inverted index covers the text, product and vector columns; step 4 grants the agent every column but customer_email.

sql
CREATE TEXT SEARCH DICTIONARY en AS
    split_text(case := 'lower') | stem_words('en_US.UTF-8')
    WITH (frequency, position);

CREATE TABLE tickets (id INTEGER PRIMARY KEY, product VARCHAR,
    body VARCHAR, customer_email VARCHAR, emb FLOAT[3]);

CREATE INDEX tickets_idx ON tickets
    USING inverted (id, product, body en, emb ivf (metric = 'l2'));
Step 2: Create the table and its index.
03

Insert rows and refresh

The index is eventually consistent: rows become searchable at the next refresh, every second by default, or at once after VACUUM (REFRESH_TABLE).

sql
INSERT INTO tickets VALUES
(1, 'billing', 'Invoice shows a duplicate charge', 'a@example.com', [0.0, 1.0, 0.0]::FLOAT[3]),
(2, 'auth',    'Password reset email never arrives', 'b@example.com', [1.0, 0.0, 0.0]::FLOAT[3]),
(3, 'auth',    'Cannot log in after resetting my password', 'c@example.com', [0.9, 0.1, 0.0]::FLOAT[3]),
(4, 'network', 'Connection drops every few minutes', 'd@example.com', [0.0, 0.0, 1.0]::FLOAT[3]);

VACUUM (REFRESH_TABLE) tickets;
Step 3: Insert rows and refresh.
04

Create the agent's role

SELECT on four columns only: an INSERT or a SELECT of customer_email fails with permission denied.

sql
CREATE ROLE support_agent LOGIN PASSWORD 'change-me'
    VALID UNTIL '2027-01-01';

GRANT SELECT (id, product, body, emb) ON tickets TO support_agent;
Step 4: Create the agent's role.
05

Connect as the agent and call its tool

The model picks the term; the statement is fixed. Stemming matches reset and resetting, so both auth tickets count.

python
import psycopg

conn = psycopg.connect(
    "host=localhost port=7890 dbname=postgres user=support_agent password=change-me"
)

def search_tickets(term):
    return conn.execute(
        "SELECT product, count(*) FROM tickets_idx"
        " WHERE body @@ %s GROUP BY product",
        (term,),
    ).fetchall()

search_tickets("resets")                             # [('auth', 2)]
conn.execute("SELECT customer_email FROM tickets")   # permission denied
Step 5: Connect as the agent and call its tool.
> use cases

Use Cases for an AI Agent Database

Support and triage agents

Tickets, error logs and release notes as indexed tables: BM25 catches the exact error code, vector distance the same failure in other words, GROUP BY how many customers hit it. The answering side is a RAG database.

Data agents over live sources

Text-to-SQL needs the schema; information_schema lists it in PostgreSQL's layout. The same queries run over remote Parquet, local files or a native table, and S3 is indexed in place: search over a data lake.

Coding agents that read your docs

Serene Docs Search indexes a docs repo, site or bucket into SereneDB; its optional MCP server lets Claude or Codex search it. A docs tool, not SQL over your tables: see documentation search.

> trade-offs

When SereneDB Is Not the Best Database for AI Agents

Three needs the docs do not cover:

01 · state

Agent memory and checkpoints

langchain-serenedb is a vector store and a retriever. The docs describe no chat-history store or checkpointer; long-term agent state would be tables you design yourself.

02 · isolation

Row policies, branches, per-agent copies

Access control is roles plus table, column and server privileges. Row-level security is not supported, the docs describe no database branching, and CONNECTION LIMIT is not enforced.

03 · operations

A managed service or a cluster

SereneDB ships as one binary. The docs describe a single-node deployment and mention no managed cloud.

> faq

Frequently Asked Questions

A database whose clients are AI agents: queries come from tools, unreviewed and at machine pace. In SereneDB: SQL over the PostgreSQL wire protocol, full-text, vector and hybrid search in one statement, and a role per agent.

The one that holds what the agent needs and limits what it touches: exact, semantic and aggregate answers in one call, reach into other stores, and per-agent roles scoped to tables and columns. SereneDB covers all three on a single node you run yourself, reaching PostgreSQL, ClickHouse and files.

Through a tool that runs parameterized SQL over a driver. SereneDB listens on port 7890 and works with psycopg, node-postgres, Npgsql and the other drivers in the clients docs; LangChain agents can use langchain-serenedb as a retriever. Connect as a role made for that agent, never as postgres.

Create a LOGIN role and grant only SELECT, on the columns it needs: GRANT SELECT (id, product, body, emb) ON tickets TO support_agent. INSERT, UPDATE and DELETE fail because they were never granted. The access_mode setting makes a whole database read-only, not one agent.

If you grant it. INSERT and UPDATE can be limited to columns; DELETE and TRUNCATE are separate privileges. Transactions are ACID, so a tool can roll back.

From their tools: APIs, search indexes, files and databases. Through SereneDB: native tables, PostgreSQL and ClickHouse via CREATE SERVER, and Parquet, CSV, JSON or Iceberg on S3 or disk, indexed in place through a view. A Hugging Face dataset loads with one CREATE TABLE.

The docs describe one, for documentation search. Serene Docs Search can add an optional MCP container that lets Claude or Codex search a docs corpus indexed into SereneDB, as our docs do at api.serenedb.com/mcp. It does not reach your tables; for SQL, agents use a PostgreSQL driver or langchain-serenedb.

> get started

Get Started with SereneDB

One container, one table, one role: five steps to an agent that searches tickets and cannot select customer_email or change a row.