Skip to main content
Glama
mahAnuj

mcp-multi-db

by mahAnuj

mcp-multi-db

npm version npm downloads license mcp-multi-db MCP server

One MCP server for all your SQL databases — read-only and safe by default.

mcp-multi-db MCP server card

Connect an AI agent to PostgreSQL, MySQL, and SQLite at the same time through a single Model Context Protocol server. List your databases in one config file and the agent picks which one to query by database_id. Every query is enforced read-only at the database level, so it's safe to point at real data.

  • Multi-engine, one server — Postgres, MySQL, and SQLite side by side; no separate server per database.

  • Read-only & safe by default — two-layer enforcement (SQL-text guard + database-level read-only transactions) plus row limits and query timeouts. See SECURITY.md.

  • Schema-aware — the agent can discover databases, tables/views, and column metadata before it writes a query.

  • Zero query language to learn — just ask in natural language.

Demo: the MCP server listing databases, inspecting schema, running a read-only query, and refusing a write

The clip drives the real server over stdio (via the MCP SDK) against a seeded SQLite database. Regenerate it with npm run build && vhs examples/demo.tape.

Tools

Tool

Description

list_databases

List configured database connections

list_tables

List tables/views in a database

describe_table

Show column metadata for a table

run_query

Run read-only SQL (SELECT, WITH, EXPLAIN)

Related MCP server: dbridge-mcp

Quick start

No install needed — npx fetches the package on first use.

1. Create databases.json

Copy the example and edit with your connection details:

cp databases.example.json databases.json
{
  "databases": [
    {
      "id": "local-sqlite",
      "type": "sqlite",
      "path": "/absolute/path/to/app.db",
      "label": "Local dev SQLite"
    },
    {
      "id": "analytics-pg",
      "type": "postgres",
      "connectionString": "postgresql://user:pass@localhost:5432/analytics",
      "label": "Analytics Warehouse"
    },
    {
      "id": "reporting-mysql",
      "type": "mysql",
      "connectionString": "mysql://user:pass@localhost:3306/reporting",
      "label": "Reporting MySQL"
    }
  ]
}

Never commit databases.json — it contains credentials. It's already gitignored if you cloned the repo. Prefer read-only database users (see Security).

2. Register the server with your MCP client

The server speaks MCP over stdio, so it works with any MCP-capable client. Use npx mcp-multi-db as the command and pass MCP_DB_CONFIG (the path to your databases.json). See mcp.example.json and databases.example.json for templates.

Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "mcp-multi-db": {
      "command": "npx",
      "args": ["-y", "mcp-multi-db"],
      "env": {
        "MCP_DB_CONFIG": "/absolute/path/to/databases.json"
      }
    }
  }
}

Restart Claude Desktop afterward.

claude mcp add mcp-multi-db \
  --env MCP_DB_CONFIG=/absolute/path/to/databases.json \
  -- npx -y mcp-multi-db

Add to ~/.cursor/mcp.json (or .cursor/mcp.json in your project), then open Cursor Settings → Tools & MCP, restart the server, and use Agent mode:

{
  "mcpServers": {
    "mcp-multi-db": {
      "command": "npx",
      "args": ["-y", "mcp-multi-db"],
      "env": {
        "MCP_DB_CONFIG": "/absolute/path/to/databases.json"
      }
    }
  }
}

Any client that supports stdio MCP servers uses the same shape: command npx, args ["-y", "mcp-multi-db"], and env MCP_DB_CONFIG pointing at your databases.json. Consult your client's docs for where its MCP config lives.

Prefer a pinned global install? npm install -g mcp-multi-db, then use command mcp-multi-db with no args.

Configuration reference

Config is loaded from one of two environment variables, in order:

  1. MCP_DB_CONFIG — path to a JSON file (recommended).

  2. MCP_DATABASES — inline JSON (useful when a file path is awkward).

The JSON may be either { "databases": [ ... ] } or a bare array. Each entry:

Field

Required

Notes

id

yes

Unique; the agent references this as database_id

type

yes

postgres | mysql | sqlite

connectionString

postgres/mysql

Standard connection URI

path

sqlite

Absolute path to the .db file

label

