SafetyCard Request a review

DBHub

Token-conscious database MCP server for Postgres, MySQL, SQL Server, Oracle, MariaDB, SQLite

github.com/bytebase/dbhub · 2026-10-03 · 4ddb26e

Defense-in-depth score

4.1 / 10

As shipped in the README's lead command, DBHub gives MCP clients full read-write SQL access to your database, with no row limit or timeout, over an HTTP transport whose access control is not locked down. Its read-only mode is well built (a statement classifier plus a read-only database transaction on every engine), but it is opt-in and can only be enabled through a TOML file. Use a least-privilege database account and set readonly and max_rows in TOML before exposing it; the MCPB bundle and Claude Code plugin already ship read-only.

Safest setup

DBHub masks database passwords in its logs, sends no telemetry and includes a well-built read-only mode, but as shipped `execute_sql` runs any SQL, writes included, with no row limit or timeout. The safest setup pairs a least-privilege database account with the read-only mode and limits DBHub already offers, all set in a TOML file.

SetupHowWhat it gives you
A least-privilege database accountConnect with a dedicated, non-superuser account granted only the schemas and operations the task needs, read-only where the task allowsThe database itself refuses anything outside that grant, whatever SQL the model writes C1
Read-only modereadonly = true on the execute_sql entry under [[tools]] in a file passed with --config <path>Non-read statements are rejected and every query runs in a read-only database transaction C2
Parameterized custom toolsList only the tools each source needs under [[tools]], using custom tools with a fixed statement and typed parameters in place of raw SQLThe model fills in checked values for queries you wrote, against only the tools you listed C3
Row and time limitsmax_rows = <n> on each [[tools]] entry and query_timeout = <seconds> on each [[sources]] entryEach query returns a bounded number of rows and, on engines that support it, stops after a set time C10
The stdio transportKeep the default stdio transport whenever one local client is all you needOnly the host process that launched DBHub can call it C1
A private HTTP endpointWhen you need HTTP, serve it only on a private network reachable by your own clients, with access control turned onOnly clients you chose share the database credential DBHub holds C1
A clean working directoryStart DBHub from a directory with no .env file you didn't writeThe database and transport settings come only from you C6

Approving with confidence

  • Read each prompt and approve execute_sql calls one at a time; with writes enabled one tool runs both reads and writes, so the SQL text is what shows which kind a call is.
  • Statements run as soon as they are approved, with no preview or undo, so a call that changes data is worth a careful read.

Handling data

  • The tool-call record holds full SQL text in memory, keeps the last 100 calls per source and is gone on restart; keep your MCP host's own log if you need a lasting record.
  • The README's --dsn command puts the database password on the command line; a TOML file readable only by you keeps it out of shell history and process listings.

Key gaps (1)

  1. In the default configuration a hijacked host model can run destructive SQL (DROP, DELETE, UPDATE) unattended, so the worst case of a prompt injection from database content is irreversible damage to the database (C5-WORSTCASE). C5 · Untrusted input blast radius

Criteria

C1 Identity & least privilege

0.17 / 1.00

DBHub connects with one database credential supplied by the operator (the DSN) and uses it for every tool and every client. In the README's lead setup (HTTP transport), access control on the HTTP endpoint is not locked down. Read-only access is possible only through a TOML file; the old --readonly flag now exits with an error.

C2 Approval gates

0.50 / 1.00

As a tool server, DBHub's job is to tell the host which calls are dangerous. By default the single execute_sql tool both reads and writes, and it is honestly flagged as destructive, so a host can only gate all SQL or none. DBHub has a strong opt-in read-only mode: a per-tool TOML setting that rejects non-read statements and also runs them in a read-only database transaction, with matching read-only annotations. Because it is off by default and cannot be set from the command line, a wrongly approved call in the shipped setup can drop or delete production data with no undo.

C3 Tool & action scoping

0.47 / 1.00

The default execute_sql tool takes arbitrary SQL with no validation, row limit or timeout, against any table the credential can reach. Narrower options exist: TOML custom tools use parameterized statements with typed and enumerated arguments, search_objects validates and caps its inputs, and the opt-in read-only mode combines a keyword classifier with a database-level read-only transaction. None of these is the default, so a misused tool in the shipped setup can read or rewrite the whole database.

C4 Code-execution isolation

0.05 / 1.00

Raw SQL from the model is code, and DBHub adds no isolation around it: statements run in the database with the full privileges of the configured account, and SQLite databases are opened inside DBHub's own process. DBHub itself starts no subprocesses and evaluates no JavaScript. What a statement can reach depends entirely on the database account: with a superuser or highly privileged account, server-side features (file reads and writes, program execution) are within reach in the default write-enabled mode.

C5 Untrusted input blast radius

0.25 / 1.00

Database contents are untrusted input: any row can carry instructions aimed at the model reading it. DBHub returns results as structured JSON that names the source and the SQL each result came from, which helps a host tell data from metadata, but nothing marks the rows as untrusted. Its read-only mode would drop the state-change leg, but it is off by default. In the README's HTTP setup, a hijacked session can delete or alter shared data that every other client of the server also uses, so the worst case is rated at the bottom.

C6 Memory, context & configuration integrity

0.40 / 1.00

DBHub has no memory, retrieval store, or instruction files. The TOML config is loaded only from an explicit --config path and is hot-reloaded from that path. However, in TOML mode and in the env-var fallback mode, DBHub silently loads a .env file from the current working directory first, which can supply the database DSN, switch the transport to HTTP, or disable the DNS-rebinding check when those values are not already set. The README's --dsn invocation does not load it.

C7 Third-party extensions

N/A · full credit 1.00 / 1.00

DBHub loads no third-party code at runtime: there is no plugin system, no MCP client, and no model-driven package installs. Database drivers and optional cloud SDKs are fixed, string-literal imports that ship with the package, which is the project's own build supply chain and out of scope here.

C8 Secrets & sensitive-data protection

0.55 / 1.00

Database passwords are redacted when DSNs appear in startup logs and connection errors, the web API omits passwords and SSH credentials, and there is no telemetry. Credentials come from command-line flags, environment variables, or config files in plain text, and the SSH tunnel and the HTTP-mode request log (which holds full SQL text) do not fully protect sensitive data.

C9 Audit & traceability

0.40 / 1.00

Every tool call is recorded with its tool name, SQL, timestamp, duration, success and error, and the client's User-Agent. The record lives only in memory, keeps the last 100 calls per source, and disappears on restart; nothing is written to disk or shipped elsewhere, and tool calls are not logged to the console. A model can push its own earlier calls out of the record simply by making more calls.

C10 Limits & kill switch

0.33 / 1.00

search_objects has a server-enforced result cap (default 100, maximum 1000). The main execute_sql tool has no row limit and no query timeout unless the operator sets max_rows and query_timeout in a TOML file, and neither can be set with --dsn. Tool handlers ignore MCP cancellation, so a cancelled or abandoned query keeps running on the database.