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.
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.
SELECT product, count(*) FROM tickets_idx WHERE body @@ 'password' GROUP BY product;
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.
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.
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.
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.
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.
%s parameters
port 7890
usage on servers
ai_embed()
s3 · disk
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.
SELECT id, title
FROM kb_idx
WHERE product @@ 'billing'
ORDER BY emb <=> ai_embed($1, 'all-minilm', 'local_ai')::FLOAT[384]
LIMIT 5;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.
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;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.
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';Step-by-Step: Give an AI Agent Scoped SQL Access in 5 Minutes
Run SereneDB
One container on port 7890; POSTGRES_PASSWORD sets the superuser's password. Run steps 2 to 4 as postgres.
docker run -d --name serenedb -p 7890:7890 -e POSTGRES_PASSWORD=change-this serenedb/serenedbCreate 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.
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'));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).
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;Create the agent's role
SELECT on four columns only: an INSERT or a SELECT of customer_email fails with permission denied.
CREATE ROLE support_agent LOGIN PASSWORD 'change-me'
VALID UNTIL '2027-01-01';
GRANT SELECT (id, product, body, emb) ON tickets TO support_agent;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.
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 deniedUse 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.
When SereneDB Is Not the Best Database for AI Agents
Three needs the docs do not cover:
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.
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.
A managed service or a cluster
SereneDB ships as one binary. The docs describe a single-node deployment and mention no managed cloud.
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 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.