dbmole-mcp

A monorepo of stdio MCP servers for databases, built on one shared connection core. Each server exposes named connections, optional SSH tunnels, and runtime connection management: you add, edit, and remove connections through MCP tools without restarting the harness. Both ship as an npx package and a Docker image, so they run anywhere your MCP client does.

Packages

Package Backend Install
dbmole-mcp PostgreSQL, MySQL npx -y dbmole-mcp
esmole-mcp Elasticsearch 7.x and 8.x npx -y esmole-mcp

Each package README documents its tools, connection fields, and Docker image in full. This page covers what the two servers share.

Quick start

Add either server — or both — to your client's .mcp.json:

{
    "mcpServers": {
        "dbmole": { "command": "npx", "args": ["-y", "dbmole-mcp"] },
        "esmole": { "command": "npx", "args": ["-y", "esmole-mcp"] }
    }
}

That is enough to start a server. With no connections configured it still runs; register one at runtime with add_connection, or supply connections up front through one of the sources below.

Shared design

Both servers inherit the same connection model from @dbmole/core.

Connection sources. Connections merge from three layers, highest priority first. The prefix is DBMOLE_ for dbmole and ESMOLE_ for esmole.

Priority Source How to set Mutable at runtime
High <PREFIX>_CONNECTIONS env JSON array of connection objects No (read-only)
Medium Config file --config <path> or <PREFIX>_CONFIG, shape { "connections": [...] } No (read-only)
Low Persistent store ~/.config/<server>/connections.json (mode 0600); override with <PREFIX>_STORE Yes (via tools)

Reads resolve name collisions by layer priority, and list_connections reports the source layer that won. The write tools — add_connection, update_connection, remove_connection — touch only the store layer; editing a connection from the env or a config file returns an error naming its source.

SSH tunnels. Any connection may carry an ssh block to reach a host through a bastion. Authentication accepts a password, a private key (inline or by path, with ~ expansion), or the SSH agent at SSH_AUTH_SOCK.

Readonly mode. A readonly: true connection blocks writes at the server, not by trusting the caller. dbmole pins read-only transactions; esmole enforces an HTTP method-and-path allowlist. Treat it as defence in depth — still connect with a least-privilege user for a hard guarantee.

Persistent store. The store is a plaintext JSON file written with 0600 permissions; whoever can read it owns the credentials in it. It is re-read on every operation, so instances sharing one store file see each other's changes at once. For secrets you do not want the tools to persist, prefer the env or config layer.

See each package README for the backend-specific tools, field reference, and defaults (ports, schemes, and so on).

Repository layout

packages/
  core/         @dbmole/core — shared Manager, registry, SSH tunnels, MCP plumbing (private)
  dbmole-mcp/   PostgreSQL and MySQL server
  esmole-mcp/   Elasticsearch server

@dbmole/core is private and never published. Each leaf package bundles it at build time, so the published artifacts have no @dbmole/core dependency.

Development

The repo is an npm workspace; run these from the root to cover every package:

npm run test:unit   # fast unit tests (mocked IO)
npm run test:int    # integration tests (needs Docker)
npm run coverage    # unit tests with coverage
npm run typecheck   # tsc across all packages
npm run lint        # Biome check
npm run build       # bundle each package to dist/

See AGENTS.md for the contributor style contract: code style, TypeScript discipline, testing rules, and commit conventions.

License

MIT

S
Description
MCP server for PostgreSQL and MySQL with named connections and SSH tunnels
Readme MIT
506 KiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 99.2%
Dockerfile 0.8%