mcp-server-database 是一个 Go 实现的 MCP Server,统一暴露 MySQL、SQLite、PostgreSQL 的数据库查询、写入、DDL 和元数据工具。
- MCP 入口:
POST /mcp(HTTP)或stdio - 已实现工具:
db_list_connections、db_list_schemas、db_list_tables、db_describe_table、db_list_indexes、db_query、db_exec、db_ddl - 工具契约:
tools/*.yml - 协议文档:
docs/mcp-protocol-definition.md - 协议版本:
2025-06
前置要求:
- Go
1.26+ - Docker 和 Docker Compose(可选)
连接外部 MySQL / PostgreSQL:
cp .env.example .env
cp configs/local-mysql.example.yml configs/local-mysql.yml
cp configs/local-postgres.example.yml configs/local-postgres.yml
mkdir -p tmp
make run将 configs/local-mysql.yml、configs/local-postgres.yml 里的 url、username、password 改成你自己的云数据库、本机数据库或其他现有数据库地址后,再启动服务。
容器方式启动 MCP 服务本体:
cp .env.example .env
cp configs/local-mysql.example.yml configs/local-mysql.yml
cp configs/local-postgres.example.yml configs/local-postgres.yml
mkdir -p tmp
make docker-up快速本地验证:
cp .env.example .env
cp configs/local-sqlite.example.yml configs/local-sqlite.yml
mkdir -p tmp
make runstdio 模式:
cp .env.example .env
cp configs/local-sqlite.example.yml configs/local-sqlite.yml
MCP_TRANSPORT=stdio make run测试:
make test- 环境变量契约主维护文件是
.env.example,本地真实值写入.env。 - 数据库连接示例模板放在
configs/*.example.yml,本地真实连接配置默认放在configs/。 local-mysql.example.yml、local-postgres.example.yml使用url + username + password占位符,复制后必须替换为真实地址和凭据。local-sqlite.example.yml是零依赖示例,用于快速验证服务链路,不代表仅支持 SQLite。- 配置优先级:代码默认值 < 环境变量。
DB_CONNECTIONS_CONFIG_PATH可显式指定连接配置目录或单个 YAML 文件;未设置时默认读取./configs。- 目录扫描会忽略
*.example.yml/*.example.yaml模板文件,只加载真实连接配置。
常用变量分组:
- Server:
SERVER_PORT、SERVER_SHUTDOWN_TIMEOUT_SECONDS - MCP:
MCP_TRANSPORT、MCP_TOOLS_SPEC_LOCATION_PATTERN、MCP_HTTP_MAX_BODY_BYTES - MCP 限流:
MCP_RATE_LIMIT_ENABLED、MCP_RATE_LIMIT_RPS、MCP_RATE_LIMIT_BURST - Observability:
MCP_OBSERVABILITY_LOG_ENABLED、MCP_OBSERVABILITY_LOG_MAX_BODY_LENGTH、MCP_OBSERVABILITY_LOG_INCLUDE_HEADERS - Database:
DB_CONNECTIONS_CONFIG_PATH、DB_DEFAULT_QUERY_TIMEOUT_SECONDS、DB_MAX_RESULT_ROWS、DB_MAX_CELL_BYTES - Compose:
HOST_PORT
连接配置文件字段:
- 一个数据库连接对应一个
yml/yaml文件。 name:MCP 工具里使用的连接名description:面向客户端的人类可读描述driver:可选。使用url时通常自动推断;仅在保留旧dsn写法时需要显式指定。url:推荐使用的目标数据库地址。MySQL 使用mysql://host:port/db?...,PostgreSQL 使用postgres://host:port/db?...或postgresql://...,SQLite 使用file:...或本地路径。username/password:MySQL、PostgreSQL 的独立凭据字段;SQLite 不支持。dsn:兼容旧配置的原生驱动连接串,保留但不再推荐。allow_write:是否允许db_execallow_ddl:是否允许db_ddl
以下示例默认服务运行在 http://localhost:11965(基于 .env.example 默认值)。
curl -sS -X POST http://localhost:11965/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": "init-1",
"method": "initialize",
"params": {
"protocolVersion": "2025-06",
"capabilities": {},
"clientInfo": {
"name": "curl",
"version": "1.0.0"
}
}
}'curl -sS -X POST http://localhost:11965/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":"tools-list-1","method":"tools/list","params":{}}'tools/list 返回的每个工具对象都保留原始 name,并额外声明中文展示字段 label。客户端应优先展示 label,但发起 tools/call 时仍必须使用 name。完整协议说明见 docs/mcp-protocol-definition.md。
curl -sS -X POST http://localhost:11965/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": "conn-1",
"method": "tools/call",
"params": {
"name": "db_list_connections",
"arguments": {}
}
}'db_list_connections 返回的每个连接项包含 status,当探测失败时还会额外返回可选字段 status_reason,用于展示脱敏后的失败原因,例如网络超时、鉴权失败或 DNS 解析失败。
curl -sS -X POST http://localhost:11965/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": "query-1",
"method": "tools/call",
"params": {
"name": "db_query",
"arguments": {
"connection_name": "local-sqlite",
"sql": "select id, name from demo_users where id > ?",
"args": [10],
"max_rows": 20
}
}
}'curl -sS -X POST http://localhost:11965/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": "exec-1",
"method": "tools/call",
"params": {
"name": "db_exec",
"arguments": {
"connection_name": "local-postgres",
"sql": "insert into demo_users(name) values ($1)",
"args": ["alice"]
}
}
}'curl -sS -X POST http://localhost:11965/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": "ddl-1",
"method": "tools/call",
"params": {
"name": "db_ddl",
"arguments": {
"connection_name": "local-mysql",
"sql": "create table if not exists demo_users (id bigint primary key auto_increment, name varchar(255) not null)"
}
}
}'- 每次工具调用只执行一条 SQL,不支持跨请求事务。
db_query只允许只读语句;db_exec只允许 DML;db_ddl只允许 DDL。- 工具使用目标数据库原生 SQL 和原生占位符风格,不做跨方言改写。
- 元数据工具
db_list_tables、db_describe_table、db_list_indexes在未传schema时,会使用数据库连接当前默认 schema/database;PostgreSQL 会遵循连接的search_path/current_schema()。