sqlglot MCP server

sqlglot MCP server

Provides SQL parsing, transpilation, formatting, extraction, and condition injection via MCP protocol, enabling agents to validate, analyze, and transform SQL.

Category
Visit Server

README

SQL 解析 API 服务(REST / HTTP)

基于 sqlglot 的 SQL 解析 / 转译 / 格式化 / 提取 / 条件注入服务,使用 FastAPI 暴露为 REST 接口。核心逻辑在 core.py,被本服务(HTTP)复用。

运行

pip install -r requirements.txt
uvicorn main:app --host 0.0.0.0 --port 8000 --reload

启动后访问交互式文档:http://localhost:8000/docs

服务默认开启 CORS(allow_origins=["*"]),便于前端跨域调用。

接口总览

方法 路径 说明
GET /health 健康检查,返回 sqlglot 版本
GET /dialects 列出 sqlglot 支持的所有方言
POST /parse 将 SQL 解析为结构化 AST(JSON)
POST /transpile 在方言之间互转 SQL(如 MySQL → PostgreSQL)
POST /format 美化 / 标准化 SQL
POST /validate 校验 SQL 语法是否合法(不抛异常)
POST /extract 提取表名、列名、函数、CTE 及别名映射
POST /add_condition 追加 WHERE 条件(自动别名,支持多表 / 多条件 / 多操作符 / 直拼原始 SQL)

所有接口在 SQL 解析 / 处理失败时会返回 400,错误信息在响应体 detail 字段中。


接口详情

1. 健康检查 GET /health

返回服务状态与 sqlglot 版本号。

curl http://localhost:8000/health
# {"status":"ok","sqlglot_version":"30.12.0"}

2. 方言列表 GET /dialects

返回 sqlglot 支持的全部方言名称(按字母序)。

curl http://localhost:8000/dialects
# {"dialects":["bigquery","clickhouse","mysql","postgres", ...]}

3. 解析为 AST POST /parse

请求体:

字段 类型 说明
sql string 待解析的 SQL
read string? 输入方言,留空自动识别
pretty bool AST 是否美化输出(默认 true)
curl -X POST http://localhost:8000/parse \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT a, b FROM t WHERE a > 1"}'
# {"sql":"...","dialect":null,"ast":"SELECT a, b FROM t WHERE a > 1","json":{...}}

返回含 sql / dialect / ast / json 四个字段,其中 json 为 AST 的树形结构。

4. 方言转译 POST /transpile

字段 类型 说明
sql string 待转译的 SQL
read string? 输入方言,留空自动识别
write string 目标方言(必填)
curl -X POST http://localhost:8000/transpile \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT IFNULL(a, 0) FROM t", "write": "postgres"}'
# {"read":null,"write":"postgres","sql":"SELECT IFNULL(a, 0) FROM t","transpiled":"SELECT COALESCE(a, 0) FROM t"}

5. 格式化 POST /format

字段 类型 说明
sql string 待格式化的 SQL
read string? 输入方言,留空自动识别
write string? 输出方言,默认与输入一致(可顺带转译)
curl -X POST http://localhost:8000/format \
  -H "Content-Type: application/json" \
  -d '{"sql": "select a,b from t where a>1"}'
# {"sql":"select a,b from t where a>1","formatted":"SELECT a, b\nFROM t\nWHERE a > 1"}

6. 语法校验 POST /validate

字段 类型 说明
sql string 待校验的 SQL
read string? 输入方言,留空自动识别

返回不抛异常,valid 为布尔,error 在合法时为 null。

curl -X POST http://localhost:8000/validate \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT a FROM t"}'
# {"valid":true,"error":null}

7. 提取元数据 POST /extract

字段 类型 说明
sql string 待分析的 SQL
read string? 输入方言,留空自动识别

返回字段:

字段 说明
tables 真实表名(已剔除 CTE 名)
columns 带表限定符的列名,如 t1.id
columns_bare 裸列名(不含来源),如 id
functions 函数调用文本
ctes CTE 别名
table_aliases FROM/JOIN 上的显式别名映射 [{alias, table}]
cte_sources CTE 名 → 内部真实表映射 [{cte, tables}]
curl -X POST http://localhost:8000/extract \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT a, b FROM t1 JOIN t2 ON t1.id = t2.id"}'
# {"tables":["t1","t2"],"columns":["a","b","t1.id","t2.id"],
#  "columns_bare":["a","b","id"],"functions":[],"ctes":[],
#  "table_aliases":[],"cte_sources":[]}

8. 追加条件 POST /add_condition

为 SQL 追加 WHERE 条件,支持 多表 / 多条件 / 多操作符 / 直拼原始 SQL。自动定位每个真实表在 SQL 中的引用名(别名优先),把裸列或真实表名限定列改写为别名前缀后,注入到「该表所属查询的作用域」。

