Skip to main content
Glama
sijunkim

DB Gateway MCP Server

by sijunkim
README.md
# DB Gateway MCP Server

[![npm](https://img.shields.io/npm/v/db-gateway)](https://www.npmjs.com/package/db-gateway)
[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-listed-6E56CF)](https://registry.modelcontextprotocol.io/?search=db-gateway)
[![8 databases](https://img.shields.io/badge/8%20databases-145%2B%20tools-0A7EA4)](https://github.com/sijunkim/db-gateway/blob/main/docs/TOOLS.md)
[![license](https://img.shields.io/npm/l/db-gateway)](https://github.com/sijunkim/db-gateway/blob/main/LICENSE)

English | [한국어](https://github.com/sijunkim/db-gateway/blob/main/README_KR.md)

An MCP server that gives AI agents direct access to your databases — 145+ tools across 8 engines.

The point is that the agent reads your schema itself instead of you pasting DDL into a prompt:

```
You: "Find users who signed up last month and never placed an order"

  1. mysql_get_all_schemas          → reads every table definition
  2. mysql_get_table_relationships  → finds the users ↔ orders foreign key
  3. mysql_execute_query            → runs the LEFT JOIN
```

## Why db-gateway?

Most database MCP servers cover one engine, or a handful of relational ones. If your stack is MySQL for the app, Redshift for analytics, Redis for cache, and Kafka for events, that means four servers with four different config styles.

This is one server, one config block:

| | Engines | Tools |
| :--- | :--- | ---: |
| **Relational** | MySQL, PostgreSQL, Redshift | 59 |
| **NoSQL** | MongoDB, Redis, DynamoDB | 48 |
| **Search** | Elasticsearch | 19 |
| **Streaming** | Kafka | 19 |

`DBS` decides which of them are enabled — only those tools get registered, so a MySQL-only setup stays a MySQL-only tool list.

## See It Work

Every screenshot below is one real session against a development MySQL database holding 249 rows — unedited output, not mock data. The agent calls a single tool, `mysql_execute_query`, and never sees a host, port, or password: those stay in the client config, and the agent only ever names the `alias`.

![Step 1 — READ: query the most recently added item](https://raw.githubusercontent.com/sijunkim/db-gateway/main/docs/images/step-1-read.png)

![Step 2 — CREATE: insert a new item, and MySQL returns its insertId](https://raw.githubusercontent.com/sijunkim/db-gateway/main/docs/images/step-2-create.png)

![Step 3 — UPDATE: move it to the freezer, matching exactly one row by primary key](https://raw.githubusercontent.com/sijunkim/db-gateway/main/docs/images/step-3-update.png)

![Step 4 — DELETE: remove that row by primary key](https://raw.githubusercontent.com/sijunkim/db-gateway/main/docs/images/step-4-delete.png)

![Step 5 — VERIFY: the table is back to its original 249 rows](https://raw.githubusercontent.com/sijunkim/db-gateway/main/docs/images/step-5-verify.png)

Point the same server at production with `READ_ONLY=true` and steps 2 through 4 simply do not exist — the write tools are never registered, so the agent cannot see them to call them.

## Quick Start

Requires Node.js 18+. Register it with your MCP client — no install step:

```json
{
  "mcpServers": {
    "db-gateway": {
      "command": "npx",
      "args": ["-y", "db-gateway"],
      "env": {
        "DBS": "mysql,redis",
        "MYSQL": "mysql://<user>:<password>@<host>:3306/<database>?alias=dev&default=true",
        "REDIS": "redis://:@<host>:6379/0?alias=dev&default=true"
      }
    }
  }
}
```

`DBS` decides which engines are enabled — only those tools get registered.

### Connection strings

One string per engine. Semicolons separate multiple instances.

| Variable | Format |
| :--- | :--- |
| `MYSQL` | `mysql://<user>:<password>@<host>:<port>/<db>?alias=name` |
| `POSTGRESQL` | `postgresql://<user>:<password>@<host>:<port>/<db>?alias=name&ssl=true` |
| `REDIS` | `redis://:<password>@<host>:<port>/<db-index>?alias=name` |
| `MONGODB` | `mongodb://<user>:<password>@<host>:<port>/<db>?alias=name` |
| `REDSHIFT` | `redshift://<user>:<password>@<host>:<port>/<db>?alias=name&ssl=true` |
| `ELASTICSEARCH` | `elasticsearch://<user>:<password>@<host>:<port>?alias=name`, or `http(s)://<host>:<port>?alias=name` |
| `KAFKA` | `kafka://<user>:<password>@<broker>:<port>,<broker2>:<port>?alias=name&mechanism=plain` |

> **`alias` is required.** It is how tools address a specific instance — omit it and that engine fails to connect.

**Several instances of the same engine** — separate their connection strings with a semicolon. The agent picks one by passing an `alias` argument to any tool; `default=true` marks the one used when no alias is given:

```env
MYSQL="mysql://<user>:<password>@<dev-host>:3306/<db>?alias=dev&default=true;mysql://<user>:<password>@<prod-host>:3306/<db>?alias=prod"
```

DynamoDB is the exception — it takes `DYNAMODB_REGION`, `DYNAMODB_ACCESS_KEY_ID`, and `DYNAMODB_SECRET_ACCESS_KEY` instead. See [`.env.example`](https://github.com/sijunkim/db-gateway/blob/main/.env.example) for every option.

## Read-Only Mode

`READ_ONLY=true` hides write tools from the tool list entirely and restricts `*_execute_query` to SELECT-style statements.

Register production as a second MCP server with this flag on. The agent then cannot modify production data — the write tools do not exist as far as it can see.

```json
"db-gateway-prod": {
  "command": "npx",
  "args": ["-y", "db-gateway"],
  "env": { "READ_ONLY": "true", "DBS": "mysql", "MYSQL": "..." }
}
```

## Documentation

- **[Tool Reference](https://github.com/sijunkim/db-gateway/blob/main/docs/TOOLS.md)** — all 145+ tools, by engine
- **[Connection Management](https://github.com/sijunkim/db-gateway/blob/main/docs/CONNECTIONS.md)** — pooling, health checks, and why `connectionLimit` multiplies per session
- **[Deployment](https://github.com/sijunkim/db-gateway/blob/main/docs/DEPLOYMENT.md)** — SSE mode, Nginx, PM2, sharing one gateway across a team

## License

MIT

TDQS

A3.5/5.0

Scored across 17 tools

Disambiguation4/5

Most tools target distinct MySQL operations (e.g., show_tables vs. list_databases vs. get_schema). A few pairs like execute_query/execute_batch and describe_table/get_schema overlap in purpose, but descriptions clarify the differences.

Naming Consistency5/5

All tools follow a consistent 'mysql_<verb>_<noun>' pattern (e.g., mysql_show_tables, mysql_execute_query, mysql_kill_process). This makes the set predictable and easy to navigate.

Tool Count4/5

At 17 tools, the server is slightly larger than the ideal 3-15 range but remains well-scoped for a MySQL gateway. Each tool addresses a specific operational need without redundancy.

Completeness4/5

The set covers core database operations: schema inspection, query execution, process management, and table relationships. While explicit CRUD or transaction tools are absent, mysql_execute_query and mysql_execute_batch provide a flexible escape hatch for any SQL operation.

Maintenance

ActivitySlowing
ResponsivenessNo issues