Your agents can read production. They can’t change it.
QueryIO sits between AI agents and your database. Agents connect over MCP, the protocol Claude, Cursor and other clients use to call tools, and get three read‑only tools instead of a connection string.
Your agent calls run_query over MCP
UPDATE subscriptions SET status = 'cancelled' WHERE id = '3f9a-11ee' RETURNING id;
QueryIOchecks every query before connecting
- One statement: passed1 statement
- SELECT only: refusedUPDATE refused
- Allowlisted tables: not checkednot reached
- Row cap: not checkednot reached
- Timeout: not checkednot reached
Read-only replica PostgreSQL
Refused before the database. No connection was opened, so there was nothing to roll back.
A connection string gives the agent everything the role can do.
Most agent database setups hand the model a DATABASE_URL. You find out what it did afterwards.
It can write.
A prompt injection or a confused agent can run UPDATE, DELETE or DROP with the same credentials it uses to read.
It can stall production.
One unbounded join can hold locks and saturate I/O until someone notices and kills it.
It sees everything.
Payment tokens and secrets sit in the schema the agent pulls into its context window.
Three tools. Nothing else is on offer.
The agent can find tables, read their shape, and ask one question at a time. That covers what analysis needs and leaves out everything else.
list_tablesThe tables you allowlisted, with a one-line description each.
Withheld: System catalogs, migration tables, anything not on the list.
describe_tablesColumns, types and foreign keys for the tables it asks about.
Withheld: Columns you mark sensitive, like payment_method_token.
run_queryRows from one SELECT, run on a read-only replica.
Withheld: Every other statement type, multiple statements, more than 100 rows.
Why not just a read-only role?
A read-only role stops writes, and QueryIO uses one as its second lock. On its own it won’t stop a 40-table join at 3 a.m., keep secret columns out of the agent’s context, or narrow what the agent can ask for in the first place.
- Before the database
- The statement must parse as a single SELECT on allowlisted tables. A LIMIT 100 is added if missing. Anything else is refused without opening a connection.
- At the database
- Queries run on a replica in read-only transaction mode, so a write fails at the engine even if the first check were bypassed.
- Around every query
- A 5,000 ms timeout cancels long runs before they load your primary.
Hosted, or in your own VPC.
Point any MCP client at QueryIO: Claude Desktop, Claude Code, Cursor, or your own. The checks are the same either way.
We run the gateway and the replica connection. You add one URL to your MCP client.
{
"mcpServers": {
"queryio": {
"url": "https://<workspace>.queryio.dev/mcp"
}
}
}Illustrative config. Final names ship with the beta.
Give agents the answers, not the connection string.
We’re onboarding teams in small cohorts, starting with PostgreSQL. Tell us which database and agent client you use and we’ll prioritize accordingly.