提供三种入参方式(互斥,优先级:conditions > raw > 兼容旧版):

方式一 · 结构化(推荐,支持多表 + 多操作符) — 字段 conditions 为条件数组,每个元素:

字段 类型 说明
column string 列名,可带引用前缀,如 "status" 或 "t1.id"
op string 操作符,默认 =。支持 = != > >= < <= LIKE IN NOT IN BETWEEN IS NULL IS NOT NULL
value any? 比较值;IN / NOT IN 用列表,BETWEEN 用 [下限, 上限] 两元素列表,IS NULL 可省略
table string? 可选,条件所属真实表名(多表场景);跨表 JOIN 条件留空,注入顶层查询
combine string 与上一条条件的连接符 AND(默认)或 OR
curl -X POST http://localhost:8000/add_condition \
  -H "Content-Type: application/json" \
  -d '{
    "sql": "SELECT a FROM table1 AS t1 JOIN table2 AS t2 ON t1.id = t2.id WHERE t1.flag = 0",
    "conditions": [
      {"column": "status", "op": "=",   "value": 1, "table": "table1", "combine": "AND"},
      {"column": "amount", "op": ">",   "value": 100, "table": "table1"},
      {"column": "id",     "op": "IN",  "value": [1, 2, 3], "table": "table2", "combine": "OR"},
      {"column": "t1.id",  "op": "=",   "value": "t2.fid"}
    ]
  }'
# SELECT a FROM table1 AS t1 JOIN table2 AS t2 ON t1.id = t2.id
# WHERE t1.flag = 0 AND (((t1.status = 1 AND t1.amount > 100) OR t2.id IN (1, 2, 3)) AND t1.id = 't2.fid')

方式二 · 直拼原始 SQL(自动把真实表名替换为别名) — 字段 raw,直接写 WHERE 片段(用真实表名),系统自动改写为别名后注入:

字段 类型 说明
raw string | string[] 原始 WHERE 片段(用真实表名写);多条按 operator 合并
operator string 多 raw 片段之间的合并方式,AND(默认)或 OR
read string? 输入方言,留空自动识别
# 片段里用真实表名 table1 / table2 写,自动替换为别名 t1 / t2
curl -X POST http://localhost:8000/add_condition \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT a FROM table1 AS t1 JOIN table2 AS t2 ON t1.id = t2.id WHERE t1.flag = 0",
       "raw": "table1.status = 1 AND table2.amount > 100"}'
# SELECT a FROM table1 AS t1 JOIN table2 AS t2 ON t1.id = t2.id
# WHERE t1.flag = 0 AND (t1.status = 1 AND t2.amount > 100)

# 多条 raw 片段按 operator 合并
curl -X POST http://localhost:8000/add_condition \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT a FROM table1 AS t1",
       "raw": ["table1.status = 1", "table1.deleted_at IS NULL"], "operator": "OR"}'
# SELECT a FROM table1 AS t1 WHERE table1.status = 1 OR table1.deleted_at IS NULL

方式三 · 兼容旧版(单表 + 原始条件串):

字段 类型 说明
sql string 原始 SQL
table string 真实表名(非别名),用于定位引用名
condition string | string[] 条件片段;单条字符串或字符串数组(多条件)
operator string 多条件合并方式,AND(默认)或 OR
read string? 输入方言,留空自动识别
curl -X POST http://localhost:8000/add_condition \
  -H "Content-Type: application/json" \
  -d '{"sql": "SELECT a FROM table1 AS t1", "table": "table1",
       "condition": ["status = 1", "amount > 100"], "operator": "AND"}'
# SELECT a FROM table1 AS t1 WHERE t1.status = 1 AND t1.amount > 100

选型建议:

  • 需要精确控制多表分作用域和每个条件的操作符 → 用 conditions(方式一)。
  • 已有现成的 WHERE 片段(用真实表名写)想直接拼上去 → 用 raw(方式二)。
  • 老接口 / 单表简单场景 → 用 table + condition(方式三)。

行为说明:

  • 自动建立「真实表名 → 别名」映射;raw 直拼片段里用真实表名写的列(如 table1.status)会自动改写为别名(t1.status)。
  • 裸列自动加引用名前缀(status = 1 → t1.status = 1);列已带前缀(如 t1.id)则原样保留。
  • 多表:条件按 table 定位到各自所属查询作用域;表位于子查询 / CTE 内部时,条件只注入到那一层。所有表在同一查询(如 JOIN)时,条件合并进同一 WHERE。raw 片段若跨多表,注入到这些表的最近公共查询作用域。
  • 多操作符:除 AND / OR 连接符外,每个条件自带 op(IN / BETWEEN / LIKE / IS NULL 等)。
  • 同一作用域内多条件按各自 combine 从左到右联结;若目标查询已有 WHERE,则与原有条件 AND 合并。
  • 同一真实表在 SQL 中出现多次时取第一个匹配;找不到表 / 操作符不合法 / SQL 解析失败时返回 400 错误。