no

Human-friendly name shown to the agent

description

no

Extra context shown to the agent

Example prompts

  • "List my configured databases"

  • "What tables are in local-sqlite?"

  • "Describe the users table in analytics-pg"

  • "Run SELECT COUNT(*) FROM orders on reporting-mysql"

Security

  • Read-only only. INSERT, UPDATE, DELETE, DDL, etc. are blocked — both by a SQL-text guard and by running each query inside a database-level read-only transaction (SQLite opens read-only). A SELECT that calls a side-effecting function is still refused.

  • Row limits. Results are capped (default 100, max 1000).

  • Query timeouts. Statements are bounded (30s) to avoid runaway queries.

  • Use least privilege anyway. Prefer dedicated read-only DB users and read replicas. Full details and reporting in SECURITY.md.

Docker

A multi-stage Dockerfile is included. Build and run with your databases.json mounted in:

docker build -t mcp-multi-db .

docker run --rm -i \
  -v /absolute/path/to/databases.json:/config/databases.json:ro \
  mcp-multi-db

The image runs as a non-root user, ships only the built JS and runtime node_modules (no toolchain), and speaks MCP over stdio just like the npx install — so it slots into any MCP client by replacing the command and args with the appropriate docker run -i invocation.

Development

npm install
npm run build     # tsc -> build/, the artifact MCP clients run
npm test          # builds, then runs the node:test suite

Tests use Node's built-in test runner (no extra dependencies) and cover the read-only SQL guard and the SQLite adapter end to end. CI runs build + tests on every push and pull request.

Adding another database engine is a contained change: add the config variant in src/config.ts, implement the SqlDatabasePort interface in a new adapter under src/adapters/, and register it in the adapter factory. New adapters must enforce read-only at the connection level — not rely on the text guard alone. See docs/extending.md for the full checklist.

Documentation

  • Architecture — components, request lifecycle, and the port-family design (with diagrams).

  • Extending — add a SQL engine or a non-SQL family.

  • Security — the two-layer read-only model and safe deployment.

The full index is in docs/.

Contributing

Issues and pull requests are welcome — see CONTRIBUTING.md for setup, the read-only invariants, and how to add a database engine.

License

ISC — see LICENSE.

Available Tools

4 tools
describe_tableA

Describe columns for a table in a configured database.

ParametersJSON Schema
NameRequiredDescriptionDefault
database_idYesDatabase id from list_databases
tableYesTable name
schemaNoSchema name (Postgres/MySQL). Ignored for SQLite.

TDQS

A3.5/5.0
Behavior2/5

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

No annotations are provided, so the description bears full responsibility for behavioral disclosure. It only states 'describe columns' with no mention of side effects, permissions, error handling, or return format, leaving significant gaps for a read-like operation.

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 concise sentence with no wasted words, front-loading the core action and target.

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

Completeness3/5

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

Given the absence of an output schema and low complexity, the description adequately identifies the tool's purpose but lacks details about what the tool returns (e.g., column names, types), which would improve completeness.

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%, so the input schema already documents each parameter with descriptions. The tool description adds no additional meaning beyond the schema, meeting the baseline expectation.

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 action ('describe columns') and the resource ('table in a configured database'), distinguishing it from sibling tools like list_databases (list databases), list_tables (list tables), and run_query (execute arbitrary SQL).

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 when column details of a specific table are needed, but provides no explicit guidance on when to prefer this tool over alternatives like run_query, nor any 'when not to use' scenarios.

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

list_databasesA

List all configured database connections (id, type, label, description). Call this first to discover which database_id to use.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior3/5

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

No annotations exist, so description carries full burden. It describes a simple list operation (read-only) but does not explicitly state safety or idempotency. However, for a 0-param list tool, the default assumption of no side effects is reasonable.

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?

Single sentence front-loads action and output fields, with no wasted words. Efficient and clear.

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

Completeness5/5

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

For a 0-param discovery tool with no output schema, the description sufficiently covers what it returns and why to call it. No gaps.

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?

