Bounded by default. Agents welcome.
An MCP server that lets an agent look at a production database the way safe-db lets a person: read-only, bounded, and scored before anything runs. The same engine as the desktop app, with no window in front of it.
npm install -g @safe-db/mcp
- Standard MCP
- Apache-2.0
- macOS, Windows, and Linux

Same engine, no window
The agent sends SQL text. safe-db parses it into a structured query and compiles that with
bound parameters, so the text itself never reaches the database. One SELECT per call. Writes, subqueries, aggregates, and multiple statements are rejected with an explanation
the agent can act on.
Every run is scored against its query plan and an adjustable risk gate. Above the gate, the tool returns a reason instead of rows. The agent can rewrite the query. It cannot argue with the gate.
- Default sample
- 500 rows. Enough to answer the question.
- Hard cap
- 10,000 rows. The ceiling is not negotiable from inside a tool.
- Query timeout
- 10 seconds, then the database is left in peace.
- Preview
- About 10 rows in the receipt. The rest is paged, 50 at a time.
- Results
- Kept in memory for 30 minutes, then forgotten.
Seven tools, one gate
A progressive catalog, then a gated query. No tool returns the full schema or the full result, and no tool accepts a password or a connection URL.
- list_connections
- Saved connections as id, name, dialect, and database. No passwords, no URLs.
- list_tables
- Visible tables with schema, size class, and column count. Blocked schemas and system catalogs are omitted.
- describe_table
- Columns, indexes, and foreign keys for one table. Not the whole catalog.
- run_query
- One SELECT through the parser, validator, compiler, caps, and risk gate. Returns a receipt with a short preview and a result_id, not the grid.
- get_result_rows
- Pages the fetched sample by result_id, 50 rows at a time. No second query.
- summarize_result
- Per-column null counts, min and max, and up to 8 distinct values from the same sample.
- delete_connection
- Removes a saved connection. The first call asks for confirmation; the agent cannot supply its own.
{
"mcpServers": {
"safe-db": {
"command": "npx",
"args": ["-y", "@safe-db/mcp"]
}
}
} Configure once
That is the whole client entry. Connections are added from the CLI, which prompts for the password without echo or reads it from an owner-only file, tests the connection, and saves the secret to the credential store. Tools refer to connections by id and never return secrets.
Passwords do not appear in the client config, in tool arguments, in flags, or in environment variables. The agent does not know the password. That is the point.
Where it runs
The package bundles its own Java runtime, so the machine does not need Java. Same four databases as the desktop app: PostgreSQL, MySQL, SQL Server, and Oracle.
macOS
Apple Silicon only. Intel Macs are not supported.
Windows
x64. Shares connections and Credential Manager with the desktop app.
Linux x64
glibc distributions. Alpine and musl are not supported.
Linux arm64
glibc distributions. The desktop app does not run here; the server does.
Give the model a database client you don’t have to worry about
One npm package, one CLI command per connection, one line in the client config. The agent can look. It cannot touch.