错误处理

所有接口在 SQL 解析 / 处理失败时会返回 HTTP 400,错误信息位于响应体的 detail 字段:

{ "detail": "解析失败: ..." }

常见错误与含义:

detail 片段 含义
解析失败: ... 输入 SQL 或条件片段无法被 sqlglot 解析(语法错误)
未在 SQL 中找到表: xxx table / conditions[].table 指定的真实表在 SQL 中不存在
条件不能为空 传入的 condition / raw 为空
不支持的合并方式: xxx operator 不是 AND / OR
不支持的操作符: xxx conditions[].op 不在支持的操作符列表内
IN 操作符的 value 必须为列表 使用 IN / NOT IN 时 value 不是数组
BETWEEN 操作符的 value 必须为包含 [下限, 上限] 的列表 使用 BETWEEN 时 value 不是两元素数组

提示:/validate 接口不会抛异常,可通过其 valid / error 字段预先判断 SQL 是否合法,再调用其它写操作接口。

MCP 服务(供 Agent 调用)

除了 REST 接口,本服务还提供 MCP Server(mcp_server.py),让 Agent 通过 MCP 协议(stdio 传输)直接调用 SQL 解析/校验/权限能力。

特点:零额外依赖,仅依赖 sqlglot(未使用官方 mcp SDK 分叉包,避免版本/兼容风险),通过标准「换行分隔的 JSON-RPC 2.0」与任何 MCP 客户端(Claude Desktop、自定义 Agent 等)对接。

运行(Agent 以子进程方式拉起):

python mcp_server.py

暴露的工具

工具 说明
validate_sql 校验 SQL 语法是否合法,返回 {valid, error}(不抛异常)
parse_sql 将 SQL 解析为结构化 AST(JSON)
transpile_sql 方言互转(如 MySQL → PostgreSQL)
format_sql 美化 / 标准化 SQL
extract_sql 提取表名、列名、函数、CTE 及别名映射
add_condition 追加 WHERE 条件(多表 / 多条件 / 多操作符 / 直拼原始 SQL)
check_permission 按策略校验 SQL(表/列白黑名单、禁止 DML/DDL 等),仅校验不改写
enforce_permission 校验通过后自动加固 SQL(注入行级过滤、自动补 LIMIT),返回改写结果

权限策略(policy)

check_permission / enforce_permission 共用如下策略(全部可选):

字段 类型 说明
allow_write bool 是否允许 DML(INSERT/UPDATE/DELETE),默认 false
allow_ddl bool 是否允许 DDL(CREATE/DROP/ALTER/TRUNCATE),默认 false
allowed_tables list 表白名单(非空时,不在其中的表一律拒绝)
denied_tables list 表黑名单(命中即拒绝,优先级高于白名单)
allowed_columns dict 列级白名单 {表: [列,...]}(仅校验带表限定符的列)
row_filters dict 行级过滤 {表: "条件"},enforce_permission 自动注入 WHERE
max_limit int SELECT 自动补 LIMIT 上限(无 LIMIT 时)

enforce_permission 示例(enforce_permission 工具):

{
  "sql": "SELECT id, amount FROM orders",
  "policy": {
    "allow_write": false,
    "row_filters": { "orders": "tenant_id = 7" },
    "max_limit": 100
  }
}

→ 返回 SELECT id, amount FROM orders WHERE tenant_id = 7 LIMIT 100(行级隔离 + 限流已自动生效)。

Agent 接入配置示例

Claude Desktop / 兼容 MCP 的客户端(claude_desktop_config.json):

{
  "mcpServers": {
    "sqlglot": {
      "command": "python",
      "args": ["/绝对路径/mcp-sqlglot/http/mcp_server.py"]
    }
  }
}

自定义 Agent(stdio 调用骨架):向子进程 stdin 逐行写入 JSON-RPC 消息,读取 stdout 每行响应:

→ {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"agent","version":"1"}}}
← {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"sqlglot-mcp","version":"1.0.0"}}}
→ {"jsonrpc":"2.0","id":2,"method":"tools/list"}
→ {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"enforce_permission","arguments":{"sql":"SELECT * FROM orders","policy":{"row_filters":{"orders":"tenant_id = 7"},"max_limit":100}}}}

http/
├── main.py          # FastAPI 应用与全部 REST 接口
├── mcp_server.py    # MCP Server(stdio JSON-RPC,供 Agent 调用,零额外依赖)
├── core.py          # 核心逻辑(解析/转译/格式化/提取/条件注入/权限校验)
├── requirements.txt # 依赖(fastapi, uvicorn, sqlglot, pydantic, ...)
└── README.md        # 本文档

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured