Skip to main content
Glama
ByteTora

mysql-mcp-server-all

by ByteTora
README.md
# mysql-mcp-server-all

A read-only **MySQL MCP server** that speaks **stdio**, **SSE**, and
**Streamable HTTP** — one binary, three transports.

## Why this project exists

We needed to expose a MySQL database as an MCP server to **Dify**, whose
"MCP (HTTP)" integration form **only supports the Streamable HTTP protocol**.

We evaluated the existing ecosystem:

| Project | Transport | Dify "HTTP" form |
|---|---|---|
| [benborla/mcp-server-mysql](https://github.com/benborla/mcp-server-mysql) | stdio; remote HTTP mode is stateless & incomplete | ❌ |
| [dpflucas/mysql-mcp-server](https://github.com/dpflucas/mysql-mcp-server) | stdio only | ❌ |
| [designcomputer/mysql_mcp_server](https://github.com/designcomputer/mysql_mcp_server) | stdio + SSE | ❌ |
| **mysql-mcp-server-all (this project)** | **stdio + SSE + Streamable HTTP** | ✅ |

This project is a **derived / enhanced work of
[designcomputer/mysql_mcp_server](https://github.com/designcomputer/mysql_mcp_server)** (MIT).
It keeps the same familiar toolset and adds the missing transport — so the
same server can serve Claude Code / opencode over stdio, Cherry Studio over
SSE, and Dify over Streamable HTTP.

## Features

- **Three transports** via `MCP_TRANSPORT`: `stdio` (default) / `sse` / `streamable-http`
- **Read-only by design**: only `SELECT / SHOW / DESCRIBE / EXPLAIN / WITH`
- **Single & multi database mode**: omit `MYSQL_DATABASE` to query any schema via `db.table`
- **Identifier whitelist** against SQL injection in schema/sample tools
- **Optional Bearer-token auth** for Streamable HTTP (recommended when binding beyond loopback)
- Works from **Dify**, **Cherry Studio**, **Claude Code**, **opencode** and any MCP client

## Install

Requires Python 3.10+.

```bash
# via uv (recommended)
uvx --from mysql-mcp-server-all mysql-mcp-server-all

# or pip
pip install mysql-mcp-server-all
```

> Note: this repository is GitHub-only for now. The PyPI name
> `mysql-mcp-server-all` is reserved for future publishing.

## Quick start

```bash
# stdio (Claude Code / opencode / Cherry Studio local)
MYSQL_HOST=127.0.0.1 MYSQL_USER=root MYSQL_PASSWORD=secret \
  MYSQL_DATABASE=my_db mysql-mcp-server-all

# Streamable HTTP (Dify) with token auth
MYSQL_HOST=127.0.0.1 MYSQL_USER=root MYSQL_PASSWORD=secret \
  MYSQL_DATABASE=my_db MCP_TRANSPORT=streamable-http \
  MCP_HTTP_HOST=127.0.0.1 MCP_HTTP_PORT=8000 MCP_HTTP_TOKEN=my-token \
  mysql-mcp-server-all
# -> http://127.0.0.1:8000/mcp
```

## Environment variables

| Variable | Default | Description |
|---|---|---|
| `MYSQL_HOST` | *(required)* | Database host |
| `MYSQL_PORT` | `3306` | Database port |
| `MYSQL_USER` | *(required)* | Database user |
| `MYSQL_PASSWORD` | `` | Database password |
| `MYSQL_DATABASE` | *(none)* | Default database. Omit → multi-database mode |
| `MYSQL_CONNECT_TIMEOUT` | `10` | Connection timeout (seconds) |
| `MCP_TRANSPORT` | `stdio` | `stdio` \| `sse` \| `streamable-http` |
| `MCP_HTTP_HOST` | `127.0.0.1` | Listen host for `sse` / `streamable-http` |
| `MCP_HTTP_PORT` | `8000` | Listen port for `sse` / `streamable-http` |
| `MCP_HTTP_TOKEN` | *(none)* | Bearer token for `streamable-http` |

## Transports

| Transport | Endpoint | Clients |
|---|---|---|
| `stdio` | — | Claude Code, opencode, Cursor |
| `sse` | `http://host:port/sse` | Cherry Studio (SSE), Claude Desktop |
| `streamable-http` | `http://host:port/mcp` | **Dify (HTTP)**, Cherry Studio (HTTP) |

## Client configuration

### Dify (recommended: Streamable HTTP)

```
MCP type:          HTTP
Endpoint URL:      http://127.0.0.1:8000/mcp
Auth header:       Authorization: Bearer <MCP_HTTP_TOKEN>   (if set)
Dynamic client registration: leave disabled
```

> Dify self-hosted in Docker: use `http://host.docker.internal:8000/mcp`,
> bind `MCP_HTTP_HOST=0.0.0.0`, and **add the target to Dify's SSRF proxy
> allowlist** (`SSRF_PROXY_ALLOW_PRIVATE_IPS` / `SSRF_PROXY_ALLOW_PRIVATE_DOMAINS`
> in Dify's `docker/.env`) — Dify blocks private networks by default.

### Cherry Studio

```
Type:  SSE   → URL http://127.0.0.1:8000/sse
   or  HTTP  → URL http://127.0.0.1:8000/mcp  (streamable-http)
```

### Claude Code / opencode (stdio)

```json
{
  "mcpServers": {
    "mysql": {
      "command": "mysql-mcp-server-all",
      "env": {
        "MYSQL_HOST": "127.0.0.1",
        "MYSQL_USER": "root",
        "MYSQL_PASSWORD": "secret",
        "MYSQL_DATABASE": "my_db"
      }
    }
  }
}
```

> opencode: use `"environment"` (not `"env"`) in `opencode.json`.

## Tools

| Tool | Arguments | Description |
|---|---|---|
| `execute_sql` | `query` | Run a read-only SQL query (SELECT/SHOW/DESCRIBE/EXPLAIN/WITH). Single statement. Returns JSON rows |
| `get_schema_info` | `table_name` | Column metadata (SHOW FULL COLUMNS). Accepts `db.table` |
| `get_table_sample` | `table_name`, `limit` (≤20) | Sample rows from a table. Accepts `db.table` |

## Security

- **Read-only enforced** in `execute_sql` — write/DDL queries are rejected
- **Identifier whitelist** — only alphanumeric, `_`, `$`, and one `.` separator
- **Bind loopback by default** (`127.0.0.1`)
- **Use a least-privilege MySQL user** — never `root` with full grants
- **Add token auth** (`MCP_HTTP_TOKEN`) whenever you bind `0.0.0.0`
- SSE transport has **no built-in auth** — keep it behind a loopback or a
  reverse proxy with auth (nginx / Caddy)

## Credits & License

- Derived from [designcomputer/mysql_mcp_server](https://github.com/designcomputer/mysql_mcp_server) (MIT) — same toolset, extended with unified stdio/SSE/Streamable HTTP transports.
- MIT License, see [LICENSE](LICENSE).

TDQS

A3.8/5.0

Scored across 3 tools

Disambiguation4/5

The tools are largely distinct: execute_sql runs arbitrary read-only queries, get_schema_info returns column metadata, and get_table_sample fetches sample rows. However, execute_sql can also perform SELECT queries that return sample data, creating some overlap with get_table_sample.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case: execute_sql, get_schema_info, get_table_sample. This makes the toolset predictable and easy to navigate.

Tool Count4/5

Three tools is a reasonable count for a focused read-only MySQL exploration server. While on the smaller side, each tool serves a clear purpose and the set does not feel overly thin.

Completeness4/5

The domain is well-covered for read-only database exploration: arbitrary SQL queries, schema metadata, and sample rows cover the core needs. Missing functionality like listing all tables can be achieved via execute_sql, so there are no major gaps.

Maintenance

ActivitySlowing
ResponsivenessNo issues