Every time I connect an AI agent to a database, the same question comes up: where does the connection string live? Usually the answer is "in the agent's config file", which means a password sitting in a JSON file next to a tool I don't fully control.
I took a different route in omni-sql, an open-source desktop SQL IDE. The IDE already holds my connections (passwords live in the OS keyring). It also runs a local MCP server, so the agent talks to the IDE, not to the database.
How it works
- The MCP server runs over STDIO on loopback. The agent never receives a host, user, password or connection string.
- Reads (
getSchemaSummary,getTableIndexes,explainSql,getLatestSqlExecutionError) work on the connection of the active tab only. There is no tool to list or open other connections. - Writes are never automatic.
proposeSqlEditshows a before/after diff in the desktop.executeSqlshows the connection and the exact SQL, and runs only after I approve; the approval is bound to that request and expires after 120 s. - Results are bounded (default 100 rows, max 1,000, 256 KiB per response).
What this does and does not protect
It removes the credential from the agent's configuration. It does not hide data: SQL, schema names and permitted results are visible to the connected MCP client, so use it only when that exposure is acceptable. Approved SQL can still change data, so I use a least-privilege database user for anything important.
Why a desktop approval step
An agent that can run arbitrary SQL on its own is a bigger risk than one that has to ask. The approval dialog keeps a human in the loop for the one action that matters.
Also new since my last post
MongoDB (native queries plus read-only SQL via DuckDB), local analysis with DuckDB, CSV/S3 imports and macOS installers (v0.14.0).
Repo and docs: github.com/cccadet/omni-sql (see docs/MCP.md).
Question for readers: would you trust this model for a staging database, and what would you want the approval dialog to show?
Top comments (1)
This is the right shape: the agent gets a capability, not a credential. The 120-second approval window with the exact SQL shown is a nice touch. The same pattern works for wallets: the agent proposes an unsigned transaction, a local signer shows exactly what will be signed, and the key never leaves the machine. For staging I'd trust it with a least-privilege role and a statement timeout.