Skip to main content
Glama
andychinghk01

db-query-mcp

db-query-mcp

A Model Context Protocol (MCP) server for running read-only SQL queries across multiple MySQL and PostgreSQL databases. Built with TypeScript, runnable with Node.js, Bun, or pnpm.

Give an AI assistant (Claude Desktop, Copilot, Cursor, Zed, or any MCP-compatible client) safe, read-only access to your databases β€” without pasting credentials into the chat.

Features

  • πŸ—„οΈ MySQL & PostgreSQL β€” mix both engines in one config

  • πŸ”’ Read-only by design β€” only SELECT/SHOW/DESCRIBE/DESC/EXPLAIN; DML/DDL keywords rejected

  • πŸ” Credentials out of source β€” connection config lives in ~/.config/db-query-mcp/config.json, never in the repo

  • ⏱️ Safety guardrails β€” automatic LIMIT, per-query timeout, parameterized queries

  • πŸ“¦ Installable β€” npx, pnpm dlx, bunx, or global install; one binary, no source editing

  • 🧩 Single config, many databases β€” each connection can expose multiple databases

Related MCP server: mysql-mcp

Requirements

  • Node.js β‰₯ 20, Bun, or pnpm (any one)

Install

npx db-query-mcp
# or
pnpm dlx db-query-mcp
# or
bunx db-query-mcp

Install globally

npm install -g db-query-mcp
# or
pnpm add -g db-query-mcp

Then run db-query-mcp directly.

From source

git clone https://github.com/andychinghk01/db-query-mcp.git
cd db-query-mcp
pnpm install
pnpm build
node dist/index.js

Configuration

db-query-mcp reads connections from a JSON config file.

Path (first match wins):

  1. DB_QUERY_MCP_CONFIG env var (absolute path)

  2. ~/.config/db-query-mcp/config.json

Create the config

mkdir -p ~/.config/db-query-mcp
cp examples/config.example.json ~/.config/db-query-mcp/config.json
# edit with your real credentials
$EDITOR ~/.config/db-query-mcp/config.json

Schema

{
  "queryTimeoutMs": 30000,   // optional, default 30000
  "defaultRowLimit": 1000,   // optional, default 1000
  "connections": [
    {
      "name": "unique-connection-id",      // shown in list_db
      "description": "Human-readable note",
      "type": "mysql",                      // "mysql" | "postgresql"; defaults to "mysql"
      "host": "db.example.com",
      "port": 3306,
      "username": "readonly-user",
      "password": "your-password",
      "databases": [
        { "name": "actual_db_name", "description": "What this DB contains" }
      ]
    }
  ]
}

Field

Type

Required

Notes

connections

array

yes

One entry per server you connect to

connections[].type

"mysql" | "postgresql"

no

Defaults to "mysql"

connections[].databases

array

yes

Each becomes a queryable target in list_db

queryTimeoutMs

number

no

Per-query timeout, default 30000

defaultRowLimit

number

no

Max rows returned, default 1000

πŸ’‘ Use a dedicated read-only database user. The server enforces read-only SQL, but defense in depth matters β€” grant only SELECT (and SHOW/EXPLAIN where needed) to the user in this config.

MCP client configuration

Add the server to your MCP client config.

Claude Desktop / Claude Code (claude_desktop_config.json or .mcp.json)

{
  "mcpServers": {
    "db-query-mcp": {
      "command": "npx",
      "args": ["db-query-mcp"]
    }
  }
}

With Bun

{
  "mcpServers": {
    "db-query-mcp": {
      "command": "bunx",
      "args": ["db-query-mcp"]
    }
  }
}

With pnpm

{
  "mcpServers": {
    "db-query-mcp": {
      "command": "pnpm",
      "args": ["dlx", "db-query-mcp"]
    }
  }
}

Custom config path

{
  "mcpServers": {
    "db-query-mcp": {
      "command": "npx",
      "args": ["db-query-mcp"],
      "env": { "DB_QUERY_MCP_CONFIG": "/custom/path/config.json" }
    }
  }
}

Tools

list_db

Lists every configured database with its connection name, engine type, host, port, and description. No arguments.

query

Executes a read-only query.

Argument

Type

Required

Description

dbName

string

yes

Database name from list_db

sql

string

yes

Read-only SQL statement

params

array

no

Positional parameters β€” ? for MySQL, $1, $2, ... for PostgreSQL

Safety guardrails

  • Statement allowlist β€” only SELECT, SHOW, DESCRIBE, DESC, EXPLAIN may start a query.

  • Keyword denylist β€” INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, TRUNCATE, REPLACE, MERGE, CALL, EXEC, GRANT, REVOKE, LOCK, UNLOCK, LOAD DATA are rejected anywhere in the statement (after comment/quote normalization).

  • Row limit β€” SELECTs are wrapped as subselects and capped at defaultRowLimit (default 1000).

  • Timeout β€” queries abort after queryTimeoutMs (default 30s).

  • Parameterized queries β€” use ? (MySQL) or $1 (Postgres) placeholders; values never interpolated into SQL.