No parameters in schema, so schema coverage is 100%. The description adds value by listing returned fields and explaining purpose, making it a baseline 4.

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 uses a specific verb 'List' and resource 'all configured database connections' with fields (id, type, label, description). It clearly differentiates from sibling tools like list_tables and describe_table by indicating this is the first call to discover database_id.

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

Usage Guidelines5/5

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

Explicitly states 'Call this first to discover which database_id to use', providing clear when-to-use guidance and implying it is a prerequisite for other tools.

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

list_tablesB

List tables and views in a configured database.

ParametersJSON Schema
NameRequiredDescriptionDefault
database_idYesDatabase id from list_databases
schemaNoSchema name (Postgres/MySQL). Ignored for SQLite.

TDQS

B3.3/5.0
Behavior2/5

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

No annotations provided, but description does not disclose behavioral traits like read-only nature, authentication needs, or side effects. Minimal information beyond the basic action.

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

Conciseness4/5

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

Single sentence is concise and front-loaded with key verb and object. No wasted words, but could be more structured.

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

Completeness2/5

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

No output schema; description does not explain return format (e.g., array of names). Parameters are covered, but the result is missing, making it incomplete for a listing tool.

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 descriptions for both 'database_id' and 'schema'. Description adds no additional meaning beyond what schema already provides, so 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?

Description clearly states verb 'List', resource 'tables and views', and context 'in a configured database'. This distinguishes it from siblings like 'describe_table' (which describes a specific table) and 'list_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?

Implied usage: use after selecting a database. No explicit when-to-use, when-not-to-use, or alternatives beyond sibling names.

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

run_queryA

Execute a read-only SQL query (SELECT, WITH, EXPLAIN) on a configured database. Writes are blocked.

ParametersJSON Schema
NameRequiredDescriptionDefault
database_idYesDatabase id from list_databases
sqlYesRead-only SQL query
limitNoMax rows to return (default 100, max 1000)

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description must disclose behavior. It clearly states the tool is read-only and blocks writes, a critical safety trait. It does not mention return format or error handling, but for a simple 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?

The description is a single sentence with no redundant information. It front-loads the key action and constraint, earning its place.

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?

Given the tool's simplicity, high schema coverage, and absence of output schema, the description is mostly complete. It could mention the result format (e.g., JSON array) but omission is minor.

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%, so the description adds no extra semantic meaning beyond the schema definitions for database_id, sql, and limit. It does not explain parameter interdependencies or formatting rules.

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 verb 'Execute' and the resource 'read-only SQL query on a configured database'. It also explicitly blocks writes, distinguishing it from siblings like describe_table and list_databases which provide metadata.

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?

The description provides clear context by specifying allowed SQL commands (SELECT, WITH, EXPLAIN) and forbidding writes. It does not explicitly list alternative tools for non-query needs, but the sibling list implies usage boundaries.

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. Dates show when Glama detected each change.

  1. 4 tool updatesv1.0.2
    • First observeddescribe_table
    • First observedlist_databases
    • First observedlist_tables
    • First observedrun_query

TDQS

A4/5.0
Disambiguation5/5

Each tool has a distinct purpose: describing a table's schema, listing database connections, listing tables in a database, and executing read-only queries. No overlap between tools.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in lower_snake_case (describe_table, list_databases, list_tables, run_query). Perfectly uniform.

Tool Count5/5

With 4 tools, the server covers essential database exploration tasks without being bloated or too sparse. The count is appropriate for a read-only multi-database interface.

Completeness4/5

The set covers discovering databases, listing tables, describing schemas, and running SELECT queries. Missing are write operations, but they are intentionally blocked. A minor gap is lack of a tool to view recent queries or metadata beyond column types, but core workflow is solid.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Read-only MCP server that lets AI agents safely query SQLite, PostgreSQL, and MySQL/MariaDB. Enforces read-only transactions with column masking, row caps, query timeouts, EXPLAIN-based cost rejection, and rate limiting.
    7
    49
    1
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    A small MCP server that lets an LLM query PostgreSQL, MySQL, MariaDB, SQL Server, or SQLite databases safely — read-only, role-restricted, and with sensitive data blacked out.
    -
  • 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

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mahAnuj/mcp-multi-db'

If you have feedback or need assistance with the MCP directory API, please join our Discord server