MCP Go SQL Server
PostgreSQL和MySQL数据库的模型上下文协议(MCP)服务器,用Go实现。这是一个 基于stdio 版本的 TypeScript HTTP SQL MCP服务器.
特性
✅ 数据库支持:PostgreSQL和MySQL\ ✅ 默认情况下启用SSL/TLS:开箱即用的安全加密连接\ ✅ 安全查询生成器:使用Squirrel查询构建器(如Knex for Go)\ ✅ SQL注入保护:所有查询都使用参数化语句\ ✅ 标识符消毒:使用前验证列名/表名\ ✅ 安全查询工具:选择、插入、更新、删除\ ✅ 原始SQL:执行自定义查询(谨慎使用)\ ✅ 元数据工具:列出数据库、表和架构\ ✅ 只读模式:阻止写入操作\ ✅ 连接验证:数据库异构保护\ ✅ 标准运输:适用于Cursor、Claude Desktop和其他MCP客户端
快速开始
1.设置环境变量
您可以使用提供的 config.example.env 作为模板:
# Copy the example config
cp config.example.env .env
# Edit with your database credentials
# Then source it (Unix/Linux/macOS)
source .env
# Or set variables manually:
export DB_TYPE=postgres # or mysql
export DB_HOST=localhost
export DB_PORT=5432 # or 3306 for MySQL
export DB_USER=postgres
export DB_PASSWORD=yourpassword
export DB_NAME=yourdatabase # or comma-separated: "db1,db2,db3"
export DB_READONLY=false # optional
export ALLOW_RAW_QUERY=false # optional
export MAX_SELECT_LIMIT=1000 # optional
export MAX_UPDATE_LIMIT=1 # optional
export MAX_DELETE_LIMIT=1 # optional
# SSL/TLS Configuration (recommended for production - ENABLED BY DEFAULT)
export DB_SSLMODE=require # PostgreSQL: disable, require, verify-ca, verify-full (default: require)
export DB_TLS=true # MySQL: true, false, skip-verify, preferred (default: true)
export DB_SSLCERT=/path/to/client-cert.pem # optional: client certificate path
export DB_SSLKEY=/path/to/client-key.pem # optional: client key path
export DB_SSLROOTCERT=/path/to/ca-cert.pem # optional: CA certificate path2.构建和运行
go mod tidy
go build -o mcp-server.exe .
./mcp-server.exe配置
所有配置都是通过环境变量完成的:
| 变量 | 必填 | 默认 | 描述 | |||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
DB_TYPE | 没有 | postgres | 数据库类型: postgres 或 mysql | |||||||||||||||||||||||||||||||||||||||||||||
DB_HOST | 没有 | localhost | 数据库主机 | |||||||||||||||||||||||||||||||||||||||||||||
DB_PORT | 没有 | 5432 | 数据库端口(PostgreSQL为5432,MySQL为3306) | |||||||||||||||||||||||||||||||||||||||||||||
DB_USER | 没有 | postgres | 数据库用户 | |||||||||||||||||||||||||||||||||||||||||||||
DB_PASSWORD | 没有 | `` | Database password | DB_NAME | No | postgres | Database name(s) to connect to (comma-separated for multiple: "db1,db2,db3") | DB_READONLY | No | false | Enable read-only mode (true or false) | ALLOW_RAW_QUERY | No | false | Enable raw SQL queries ⚠️ DANGEROUS (true or false) | MAX_SELECT_LIMIT | No | 1000 | Maximum number of rows returned by SELECT queries | MAX_UPDATE_LIMIT | No | 1 | Maximum number of rows that can be updated in a single UPDATE query | MAX_DELETE_LIMIT | No | 1 | Maximum number of rows that can be deleted in a single DELETE query | DB_SSLMODE | No | require | PostgreSQL SSL mode: disable, require, verify-ca, verify-full (⚠️ disable not recommended for production) | DB_TLS | No | true | MySQL TLS mode: true, false, skip-verify, preferred (⚠️ false not recommended for production) | DB_SSLCERT | No | `` | 客户端SSL证书文件的路径(用于双向TLS身份验证) | |||||||||
DB_SSLKEY | 没有 | `` | Path to client SSL key file (for mutual TLS authentication) | DB_SSLROOTCERT | No | `` | CA证书文件的路径(用于验证服务器证书) |
MCP客户端配置
光标/VS代码
创建 .cursor/mcp.json 或 .vscode/mcp.json:
{
"mcpServers": {
"go-mcp-sql-server": {
"command": "C:\\Users\\PC\\Desktop\\mcp-go-sql\\mcp-server.exe",
"env": {
"DB_TYPE": "postgres",
"DB_HOST": "localhost",
"DB_PORT": "5432",
"DB_USER": "postgres",
"DB_PASSWORD": "yourpassword",
"DB_NAME": "yourdatabase",
"DB_READONLY": "false",
"ALLOW_RAW_QUERY": "false",
"MAX_SELECT_LIMIT": "1000",
"MAX_UPDATE_LIMIT": "1",
"MAX_DELETE_LIMIT": "1",
"DB_SSLMODE": "require"
}
}
}
}克劳德桌面版
添加到Claude Desktop配置文件:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json\ 视窗: %APPDATA%\Claude\claude_desktop_config.json\ Linux: ~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"go-mcp-sql-server": {
"command": "/path/to/mcp-server",
"env": {
"DB_TYPE": "mysql",
"DB_HOST": "localhost",
"DB_PORT": "3306",
"DB_USER": "root",
"DB_PASSWORD": "password",
"DB_NAME": "myapp",
"DB_READONLY": "false",
"ALLOW_RAW_QUERY": "false",
"MAX_SELECT_LIMIT": "1000",
"MAX_UPDATE_LIMIT": "1",
"MAX_DELETE_LIMIT": "1",
"DB_TLS": "true"
}
}
}
}多数据库支持
您可以通过提供逗号分隔的列表来配置对多个数据库的访问:
{
"mcpServers": {
"go-mcp-sql-server": {
"command": "C:\\Users\\PC\\Desktop\\mcp-go-sql\\mcp-server.exe",
"env": {
"DB_TYPE": "mysql",
"DB_HOST": "localhost",
"DB_PORT": "3306",
"DB_USER": "root",
"DB_PASSWORD": "",
"DB_NAME": "information_schema,myapp,testdb",
"DB_READONLY": "false",
"MAX_SELECT_LIMIT": "1000",
"MAX_UPDATE_LIMIT": "1",
"MAX_DELETE_LIMIT": "1",
"DB_TLS": "true"
}
}
}
}它是如何工作的:
- 服务器连接到 第一数据库 在列表中(主要连接)
- 工具可以访问 任何数据库 在列表中
- 这
get_databases该工具仅返回已配置的数据库(安全功能) - 数据库名称在每次查询时都会根据分配列表进行验证
例子:
# Configure three databases
export DB_NAME="information_schema,gzk,portals"
# Now you can query any of these:
# - information_schema.TABLES
# - gzk.users
# - portals.content可用工具(共13个)
服务器实现 所有工具 从TypeScript版本开始,分为三类:
查询工具(5个工具)
1. query_select -选择查询
使用WHERE、ORDER BY、LIMIT和OFFSET支持执行SELECT查询。
输入:
{
"database": "yourdatabase",
"table": "users",
"columns": ["id", "name", "email"],
"where": [
{"column": "status", "op": "=", "value": "active"},
{"column": "age", "op": ">", "value": 18}
],
"order_by": ["name"],
"limit": 10,
"offset": 0
}输出:
✓ SELECT from mydb.users
Found 2 row(s):
| id | name | email |
| --- | --- | --- |
| 1 | John | john@example.com |
| 2 | Jane | jane@example.com |2. query_insert -插入行
在表中插入一行。
输入:
{
"database": "yourdatabase",
"table": "users",
"data": {
"name": "Bob",
"email": "bob@example.com",
"age": 30
}
}输出:
✓ INSERT successful
Inserted 1 row(s) into yourdatabase.users3. query_update -更新行
更新表中的行。 WHERE子句是必需的 为了安全。
输入:
{
"database": "yourdatabase",
"table": "users",
"data": {
"status": "inactive"
},
"where": [
{"column": "id", "op": "=", "value": 123}
]
}输出:
✓ UPDATE successful
Updated 1 row(s) in yourdatabase.users4. query_delete -删除行
从表中删除行。 WHERE子句是必需的 为了安全。
输入:
{
"database": "yourdatabase",
"table": "users",
"where": [
{"column": "id", "op": "=", "value": 123}
]
}输出:
✓ DELETE successful
Deleted 1 row(s) from yourdatabase.users5. query_raw -原始SQL查询
执行原始SQL查询。 小心使用!
输入:
{
"database": "yourdatabase",
"query": "SELECT * FROM users WHERE status = ? AND age > ?",
"params": ["active", 18]
}输出:
✓ Raw query successful
Found 5 row(s):
| id | name | status |
| --- | --- | --- |
| 1 | Alice | active |
| 2 | Bob | active |
...元数据工具(5个工具)
6. get_databases -列出数据库
从配置的列表中列出数据库(来自 DB_NAME 环境变量)。
输入: 无
输出:
• information_schema
• myapp
• testdb注: 这只返回您在中配置的数据库 DB_NAME,并非服务器上的所有数据库。这通过限制访问来提供安全性。
7. get_tables -列表表格
列出特定数据库中的表。
输入:
{
"database": "yourdatabase",
"schema": "public"
}输出:
• users
• orders
• products8. get_table_schema -获取表架构
获取表的详细架构信息,包括外键。
输入:
{
"database": "yourdatabase",
"table": "users",
"schema": "public"
}输出:
Table: yourdatabase.users
Columns:
Column Type Nullable Default Key Extra
-----------------------------------------------------------------------------------------
id int(11) NO PRI auto_increment
name varchar(255) NO
email varchar(255) YES NULL
user_id int(11) YES NULL MUL
Foreign Keys:
• user_id → yourdatabase.profiles(id)
Indexes:
• idx_email (UNIQUE)
• idx_name (INDEX)9. get_sequences -列表序列
获取序列信息(PostgreSQL序列或MySQL auto_increment列)。
输入:
{
"database": "yourdatabase",
"schema": "public"
}输出:
Sequences in yourdatabase.public:
• users_id_seq
Type: bigint
Start: 1, Min: 1, Max: 9223372036854775807, Increment: 110. get_custom_types -列出自定义类型
列出自定义类型(仅限PostgreSQL:ENUM、COMPOSITE、DOMAIN)。
输入:
{
"database": "yourdatabase",
"schema": "public"
}输出:
Custom types in yourdatabase.public:
• status_enum (enum)
Values: [active, inactive, pending]
• address_type (composite)
Attributes:
- street: text
- city: varchar(100)功能工具(3个工具)
11. get_functions -列出功能/程序
列出所有函数和存储过程。
输入:
{
"database": "yourdatabase",
"schema": "public"
}输出:
Functions and procedures in yourdatabase.public:
Functions (2):
• calculate_total(price numeric, tax_rate numeric)
Returns: numeric | Language: plpgsql
• get_user_count()
Returns: bigint | Language: sql
Procedures (1):
• update_user_status(user_id integer, new_status text)
Language: plpgsql12. get_function_source -查看函数源
获取函数或过程的完整源代码。
输入:
{
"database": "yourdatabase",
"schema": "public",
"name": "calculate_total"
}输出:
FUNCTION: public.calculate_total
CREATE OR REPLACE FUNCTION public.calculate_total(price numeric, tax_rate numeric)
RETURNS numeric
LANGUAGE plpgsql
AS $function$
BEGIN
RETURN price * (1 + tax_rate);
END;
$function$13. execute_function -执行功能/程序
使用参数执行函数或存储过程。
输入:
{
"database": "yourdatabase",
"schema": "public",
"name": "calculate_total",
"params": [100, 0.15]
}输出:
✓ Function executed successfully
Result: 115.00注: 存储过程在只读模式下被阻止。
支持的WHERE运算符
=-平等!=或<>-不相等- `` -大于
>=-大于或等于LIKE-图案匹配IN-在列表中BETWEEN-在两个值之间IS NULL-为空IS NOT NULL-不为空
查询限制
服务器对查询操作实施可配置的限制,以防止意外的大规模操作:
选择查询
- 默认限制:1000行
- 行为:如果未指定LIMIT,则自动应用默认值
- 以(权力)否决:用户指定的限制上限为最大值
- 示例:如果
MAX_SELECT_LIMIT=100,一个查询LIMIT=200将返回最多100行
更新查询
- 默认限制:1行
- 行为:在执行之前,统计与WHERE子句匹配的行数
- 预防:如果计数超过限制,则返回计数错误
- 错误消息:“更新将影响X行,这超过了Y的最大限制”
删除查询
- 默认限制:1行
- 行为:在执行之前,统计与WHERE子句匹配的行数
- 预防:如果计数超过限制,则返回计数错误
- 错误消息:“DELETE将影响X行,这超过了Y的最大限制”
INSERT查询
- 设计:只接受单行(列映射:值对)
- 无需明确限制
为什么有这些限制?
- 防止意外的大规模删除/更新
- 防止格式不良的WHERE子句
- 强制进行大规模变更的深思熟虑的操作
- 可以根据环境(开发与生产)进行调整
SSL/TLS配置
服务器现在支持SSL/TLS连接 默认情况下启用SSL 以增强安全性。
PostgreSQL SSL模式
通过配置 DB_SSLMODE 环境变量:
| 模式 | 描述 | 安全级别 |
|---|---|---|
disable | 无SSL加密⚠️ 不建议用于生产 | ❌ 低 |
require | 默认。需要SSL,但不验证服务器证书 | ✅ 中等 |
verify-ca | 需要SSL并根据CA验证服务器证书 | ✅✅ 高 |
verify-full | 需要SSL,验证证书和主机名 | ✅✅✅ 最高 |
双向TLS(mTLS)示例:
{
"env": {
"DB_TYPE": "postgres",
"DB_SSLMODE": "verify-full",
"DB_SSLCERT": "C:\\certs\\client-cert.pem",
"DB_SSLKEY": "C:\\certs\\client-key.pem",
"DB_SSLROOTCERT": "C:\\certs\\ca-cert.pem"
}
}MySQL TLS模式
通过配置 DB_TLS 环境变量:
| 模式 | 描述 | 安全级别 |
|---|---|---|
false | 无TLS加密⚠️ 不建议用于生产 | ❌ 低 |
preferred | 使用TLS(如果可用),回退到未加密 | ⚠️ 中等 |
true | 默认。需要TLS连接 | ✅ 高 |
skip-verify | 需要TLS,但不验证服务器证书 | ⚠️ 中等 |
TLS示例:
{
"env": {
"DB_TYPE": "mysql",
"DB_TLS": "true"
}
}禁用SSL/TLS(不建议)
仅用于本地开发或测试:
PostgreSQL:
export DB_SSLMODE=disableMySQL:
export DB_TLS=false⚠️ 警告:切勿在生产环境中禁用SSL/TLS。连接到远程数据库时,始终使用加密连接。
安全特性
✅ SSL/TLS支持:默认情况下启用加密连接\ ✅ 查询构建器:用途 松鼠 查询生成器(Go相当于Knex.js)\ ✅ 参数化查询:所有值都自动转义并参数化\ ✅ 标识符验证:使用前对列名和表名进行消毒\ ✅ 无字符串连接:通过查询生成器API安全生成SQL\ ✅ 必需的WHERE子句:UPDATE和DELETE操作需要WHERE条件\ ✅ 查询限制:SELECT、UPDATE和DELETE操作的可配置限制\ ✅ 数据库验证:只能访问已配置的数据库\ ✅ 只读模式:可选择阻止所有写入操作\ ✅ 连接池:由数据库/sql包管理\ ✅ 双向TLS:可选客户端证书身份验证
SQL注入保护
与原始实现不同,此版本使用 松鼠,一个成熟的SQL查询构建器,它:
- 自动处理参数绑定(PostgreSQL为$1,MySQL为$2)
- 将SQL结构与数据值分离
- 验证和净化标识符
- 防止常见的SQL注入向量
- 与TypeScript版本的Knex.js类似的安全模型
例子
示例1:查询用户
{
"tool": "query_select",
"input": {
"database": "myapp",
"table": "users",
"columns": ["id", "name", "email"],
"where": [
{"column": "created_at", "op": ">", "value": "2024-01-01"}
],
"order_by": ["created_at DESC"],
"limit": 5
}
}示例2:插入订单
{
"tool": "query_insert",
"input": {
"database": "myapp",
"table": "orders",
"data": {
"user_id": 123,
"product_id": 456,
"quantity": 2,
"total": 99.99
}
}
}示例3:获取表结构
{
"tool": "get_table_schema",
"input": {
"database": "myapp",
"table": "products"
}
}发展
项目结构
mcp-go-sql/
├── main.go # Server setup and tool registration
├── types.go # Input/output type definitions
├── db.go # Database connection management
├── helpers.go # Helper functions (sanitization, query building)
├── query_tools.go # Query tools (SELECT, INSERT, UPDATE, DELETE, RAW)
├── metadata_tools.go # Metadata tools (databases, tables, schemas, etc.)
├── function_tools.go # Function/procedure tools
├── go.mod # Go dependencies
├── go.sum # Dependency checksums
├── README.md # This file建筑
# Build for current platform
go build -o mcp-server .
# Build for Linux
GOOS=linux GOARCH=amd64 go build -o mcp-server-linux .
# Build for macOS
GOOS=darwin GOARCH=amd64 go build -o mcp-server-macos .
# Build for Windows
GOOS=windows GOARCH=amd64 go build -o mcp-server.exe .测试
# Test PostgreSQL connection
DB_TYPE=postgres DB_HOST=localhost DB_PORT=5432 \
DB_USER=postgres DB_PASSWORD=pass DB_NAME=testdb \
./mcp-server.exe
# Test MySQL connection
DB_TYPE=mysql DB_HOST=localhost DB_PORT=3306 \
DB_USER=root DB_PASSWORD=pass DB_NAME=testdb \
./mcp-server.exe需求
- 达到1.23.0或更高
- PostgreSQL或MySQL数据库
- MCP Go SDK v1.0.0
- 松鼠v1.5.4 -SQL查询生成器
与TypeScript版本的差异
这是一个 基于stdio 与原始的基于HTTP的TypeScript版本相比:
| 特性 | TypeScript(HTTP) | Go(stdio) |
|---|---|---|
| 传输 | 带标头的HTTP | stdin/stdout |
| 配置 | HTTP标头 | 环境变量 |
| 会话管理 | HTTP会话 | 单连接 |
| 多数据库 | 每个会话(多个) | 每个实例多个数据库(逗号分隔) |
| 查询生成器 | Knex.js | 松鼠 |
| 功能/程序 | ✅ 支持 | ✅ 支持 |
| 自定义类型 | ✅ 支持 | ✅ 支持 |
| 序列 | ✅ 支持 | ✅ 支持 |
| 工具数 | 13工具 | 13工具 |
特性完成✅
这个Go实现现在有 特征奇偶校验 对于TypeScript版本:
- ✅ 所有13个工具均已实施
- ✅ 存储过程/函数支持
- ✅ 自定义类型枚举(PostgreSQL)
- ✅ 序列表
- ✅ 外键关系
- ✅ 松鼠查询生成器
- ✅ 只读模式
- ✅ 原始SQL支持(选择加入)
未来的增强功能
TypeScript版本之外的潜在添加:
- \[\]交易支持
- \[\]批量操作
- \[\]多个数据库连接
- \[\]连接池配置
- \[x\] SSL/TLS支持 ✅ 在启用默认SSL/TLS的情况下实现
- \[\]查询超时配置
- \[\]查询结果缓存
- \[\]HTTP传输选项
许可证
麻省理工学院
