That is the right shape for a tool an assistant drives: read-only per database, writes off globally, and the destructive statements still blocked after you enable writes. The schema cache is the other design decision that shows up in use — introspection is expensive on a large database, so caching it with a TTL and a version hash means the join suggestions and query help are answered from a local copy rather than re-read every turn. If you are wiring one database only, this is more configuration than you need; the payoff starts at two.
A SQL database MCP server built for the case where there is more than one database. Each connection gets an ID in a config file, and every tool call names which one it means. It discovers and caches schemas, infers relationships from foreign keys and heuristics, and blocks writes unless you have explicitly turned them on.
- The configured databases listed with their connection and cache state, and schema discovery that caches with a TTL and a version hash — `list_databases`, `introspect_schema`, `get_schema`, `cache_status`, `clear_cache`
- Parameterised queries with row limits, offsets, a byte cap on the response and a per-call timeout, plus a streaming export of large read-only results to JSONL or CSV — `run_query`, `export_query`
- Join paths suggested from the relationship graph for a set of tables you name, rather than worked out from the schema by hand — `suggest_joins`
- Query analysis: execution plans, index recommendations, slow-query detection, rewrite suggestions and per-query profiling — `explain_query`, `suggest_indexes`, `detect_slow_queries`, `rewrite_query`, `profile_query`, `analyze_performance`
- A connectivity test for when the failure is the connection rather than the query — `health_check`
A `.mcp-database-server.config` file describing each database — an `id`, a `type` of `postgres`, `mysql`, `sqlite`, `mssql` or `oracle`, and a connection string. Credentials have three paths and only one is recommended: `secretRef` names an environment variable, `credentialCommand` runs a shell command that prints the string (1Password, Vault, an AWS helper), and an inline `url` is supported but not the recommended secret handling. Install with `npm install -g @adevguide/mcp-database-server` or run through `npx`; the package is `@adevguide/mcp-database-server` (2.0.2) with a `mcp-database-server` binary. Writes are off by default at two levels — per-database `readOnly` defaults to `true` and the global `allowWrite` defaults to `false` — and `disableDangerousOperations` still blocks DELETE, TRUNCATE and DROP even when writes are allowed. Oracle is a stub requiring Oracle Instant Client.
One command plus a key — npm install -g @adevguide/mcp-database-server, then supply credentials
