使用说明
sql-mcp服务器
一个安全的模型上下文协议(MCP)服务器,通过以下方式向LLM客户端公开数据库访问权限 FastMCP.
支持的数据库提供程序:
- SQLite
- PostgreSQL
- MySQL
- Microsoft SQL Server(MSSQL)
特性
- 默认情况下是安全的SQL验证中间件
- 只读模式(
DB_READ_ONLY=true)执行前强制执行 - 单一声明执行
- 禁止关键字检测
- 对破坏性陈述进行细致的选择(例如允许
DROP通过DB_ALLOW_DROP=true) - 自动行限制(
LIMIT/TOP) - 可选表格列表(
DB_ALLOWED_TABLES) - 多实例运行时:从单个MCP服务器公开多个数据库
- 用于模式探索和安全查询的MCP工具
项目结构
src/sql_mcp_server/
main.py
config.py
errors.py
middleware/sql_validator.py
db/
tools/
配置
复制 .env.example 到 .env 并更新值。
多实例设置
集 MCP_INSTANCES 以逗号分隔的前缀列表(例如。 MCP_INSTANCES=CRM,ERP).
对于每个前缀,通过大写前缀和
标准密钥后缀: CRM_DB_PROVIDER, CRM_DB_HOST等等。实例标识符为
不区分大小写,可通过 instance_id 参数。
当 MCP_INSTANCES 如果省略,服务器将公开一个 default 实例来源
直接从下面显示的无前缀环境变量中获取。
SQLite
DB_PROVIDER=sqlite
SQLITE_PATH=./database.db
DB_READ_ONLY=true
DB_MAX_ROWS=100
PostgreSQL
DB_PROVIDER=postgres
DB_HOST=localhost
DB_PORT=5432
DB_USER=myuser
DB_PASSWORD=mypassword
DB_DATABASE=mydb
DB_READ_ONLY=true
DB_MAX_ROWS=100
MySQL
DB_PROVIDER=mysql
DB_HOST=localhost
DB_PORT=3306
DB_USER=myuser
DB_PASSWORD=mypassword
DB_DATABASE=mydb
DB_READ_ONLY=true
DB_MAX_ROWS=100
数据库
DB_PROVIDER=mssql
DB_HOST=localhost
DB_PORT=1433
DB_USER=myuser
DB_PASSWORD=mypassword
DB_DATABASE=mydb
DB_READ_ONLY=true
DB_MAX_ROWS=100
ℹ️ MSSQL客户端适用
DB_QUERY_TIMEOUT当提供pyodbc连接超时时;确保您选择的驱动程序支持此属性。 ⚠️ 确保安装SQL Server ODBC驱动程序(例如。,msodbcsql17/msodbcsql18)在启动MSSQL实例之前,否则pyodbc无法建立连接。
安装
python -m venv .venv
.venv\\Scripts\\activate
pip install -e .
跑
sql-mcp-server
服务器通过stdio(FastMCP默认)运行,可以连接到MCP兼容的客户端。
Windsurf配置(mcp_config.json)
Windsurf可以通过stdio启动此MCP服务器。您可以在以下位置进行配置:
~/.codeium/windsurf/mcp_config.json
以下示例使用“模块”入口点(选项2):
command:您的venv Python可执行文件args:["-m", "sql_mcp_server.main"]
常见的可选env字段
DB_READ_ONLY(可选,默认值:true)DB_MAX_ROWS(可选,默认值:100)DB_QUERY_TIMEOUT(可选,默认值:10秒)DB_STATEMENT_TIMEOUT_MS(可选,默认值:DB_QUERY_TIMEOUT * 1000;限制语句执行时间)DB_ALLOWED_TABLES(可选,逗号分隔的列表)DB_ALLOW_ALTER(可选,默认值:false;当true,验证器允许ALTER语句传递,因此您可以在不完全禁用关键字保护的情况下演化模式)DB_ALLOW_DROP(可选,默认值:false;设置为true只有当你故意需要跑步的时候DROP声明)ENABLE_QUERY_LOGS(可选,默认值:false;启用后,SQL元数据将记录到logs/queries.log每日轮换)LOG_QUERY_BODIES(可选,默认值:false;当true,除了哈希元数据外,还会记录完整的SQL文本——在生产环境中保持禁用状态)SQL_MCP_LOG_LEVEL(可选,默认值:INFO;覆盖以减少生产中的冗长,例如。WARNING)tokens.txt(项目根)存储一个username:token:scopes每行输入;范围接受r,w,a,d.
SQLite(风帆)
必需的env字段:
DB_PROVIDER=sqliteSQLITE_PATH
{
"mcpServers": {
"sql-sqlite": {
"command": "c:\\dev\\code\\mcp\\sql_mcp_server\\.venv\\Scripts\\python.exe",
"args": ["-m", "sql_mcp_server.main"],
"disabled": false,
"env": {
"DB_PROVIDER": "sqlite",
"SQLITE_PATH": "./database.db",
"DB_READ_ONLY": "true",
"DB_MAX_ROWS": "100",
"DB_QUERY_TIMEOUT": "10",
"DB_ALLOWED_TABLES": ""
}
}
}
}
PostgreSQL(Windsurf)
必需的env字段:
DB_PROVIDER=postgresDB_HOSTDB_PORT(可选,默认驾驶员侧;建议设置)DB_USERDB_PASSWORDDB_DATABASE
{
"mcpServers": {
"sql-postgres": {
"command": "c:\\dev\\code\\mcp\\sql_mcp_server\\.venv\\Scripts\\python.exe",
"args": ["-m", "sql_mcp_server.main"],
"disabled": false,
"env": {
"DB_PROVIDER": "postgres",
"DB_HOST": "localhost",
"DB_PORT": "5432",
"DB_USER": "myuser",
"DB_PASSWORD": "mypassword",
"DB_DATABASE": "mydb",
"DB_READ_ONLY": "true",
"DB_MAX_ROWS": "100",
"DB_QUERY_TIMEOUT": "10",
"DB_ALLOWED_TABLES": ""
}
}
}
}
MySQL(Windsurf)
必需的env字段:
DB_PROVIDER=mysqlDB_HOSTDB_PORT(可选,默认驾驶员侧;建议设置)DB_USERDB_PASSWORDDB_DATABASE
{
"mcpServers": {
"sql-mysql": {
"command": "c:\\dev\\code\\mcp\\sql_mcp_server\\.venv\\Scripts\\python.exe",
"args": ["-m", "sql_mcp_server.main"],
"disabled": false,
"env": {
"DB_PROVIDER": "mysql",
"DB_HOST": "localhost",
"DB_PORT": "3306",
"DB_USER": "myuser",
"DB_PASSWORD": "mypassword",
"DB_DATABASE": "mydb",
"DB_READ_ONLY": "true",
"DB_MAX_ROWS": "100",
"DB_QUERY_TIMEOUT": "10",
"DB_ALLOWED_TABLES": ""
}
}
}
}
MSSQL(风帆)
必需的env字段:
DB_PROVIDER=mssqlDB_HOSTDB_USERDB_PASSWORDDB_DATABASE
可选的env字段:
DB_PORT(可选;默认值:1433)DB_MSSQL_ODBC_DRIVER(可选;如果未设置,服务器将尝试:ODBC Driver 18 for SQL Server那么ODBC Driver 17 for SQL Server那么SQL Server)DB_MSSQL_TRUST_SERVER_CERTIFICATE(可选;默认值:false;设置为true使用自签名证书时用于本地/dev)
{
"mcpServers": {
"sql-mssql": {
"command": "c:\\dev\\code\\mcp\\sql_mcp_server\\.venv\\Scripts\\python.exe",
"args": ["-m", "sql_mcp_server.main"],
"disabled": false,
"env": {
"DB_PROVIDER": "mssql",
"DB_HOST": "localhost",
"DB_PORT": "1433",
"DB_USER": "myuser",
"DB_PASSWORD": "mypassword",
"DB_DATABASE": "mydb",
"DB_MSSQL_ODBC_DRIVER": "ODBC Driver 17 for SQL Server",
"DB_MSSQL_TRUST_SERVER_CERTIFICATE": "true",
"DB_READ_ONLY": "true",
"DB_MAX_ROWS": "100",
"DB_ALLOWED_TABLES": ""
}
}
}
}
MCP工具
list_tables(instance_id?: str):列出所选实例的可访问表describe_table(table: str, instance_id?: str):特定表的列run_select(query: str, instance_id?: str):执行经过验证的安全SELECT查询run_query(query: str, instance_id?: str):执行已验证的查询(当实例不是只读时,允许写入语句)
嵌入服务器时,调用 sql_mcp_server.instances.shutdown_instance_registry() 在拆卸过程中,干净地关闭数据库连接。
日志记录和隐私
- 日志文件位于
logs/每天轮换;它们是用0600避免意外暴露的权限。 - 默认情况下,查询日志仅存储查询长度和SHA-256哈希值;通过以下方式启用它们
ENABLE_QUERY_LOGS=true,然后打开LOG_QUERY_BODIES=true只有当你真的需要原始SQL进行调试时。 - 调整
SQL_MCP_LOG_LEVEL以减少生产中的冗长。
身份验证(API密钥)
- 通过提供
tokens.txt文件(默认位于项目根目录)username:token:scopes每用户一行。 list_tables和describe_table要求r范围。run_select需要r.run_query需要w也会要求a/d只要语句包含实例配置允许的ALTER或DROP操作。- 将令牌传递给
api_key每个MCP工具调用的参数(或定义API_KEY在客户端环境中,因此FastMCP会自动注入它)。 - 使用
python scripts/generate_api_key.py <username> --scopes rwad将条目附加到tokens.txt(使用--file指向另一个文件或--stdout无需书写即可打印)。删除用户python scripts/remove_api_key.py <username>.
安全说明
- 始终使用权限尽可能少的数据库用户。
- 除了中间件强制之外,更喜欢DB级只读权限。
许可证
麻省理工学院