Skip to content

Tool Pick|dbmole-mcp — An MCP Server That Lets Agents Manage Their Own PostgreSQL/MySQL Connections

Oct 26, 20261 min
TL;DRdbmole-mcp is a PostgreSQL/MySQL MCP server that lets an agent manage its own connections. Install: `claude mcp add dbmole -- npx -y dbmole-mcp`. It solves the problem that most database MCP servers hard-code connections in a client config file an agent can't touch — adding or changing one means editing JSON by hand and restarting the client.

Look up & save

Loading dictionary…

🌏 中文版

Tool Info

ItemValue
Namedbmole-mcp
TypeMCP server (stdio)
GitHubed-smartass/dbmole-mcp
Stars1 (the GitHub mirror was created on 2026-10-25; the npm package is already at 0.2.0, so it clearly had a life on the author's own git server before going public)
LanguageTypeScript (Node.js ≥ 22)
LicenseMIT
Installclaude mcp add dbmole -- npx -y dbmole-mcp

What Problem It Solves

You ask an agent to check a table on staging, and most database MCP servers keep connection strings hard-coded in the client config — adding a new one means editing JSON by hand, typing in a password, and restarting the client. Switch to a different bastion host or a different read-only account, and you do it all again. The agent has no way to help, because "configure a connection" was never an MCP tool to begin with — it was always something you did yourself, by hand.

dbmole-mcp turns connection management itself into an MCP tool. Tell the agent "connect to the staging replica behind bastion.example.com, read-only," and it calls add_connection, which writes the entry into a .dbmole.json in the project directory (or the global ~/.config/dbmole/connections.json). Both files are re-read on every tool call, so an edit you make by hand, or one made from another session, takes effect on the very next call — no restart needed. A connection can carry an SSH tunnel (password, key, or agent auth, with the host key checked against known_hosts or a fingerprint you pin), and TLS with full certificate and hostname verification. readonly: true is enforced at the database-session level rather than by a SQL parser looking for keywords — PostgreSQL wraps the call in BEGIN READ ONLY, MySQL sets SET SESSION TRANSACTION READ ONLY. Every call also resets the session cleanly afterward (rolling back any open transaction, clearing temp tables and session variables), so nothing from one call carries into the next.

Good fit: an agent that needs to move between environments constantly — local, staging, a read-only production replica behind a bastion — without you editing a config file every time it switches. Also worth a look if you're thinking about how much control to hand an agent in the first place: dbmole-mcp lays connection management fully open as a tool surface, and its docs are unusually direct about the risk that comes with it (see Things to Watch For below).

Read-only enforcement and session reset in execute_sql
Read-only enforcement and session reset in execute_sqlEvery query first checks whether the connection is read-only; whatever happens next, the session is reset when the call finishes so nothing carries over to the next call. Call execute_sql connection name + SQL Is it readonly? this connection Wrap in READ ONLY enforced at session level Execute the statement capped by rowLimit / 40KB Did it succeed? execute_sql reports Return the result Return an error session resets either way yes no yes no
  1. Agent calls execute_sql with a connection name and SQL
  2. This connection is marked readonly
  3. Not read-only, proceed directly
  4. Wrap the call in BEGIN READ ONLY / SET SESSION TRANSACTION READ ONLY, then execute
  5. Success returns the result; failure returns an error — either way the session gets reset

Simplified; connection resolution (project file overrides the global store) and SSH tunnel setup are omitted.

Quick Start

Install

# Requires Node.js 22+; the server needs no connections configured to start
claude mcp add dbmole -- npx -y dbmole-mcp

# Also supports Codex, Cursor (one-click deeplink), VS Code, Claude Desktop (.mcpb file)
# and Docker — see the README's "Install" section for each

Basic Usage

Tell the agent, for example:

Add a read-only postgres connection called shop to this project: host 10.0.0.12, database shop, user reporter, through SSH to deploy@bastion.example.com using my SSH agent. Then show me the five largest tables.

The agent calls add_connection, then test_connection, list_tables, and execute_sql in turn:

{
  "name": "shop",
  "type": "postgres",
  "host": "10.0.0.12",
  "user": "reporter",
  "database": "shop",
  "readonly": true,
  "ssh": { "host": "bastion.example.com", "user": "deploy", "agent": true },
  "scope": "project"
}

Advanced Usage

# Pin the SSH host key so future connections skip known_hosts entirely
ssh-keyscan -p 22 bastion.example.com 2>/dev/null | ssh-keygen -lf -
# 256 SHA256:EXAMPLE... bastion.example.com (ED25519)
# Give the agent that SHA256:... value and ask it to call update_connection with ssh.hostKey
// When a project and global connection share a name, the project one wins —
// list_connections flags which entry gets shadowed
{
  "connections": [
    { "name": "shop", "type": "postgres", "host": "127.0.0.1", "user": "dev", "database": "shop" }
  ]
}

How It Compares

dbmole-mcpDBHubPostgres MCP Promcp-server-mysqlMCP Toolbox
PostgreSQL✅✅✅❌✅
MySQL✅✅❌✅✅
Other databases❌✅❌❌✅
Built-in SSH tunnel✅✅—✅❌
Agent adds/edits connections via tools✅❌ (maintainer has said it's not planned)❌❌❌
Index tuning❌—✅——
Health checks❌✅✅—✅ (prebuilt PostgreSQL tools)

(Table adapted from dbmole-mcp's own README comparison, checked October 2026; other projects may have shipped updates since — check their own docs.)

Things to Watch For

  • readonly is not a security boundary. The agent can call update_connection and turn it off itself — the README says so directly. For an actual guarantee, the database account itself needs no write, file, or administrative privileges.
  • Real gaps exist in what readonly protects. PostgreSQL's COPY ... TO PROGRAM / lo_export, writes through dblink, DML on temporary tables, and administrative statements like pg_terminate_backend / SET GLOBAL / KILL all fall outside what a "read-only transaction" covers.
  • Connection files store plaintext credentials (mode 0600, same as ~/.pgpass). Keep .dbmole.json out of version control. Worse: in a repo you've just cloned and haven't reviewed, if it already ships a .dbmole.json, dbmole trusts it as-is and may shadow your global connection, redirecting queries to a different host entirely — run list_connections before working in an unfamiliar repo.
  • While an SSH tunnel is open, any local process can connect through it on 127.0.0.1 with no extra authentication, including other users on a shared host. The database's own credentials are the last line of defense there.

Today's Takeaway

Most database MCP servers leave "how to configure a connection" outside the tool surface entirely, treating it as something the user is expected to handle beforehand. dbmole-mcp moves it inside the MCP tool layer — which removes the config-file-editing, client-restarting steps, but also turns connection management itself into a new attack surface. Whoever can call update_connection, or hand you a repo to clone that ships a malicious connection file, effectively gets access to the credentials — a completely different concern from read-only enforcement at the SQL layer. The maintainer lays out this threat model plainly in SECURITY.md, and that kind of candor — writing the convenience and the risk into the same document — isn't common among comparable tools.

References