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
A terminal showing the safe-db MCP server refusing a DELETE statement: only SELECT statements can run here

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.

safe-db is proudly opensource. Apache License 2.0.

GitHub