Skip to main content
Glama
FQXCS
by FQXCS
README.md
<div align="center">
<strong>
    <h1>db-mcp</h1>
    HighGo & MySQL database MCP server<br><br>
    Query · Execute · DDL · List tables · Inspect schema<br>
    Permission-controlled · stdio transport · Single-file build
</strong>
<br>
<br>

[![GitHub](https://img.shields.io/badge/GitHub-Repository-black?style=flat-square&logo=github)](https://github.com/FQXCS/db-mcp)
[![Stars](https://img.shields.io/github/stars/FQXCS/db-mcp?style=flat-square)](https://github.com/FQXCS/db-mcp/stargazers)
[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE)
[![简体中文](https://img.shields.io/badge/简体中文-README-green?style=flat-square)](README.zh.md)

</div>

**db-mcp** is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that exposes database operations for **HighGo (瀚高)** and **MySQL** databases as MCP tools. AI assistants such as OpenCode and Claude Code can query, modify, and inspect databases through a permission-controlled, stdio-based interface.

## Features

- **Two database types**: HighGo (PostgreSQL-compatible) and MySQL, selected via configuration
- **Five MCP tools**: query, execute, DDL, list tables, and describe table
- **Fine-grained permissions**: per-operation allowlist (`SELECT` / `INSERT` / `UPDATE` / `DELETE` / `DDL`)
- **Flexible configuration**: environment variables or a JSON config file (env vars take precedence), with `${ENV_VAR}` placeholder support in config files
- **Connection pooling**: configurable pool size per connection
- **Single-file build**: `build:prod` bundles everything into one self-contained `dist/index.js` — no `node_modules` needed at runtime

## Requirements

- Node.js >= 18

## Quick Start

```bash
npm install
npm run build:prod
```

`npm run build:prod` runs `tsc` and then bundles the output with `esbuild` into a single file:

```
dist/
└── index.js    # self-contained, run directly with node
```

> Note: `npm run build` (tsc only) also compiles to `dist/`, but that output still requires `node_modules/` at runtime. Use `build:prod` for a portable single-file build.

Run the server (it speaks MCP over stdio, so it is normally launched by an MCP client, not run interactively):

```bash
node dist/index.js
```

## Configuration

Two ways to configure a connection; **environment variables take precedence** over the config file.

### Option 1: Environment variables

| Variable | Required | Default | Description |
|---|---|---|---|
| `DB_HOST` | yes | — | Database host |
| `DB_DATABASE` | yes | — | Database name |
| `DB_USERNAME` | yes | — | Username |
| `DB_PASSWORD` | yes | — | Password |
| `DB_TYPE` | no | `highgo` | `highgo` or `mysql` |
| `DB_PORT` | no | `5866` / `3306` | Auto-selected per type when omitted |
| `DB_PERMISSIONS` | no | all | Comma-separated, e.g. `SELECT,INSERT,DDL` |
| `DB_POOL_MAX` | no | `10` | Max pool size |

```bash
DB_HOST=127.0.0.1 DB_PORT=5866 DB_DATABASE=mydb DB_USERNAME=admin DB_PASSWORD=xxx node dist/index.js
```

### Option 2: Config file

The server loads `./db-mcp-config.mysql.example.json` from the current working directory by default. Copy one of the examples from [`config/`](config/) and point `DB_MCP_CONFIG` at it:

```bash
# e.g. on Windows
set DB_MCP_CONFIG=D:\path\to\db-mcp\config\db-mcp-config.highgo.example.json
node dist/index.js
```

Or place a config file named `db-mcp-config.mysql.example.json` in the working directory (the default path).

Example config:

```json
{
  "name": "highgo-dev",
  "type": "highgo",
  "host": "127.0.0.1",
  "port": 5866,
  "database": "your_database",
  "username": "your_username",
  "password": "your_password",
  "pool": { "max": 10 },
  "permissions": ["SELECT", "INSERT", "UPDATE", "DELETE", "DDL"]
}
```

Config file fields: `name`, `type` (`highgo` | `mysql`), `host`, `port`, `database`, `username`, `password`, `pool.max`, `permissions`. Values may reference environment variables with `${ENV_VAR}` syntax, e.g. `"password": "${DB_PASSWORD}"`.

> ⚠️ The config file contains database credentials — never commit real values to git. The shipped examples under `config/` only contain placeholders.

## Connecting an MCP Client

### OpenCode

Add the server to the `mcp` field of `opencode.json` (project root) or your global config:

**Via environment variables:**

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "db-mcp": {
      "type": "local",
      "command": ["node", "/path/to/db-mcp/dist/index.js"],
      "enabled": true,
      "environment": {
        "DB_TYPE": "highgo",
        "DB_HOST": "127.0.0.1",
        "DB_PORT": "5866",
        "DB_DATABASE": "your_database",
        "DB_USERNAME": "your_username",
        "DB_PASSWORD": "your_password",
        "DB_PERMISSIONS": "SELECT,INSERT,UPDATE,DELETE,DDL"
      }
    }
  }
}
```

**Via config file:**

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "db-mcp": {
      "type": "local",
      "command": ["node", "/path/to/db-mcp/dist/index.js"],
      "enabled": true,
      "environment": {
        "DB_MCP_CONFIG": "/path/to/db-mcp/config/db-mcp-config.mysql.example.json"
      }
    }
  }
}
```

**Or add it interactively with the CLI:**

```bash
opencode mcp add
```

OpenCode walks you through the setup step by step:

1. Run `opencode mcp add` — an interactive prompt opens.
2. Select **local** as the server type.
3. Give the server a name, e.g. `db-mcp`.
4. Enter the command: `node /path/to/db-mcp/dist/index.js`.
5. Add the environment variables when prompted (`DB_TYPE`, `DB_HOST`, ... or `DB_MCP_CONFIG`).
6. Verify the server is connected with `opencode mcp list`.

If the server is slow to start up, raise the tool-fetch timeout with `"timeout": 10000` (defaults to 5000 ms).

### Codex

MCP servers are configured in `~/.codex/config.toml` under the `[mcp_servers]` section. Add the server with the Codex CLI:

```bash
codex mcp add db-mcp --env DB_MCP_CONFIG=/path/to/db-mcp/config/db-mcp-config.mysql.example.json -- node /path/to/db-mcp/dist/index.js
```

Or edit `~/.codex/config.toml` directly:

```toml
[mcp_servers.db-mcp]
command = "node"
args = ["/path/to/db-mcp/dist/index.js"]
enabled = true

[mcp_servers.db-mcp.env]
DB_MCP_CONFIG = "/path/to/db-mcp/config/db-mcp-config.mysql.example.json"
```

To connect via environment variables instead, list them in the `env` table (see [Option 1](#option-1-environment-variables)).

### Claude Code

Add the server with the Claude Code CLI (saved to `~/.claude/settings.json` by default; pass `--scope project` to save it to `.mcp.json` in the project root instead):

```bash
claude mcp add -e DB_MCP_CONFIG=/path/to/db-mcp/config/db-mcp-config.mysql.example.json db-mcp -- node /path/to/db-mcp/dist/index.js
```

Or edit `.mcp.json` (project scope) or `~/.claude/settings.json` (user scope) directly:

```json
{
  "mcpServers": {
    "db-mcp": {
      "type": "stdio",
      "command": "node",
      "args": ["/path/to/db-mcp/dist/index.js"],
      "env": {
        "DB_MCP_CONFIG": "/path/to/db-mcp/config/db-mcp-config.mysql.example.json"
      }
    }
  }
}
```

## Tools

| Tool | Description | Risk |
|---|---|---|
| `db_query` | Execute a SELECT query; returns column names and data rows | Read-only |
| `db_execute` | Execute INSERT / UPDATE / DELETE; returns affected row count | Write |
| `db_ddl` | Execute DDL statements (CREATE / ALTER / DROP / indexes, etc.) | Write |
| `db_list_tables` | List all tables in the current database | Read-only |
| `db_describe_table` | Inspect a table's structure (columns, types, primary key, etc.) | Read-only |

## Permission Control

Every connection carries a `permissions` allowlist. Requests are rejected with an error when the required permission is missing:

- `db_query` / `db_list_tables` / `db_describe_table` require `SELECT`
- `db_execute` checks the statement prefix and requires `INSERT`, `UPDATE`, or `DELETE` accordingly
- `db_ddl` requires `DDL`

To restrict a connection, set `DB_PERMISSIONS` (comma-separated) or the `permissions` array in the config file. Restrictive example: `SELECT,DDL` allows reads and schema changes but no DML writes.

## Project Structure

```
src/
├── index.ts                    # MCP server entry: tool registration + stdio transport
├── config.ts                   # config loading, permission checks, SQL validation
├── types.ts                    # shared types (ConnectionConfig, QueryResult, ...)
└── clients/
    ├── highgo-client.ts        # HighGo client implementation
    └── mysql-client.ts         # MySQL client implementation
config/
├── db-mcp-config.highgo.example.json
└── db-mcp-config.mysql.example.json
highgodb/                       # vendored HighGo database driver (based on pg), installed via file: dependency
```

## Development

```bash
npm install
npm run dev        # watch mode via tsx (src/index.ts)
npm run build      # tsc compile only
npm run build:prod # tsc + esbuild single-file bundle
```

## Security Notes

- The server executes arbitrary SQL within the granted permissions — run it with the least-privileged database account your use case allows.
- The MCP transport is stdio and does not enforce authentication on its own; control access to the machine/process that hosts it.
- Read-only tools are marked with `readOnlyHint` so clients can route them accordingly, but enforcement happens through the permission allowlist.
- Keep credentials out of version control (see the config section).

## License

[MIT](LICENSE)