Skip to main content
Glama
Kenza-21

SQL MCP Server

by Kenza-21

SQL MCP Server

一个通过六个只读工具将 Postgres 数据库暴露给 LLM 智能体(Claude Desktop、Claude Code 或任何 MCP 客户端)的 Model Context Protocol 服务器。让智能体连接它,然后提出诸如 "上个月哪些客户下了超过五笔订单?" 这样的问题 —— 智能体会通过下面的工具自行探索模式并查询数据。

工具

工具

描述

list_tables()

每个表的概览:名称、描述、大小、列数

describe_table(table)

单个表的列、类型和外键关系

search_schema(keyword)

查找名称匹配关键字的表/列

sample_rows(table, limit)

查看真实数据行(默认 5 行)

count_rows(table)

表的行数

execute_select(sql)

运行任意只读 SELECT / WITH ... SELECT 查询

Related MCP server: mcp-data-gateway

为什么这不仅仅是"psycopg2 的包装器"

文本转 SQL 的演示很常见;真正困难的部分 —— 也是这个项目投入精力的地方 —— 是让 execute_select 可以安全地交给会生成任意 SQL 的 LLM:

  1. 只读 Postgres 角色。 服务器以 mcp_readonly 身份连接,该角色仅被授予 SELECT 权限(参见 scripts/init_schema.sql)。即使下面的应用层检查存在 bug,也不会导致写入。

  2. 会话级只读强制。 每个连接都会执行 SET TRANSACTION READ ONLY(db.py)。

  3. 语句验证(security.py):只允许单条 SELECT/WITH 语句 —— 不允许堆叠语句(; DROP TABLE ...)、不允许 SQL 注释(阻止基于注释的语句走私),并且关键字黑名单涵盖 INSERT/UPDATE/DELETE/DDL/GRANT 等,包括 SELECT ... INTO(它会静默地创建表)。

  4. 标识符验证。 describe_table、sample_rows 和 count_rows 将表名作为参数。由于 SQL 标识符无法用占位符参数化,表名会通过严格的正则表达式 以及 从 information_schema 获取的实时允许列表进行校验 —— 而不仅仅是字符串转义。

  5. 资源限制。 Postgres 的 statement_timeout 可防止查询失控,并且服务端会对每个查询结果强制执行行数上限,即使 LLM 的查询没有指定 LIMIT 也是如此。

快速入门

git clone <this-repo>
cd sql-mcp-server
pip install -r requirements.txt

# 1. Start Postgres with the sample schema
docker compose up -d

# 2. Generate sample e-commerce data (uses the postgres superuser, not mcp_readonly)
PGUSER=postgres PGPASSWORD=postgres python scripts/generate_sample_data.py

# 3. Configure the server to use the read-only role
cp .env.example .env
# edit .env if you changed the default mcp_readonly password

# 4. Run the tests
pytest

# 5. Run the server (stdio transport, for use with an MCP client)
python -m sql_mcp_server.server

连接 Claude Desktop

在 Claude Desktop 的 MCP 配置(claude_desktop_config.json)中添加:

{
  "mcpServers": {
    "sql-explorer": {
      "command": "python",
      "args": ["-m", "sql_mcp_server.server"],
      "cwd": "/absolute/path/to/sql-mcp-server",
      "env": {
        "PGHOST": "localhost",
        "PGPORT": "5432",
        "PGDATABASE": "sales",
        "PGUSER": "mcp_readonly",
        "PGPASSWORD": "change_me"
      }
    }
  }
}

重启 Claude Desktop,然后提出类似 "有哪些表可用,哪个产品类别的总收入最高?" 的问题。

示例模式

orders → order_items → products → categories,外加 customers。 一个订单的收入 = sum(order_items.quantity * order_items.unit_price)。 生成器会填充 ~600 位客户、~3,500 个订单,以及一些刻意加入的数据异常(缺失的电子邮件、少数批量订购的离群值),以便查询看起来像在访问真实数据。

测试

tests/test_security.py 和 tests/test_tools.py 无需数据库即可运行 —— 它们直接测试验证层,并在模拟 DB 层的情况下测试工具函数。CI 运行的就是这些。db.py 本身(psycopg2 层)在实践中则是通过让服务器连接 Docker Postgres 实例来验证的;请参见上面的快速入门。

项目结构

sql_mcp_server/
  config.py    Environment-based settings
  security.py  SQL/identifier validation (the core safety logic)
  db.py        psycopg2 access layer
  server.py    MCP tool definitions
scripts/
  init_schema.sql            Schema + read-only role setup
  generate_sample_data.py    Faker-based sample data
tests/
  test_security.py  Validation logic (18+ cases: injection, stacked
                     statements, comment smuggling, DDL/DML blocking, etc.)
  test_tools.py     Tool functions with mocked DB

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables interaction with PostgreSQL databases through MCP, allowing users to explore database structures, inspect table schemas, and execute read-only SQL queries.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to query a PostgreSQL database through a small set of controlled, read-only tools for schema inspection, row lookup, and aggregate statistics.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A read-only natural-language database agent that exposes PostgreSQL schema-discovery and SELECT tools via MCP, enabling users to query databases in plain English.
    MIT