These guardrails reduce risk but are not a substitute for least-privilege database permissions. Always pair this server with a read-only DB user.

Development

pnpm install
pnpm build      # tsc -> dist/
pnpm dev        # watch mode
pnpm start      # node dist/index.js
pnpm start:bun  # bun dist/index.js

License

MIT Β© Andy Ching

Available Tools

2 tools
list_dbA

List configured MySQL and PostgreSQL databases with their names, types, and descriptions.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. The verb 'List' implies a safe, read-only operation, but the description does not explicitly state side effects, permission requirements, or any operational constraints. It provides minimal behavioral context beyond the basic function, which is adequate but not comprehensive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence that immediately states the action and key output details. It contains no fluff or redundant information, making it highly concise and well-structured for quick agent reading.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is very simple (no parameters, no output schema), and the description covers the core operation and output. It does not mention return value format or any limitations, but given the low complexity, the description is largely sufficient. Sibling differentiation is minimal, slightly reducing completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description need not explain parameter semantics, and the input schema (empty) confirms that no parameters exist. The description adds no unnecessary param details, which is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function with a specific verb ('List') and resource ('configured MySQL and PostgreSQL databases'), and specifies the output fields (names, types, descriptions). This distinguishes it from the sibling tool 'query', which likely executes queries rather than enumerating databases.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage: use this tool to see available databases. However, it does not explicitly mention when not to use it or contrast with the sibling 'query' tool. There is no direct guidance on alternative tools, so it falls short of a clear 'when to use vs alternatives' explanation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

queryA

Execute a read-only SELECT query against a selected MySQL or PostgreSQL database. Supports optional parameterized values. Only SELECT/SHOW/DESCRIBE/EXPLAIN statements are allowed.

ParametersJSON Schema
NameRequiredDescriptionDefault
sqlYesA read-only SQL SELECT statement.
dbNameYesThe name of the database to query (as shown by list_db).
paramsNoOptional positional parameters for the SQL statement. Use ? placeholders for MySQL or $1, $2, ... for PostgreSQL.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, but the description carries the burden by specifying the tool is read-only and enumerating allowed statement types (SELECT/SHOW/DESCRIBE/EXPLAIN). It also mentions parameterized values with placeholder syntax for MySQL/PostgreSQL, giving useful behavioral context. It doesn't describe output format, but for a query tool this is sufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core purpose, and no redundant information. Every sentence contributes meaning, making it an efficient description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the key aspects for a moderate-complexity tool: read-only constraint, allowed statements, and parameterization. It lacks an explicit mention of the result format, but given no output schema and the straightforward nature of a query tool, it is sufficiently complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, with parameter descriptions already documenting sql, dbName, and params. The description additionally reinforces the read-only constraint and clarifies that dbName is as shown by list_db, but doesn't add significant new semantics beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool executes read-only SQL queries (SELECT/SHOW/DESCRIBE/EXPLAIN) against a MySQL/PostgreSQL database, using a specific verb and resource. It distinguishes itself from sibling list_db, which lists databases, by focusing on query execution.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly implies usage for read-only querying against a chosen database, referencing list_db for database selection. However, it doesn't explicitly state 'use this instead of list_db when you need to retrieve data,' making it a clear context but without explicit exclusionary guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv1.0.0
    • First observedlist_db
    • First observedquery

TDQS

A4.2/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct roles: list_db for discovery and query for executing SQL. There is no overlap in their purposes or outputs.

Naming Consistency4/5

Both tools use a verb-first pattern, but list_db is verb_noun while query is just a verb. This is a minor deviation and still predictable.

Tool Count3/5

With only 2 tools, the set feels thin, though each earns its place for the stated read-only query purpose. The count is at the lower boundary of typical MCP servers.

Completeness5/5

The tool surface fully covers the domain of read-only database querying: listing available databases and executing arbitrary SELECT/SHOW/DESCRIBE/EXPLAIN statements. No critical gaps exist.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A production-ready MCP server that enables safe, read-only SQL SELECT queries against PostgreSQL databases with built-in security validation. It features connection pooling, automatic row limits, and structured logging to ensure secure and reliable database interactions.
    47 npm
    ISC
  • A
    license
    Not graded
    quality
    D
    maintenance
    A lightweight MCP server providing safe, read-only access to MySQL databases. It enables users to query multiple MySQL instances securely while preventing write operations.
    633 npm
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Read-only MCP server for SQL databases (SQL Server, Postgres, SQLite) with multi-server support and three-layer safety using AST validation and linting.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Read-only MCP server for SQL databases (SQLite/PostgreSQL) that enables listing tables, describing schemas, and executing SELECT queries with safety guardrails.
    MIT