数据库访问协议服务器

一个安全的模型上下文协议(MCP)服务器,通过FastMCP向LLM客户端提供数据库访问服务,支持SQLite、PostgreSQL、MySQL和Microsoft SQL Server等多种数据库。

  • by lieberweiss
  • Python
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 lieberweiss/sql_mcp_server

使用说明

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=sqlite
  • SQLITE_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=postgres
  • DB_HOST
  • DB_PORT (可选,默认驾驶员侧;建议设置)
  • DB_USER
  • DB_PASSWORD
  • DB_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=mysql
  • DB_HOST
  • DB_PORT (可选,默认驾驶员侧;建议设置)
  • DB_USER
  • DB_PASSWORD
  • DB_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=mssql
  • DB_HOST
  • DB_USER
  • DB_PASSWORD
  • DB_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级只读权限。

许可证

麻省理工学院