MCP SQL Bridge:为AI助手安全连接本地数据库,实现智能数据查询
1. 项目概述:为你的AI助手装上数据库的“眼睛”
如果你和我一样,日常开发中有一半的时间都在和数据库打交道,那你肯定也经历过这样的场景:想快速查一下某个表的结构,或者写个稍微复杂点的联表查询,都得在IDE、数据库客户端和文档之间来回切换,效率低不说,还容易出错。特别是当你需要向AI助手(比如Cursor里的AI或者Claude)咨询一个涉及具体业务数据的问题时,你只能干巴巴地描述“我有一个用户表,里面大概有ID、名字、邮箱……”,AI助手因为看不到真实的数据结构,给出的建议往往隔靴搔痒。
这就是我最初开发MCP SQL Bridge(也叫Local-SQL-Insight)的动机。它的核心目标非常简单:让AI助手能够安全、直接地“看到”你的本地数据库。不是通过调用某个遥远的API,也不是把你的数据上传到云端,而是通过一个名为Model Context Protocol (MCP)的本地通信协议,在你的机器上建立一个只读的数据通道。这样一来,当你在Cursor里问“帮我写个SQL,统计一下上个月活跃用户的订单总额”时,AI助手能直接列出你的users表和orders表,看到真实的字段名和类型,甚至能读取你项目里的README.md来理解业务背景,然后生成一个几乎可以直接运行的、语法正确的SQL查询。
这个工具本质上是一个MCP服务器。你可以把它理解为一个“翻译官”,它一端连接着你的SQL数据库(SQLite、PostgreSQL、MySQL),另一端通过标准输入输出(stdio)连接着支持MCP的AI应用(如Cursor、Claude Desktop)。它只做一件事:在严格的只读权限下,把数据库的“世界”翻译给AI助手听。你的数据全程不会离开你的电脑,这既是出于安全考虑,也是为了极致的响应速度。
2. 核心设计思路:安全、透明与上下文感知
在设计之初,我就明确了几个不可妥协的原则,这些原则直接决定了工具的技术选型和架构。
2.1 安全第一:只读是底线,而非可选项
对于任何涉及生产数据或敏感信息的工具,“安全”必须是刻在骨子里的基因。MCP SQL Bridge从设计上就杜绝了任何写入操作的可能性。它只暴露两个核心工具:list_tables(列出表结构)和execute_readonly_query(执行只读查询)。底层实现上,所有SQL语句在执行前都会经过严格的语法解析和校验,确保只有SELECT语句能被放行。任何包含INSERT、UPDATE、DELETE、DROP等关键词的语句都会被直接拦截并返回明确的错误信息。
实操心得:语法校验的坑早期版本我尝试用简单的字符串匹配来检查
SELECT关键字,结果很快就被绕过了,比如SELECT * FROM users; DROP TABLE users;。后来改用了更可靠的SQL解析库(如sqlparse),先将语句标准化、去除注释,再判断其第一个有效关键字是否为SELECT,这才算堵住了漏洞。这让我明白,安全功能绝不能依赖“想当然”的实现。
2.2 上下文即王道:给AI注入“业务记忆”
一个只知道表名和字段类型的AI,就像一个只认识单词但不理解语法的翻译,很容易闹笑话。为了让AI助手真正理解你的数据,MCP SQL Bridge做了两件事:
- 提供完整的DDL(数据定义语言):
list_tables工具返回的不仅仅是表名和列名,还包括完整的CREATE TABLE语句。这意味着AI能知道某个字段是否是主键、外键,是否有唯一约束、默认值,甚至是字段注释。这些信息对于生成正确的JOIN条件和WHERE子句至关重要。 - 暴露项目README作为资源:这是我认为最巧妙的一个设计。工具会将服务器当前工作目录下的
README.md文件作为一个“资源”提供给AI。你可以在这个README里写下数据库的用途、核心业务实体解释、重要的命名约定、数据字典,甚至是常见的查询陷阱。例如,你可以写上:“注意:orders表中的status字段,1代表‘待支付’,2代表‘已发货’,99代表‘已取消’。” 这样,AI在生成查询时就能直接使用这些业务术语,而不是冷冰冰的数字代码。
2.3 多数据库支持与无网络架构
为了适应不同的开发环境,工具原生支持SQLite,并通过“Pro”特性(安装额外依赖)支持PostgreSQL和MySQL。连接方式通过一个简单的backend参数和connection_string(或SQLite的db_path)来切换,非常灵活。
传输层选择了MCP标准的stdio(标准输入输出)传输。这意味着服务器和AI主机(如Cursor)之间的通信就像在命令行里运行一个脚本一样,通过管道传递JSON数据,不需要打开任何网络端口,也无需处理复杂的认证和防火墙问题。这种“零配置”的本地通信方式,极大地降低了使用门槛和潜在的攻击面。
3. 从零开始:环境搭建与快速启动
理论说再多,不如动手跑起来。下面我会带你一步步完成从克隆代码到在Cursor中实际调用的全过程,并分享我踩过的坑和最佳实践。
3.1 基础环境准备
首先,确保你的系统满足最低要求:
- Python 3.11+:这是硬性要求,因为项目用到了一些较新的语法特性。可以用
python --version检查。 - Poetry:这是推荐的依赖管理工具。用
pip install poetry或根据官方文档安装。 - Git:用于克隆代码库。
注意事项:Python版本管理强烈建议使用
pyenv、conda或venv来管理Python版本。避免系统自带的Python,也避免多个项目共用同一个全局环境,否则依赖冲突会让你头疼不已。我个人的习惯是为每个项目创建一个独立的虚拟环境。
3.2 克隆与安装
打开终端,执行以下命令:
# 克隆项目代码 git clone https://github.com/firas-mcp-servers/mcp-sql-bridge.git cd mcp-sql-bridge # 使用Poetry安装核心依赖(这会自动创建虚拟环境) poetry install这一步会安装所有运行MCP SQL Bridge服务器所必需的基础包。
如果你想体验多数据库(Pro)功能,比如连接PostgreSQL或MySQL,需要在安装时指定额外的依赖组:
# 安装PostgreSQL支持 poetry install --extras postgres # 或安装MySQL支持 poetry install --extras mysql # 或者一次性安装所有Pro功能 poetry install --extras pro安装完成后,你可以通过poetry run mcp-sql-bridge --help来验证安装是否成功,并查看命令行参数。
3.3 可选:启动本地Web服务器
项目还贴心地附带了一个基于FastAPI的轻量级Web服务器。它主要提供三个功能:
- 一个简单的落地页,展示服务信息。
- 交互式API文档(Swagger UI),方便你手动测试工具调用。
- 项目文档站点(需要预先构建)。
如果你好奇MCP服务器背后是如何工作的,或者想手动调试,启动它很有帮助:
# 安装Web服务器所需的额外依赖 poetry install --with web # (可选)构建静态文档站点 mkdocs build # 启动Web服务器 poetry run mcp-sql-bridge-web启动后,在浏览器中打开http://localhost:8000即可访问。/docs是Swagger界面,你可以在这里直接尝试调用list_tables等工具,非常直观。
4. 深度集成:配置Cursor与Claude Desktop
安装好服务器只是第一步,接下来需要让它和你日常使用的AI工具“握手”。下面以最常用的Cursor和Claude Desktop为例,详细讲解配置过程。
4.1 与Cursor集成:让IDE内的AI拥有数据视野
Cursor是目前对MCP支持最完善的IDE之一。集成过程本质上是修改Cursor的MCP配置文件,告诉它:“嘿,我本地有一个叫local-sql-insight的服务器,这是启动它的命令。”
步骤一:定位或创建配置文件Cursor的MCP配置有两种作用域:
- 全局配置:对所有项目生效。文件位于:
- macOS/Linux:
~/.cursor/mcp.json - Windows:
%APPDATA%\Cursor\mcp.json
- macOS/Linux:
- 项目级配置:仅对当前项目生效。在项目根目录下创建
.cursor/mcp.json。
对于数据库工具,我强烈推荐使用项目级配置。因为不同项目的数据库连接信息(SQLite文件路径、PostgreSQL连接串)很可能不同。项目级配置可以跟着代码库走,方便团队共享。
步骤二:编写配置文件项目仓库里已经提供了一个非常标准的模板文件mcp-config.json。我们直接基于它修改。核心是args和cwd这两个字段。
{ "mcpServers": { "local-sql-insight": { "command": "poetry", "args": ["run", "mcp-sql-bridge"], "cwd": "/绝对路径/到/你的/mcp-sql-bridge项目目录" } } }关键点解析:
command: “poetry”:告诉Cursor使用Poetry来执行命令。args: [“run”, “mcp-sql-bridge”]:这是Poetry的命令,意思是在项目虚拟环境中运行mcp-sql-bridge这个命令。cwd:这是最容易出错的地方。必须填写mcp-sql-bridge项目目录的绝对路径。Cursor会在这个路径下执行上述命令。如果你填的是相对路径或者当前项目的路径,Cursor会找不到pyproject.toml和虚拟环境,导致启动失败。
踩坑实录:路径与虚拟环境我第一次配置时,
cwd填的是我业务项目的路径,结果Cursor报错“Poetry not found”。原因是Poetry和虚拟环境是安装在mcp-sql-bridge目录下的。另一个常见错误是在Windows上使用了反斜杠\和驱动器号(如C:\),但在JSON中,路径需要转义或使用正斜杠/。最稳妥的方法是直接复制终端里pwd命令的输出。
步骤三:重启与验证保存好.cursor/mcp.json文件后,必须完全关闭并重新启动Cursor。MCP服务器只在Cursor启动时加载。 重启后,你可以在Cursor的Chat界面中,尝试让AI助手“列出可用的工具”。如果配置成功,你应该能看到list_tables和execute_readonly_query这两个工具。至此,集成完成。
4.2 与Claude Desktop集成:桌面AI的本地数据伴侣
Claude Desktop的集成逻辑与Cursor类似,但配置文件的位置和格式略有不同。
步骤一:找到配置文件
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
如果文件不存在,可以手动创建。
步骤二:添加服务器配置编辑这个JSON文件,添加mcpServers部分。这里我推荐另一种更稳定的配置方式:直接指向虚拟环境中的可执行文件,避免依赖Poetry。
{ "mcpServers": { "local-sql-insight": { "command": "/绝对路径/到/mcp-sql-bridge/.venv/bin/mcp-sql-bridge", "args": [] } } }配置方式对比:
- 方式A(使用Poetry):和Cursor配置一样,依赖
poetry命令和正确的cwd。好处是统一。 - 方式B(直接指向可执行文件):如上例所示。你需要找到项目虚拟环境下
mcp-sql-bridge脚本的绝对路径。这种方式更直接,不依赖外部poetry命令,启动更稳定。你可以通过poetry env info --path命令查看虚拟环境路径,然后拼接上bin/mcp-sql-bridge(Windows下是Scripts\mcp-sql-bridge.exe)。
步骤三:重启与测试保存配置文件,重启Claude Desktop。之后,你就可以在对话中让Claude使用SQL工具了。
5. 核心功能实战:与AI协作查询数据库
配置妥当后,我们来看看如何在实际对话中与AI助手协作。这里我假设我们有一个简单的电商数据库ecommerce.db(SQLite),里面包含users和orders两张表。
5.1 场景一:探索未知数据库结构
当你接手一个新项目,或者想快速了解某个数据库时,可以让AI帮你“看看”。
你对AI说:“请使用Local-SQL-Insight工具,列出./ecommerce.db这个SQLite数据库中的所有表。”
AI助手的操作与回应:
- AI会调用
list_tables工具,参数为{“db_path”: “./ecommerce.db”}。 - MCP服务器连接到该数据库,获取元数据,并返回类似下面的结构化信息:
找到 2 张表: 1. 表名: users - 列: id (INTEGER, PRIMARY KEY), username (TEXT), email (TEXT, UNIQUE), created_at (TEXT) - DDL: CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT, email TEXT UNIQUE, created_at TEXT); 2. 表名: orders - 列: order_id (INTEGER, PRIMARY KEY), user_id (INTEGER, FOREIGN KEY REFERENCES users(id)), amount (REAL), status (TEXT), order_date (TEXT) - DDL: CREATE TABLE orders (order_id INTEGER PRIMARY KEY, user_id INTEGER, amount REAL, status TEXT, order_date TEXT, FOREIGN KEY(user_id) REFERENCES users(id));你能得到什么:
- 瞬间掌握了数据库的核心实体。
- 看到了完整的表结构,包括字段类型、主键、外键约束。这比单纯看列名有用得多。
5.2 场景二:编写复杂业务查询
现在你想分析数据,但不确定SQL怎么写。
你对AI说:“我想统计每个用户的订单总金额,并列出用户名,按总金额从高到低排序,只要前10名。请帮我写这个查询并执行。”
AI助手的思考与操作:
- 理解需求:AI已经通过之前的
list_tables知道了表结构,它知道需要关联users和orders表,按user_id分组,对amount求和。 - 生成SQL:AI会生成类似下面的SQL:
SELECT u.username, SUM(o.amount) as total_amount FROM users u JOIN orders o ON u.id = o.user_id GROUP BY u.id, u.username ORDER BY total_amount DESC LIMIT 10; - 调用工具执行:AI调用
execute_readonly_query工具,参数为{“db_path”: “./ecommerce.db”, “query”: “上面生成的SQL”}。 - 返回结果:服务器执行查询,并将结果以清晰的表格文本格式返回给AI,AI再呈现给你。
| username | total_amount | |----------|--------------| | alice | 12500.50 | | bob | 8920.75 | | charlie | 4567.30 | | ... | ... |效率提升:你无需手动打开数据库客户端、编写、调试SQL。整个流程在聊天界面中一气呵成,尤其适合探索性数据分析。
5.3 场景三:利用业务README提供深度上下文
假设你的orders.status字段用的不是英文,而是业务代码:‘P’代表待支付,‘S’代表已发货,‘C’代表已完成。你可以把这些信息写在项目根目录的README.md里。
README.md 片段:
## 数据库业务说明 - **orders表状态码**: - `P`: Paid (待支付) - `S`: Shipped (已发货) - `C`: Completed (已完成) - **关键业务规则**: 只有状态为`C`的订单才计入最终业绩报表。你对AI说:“帮我查一下上周已完成的订单总额。”
AI助手的增强操作:
- AI不仅通过
list_tables看到了orders表有status字段,还会自动读取README.md资源。 - AI从README中学习到状态码
C代表“已完成”。 - AI生成精准的SQL:
SELECT SUM(amount) FROM orders WHERE status = ‘C’ AND order_date >= date(‘now’, ‘-7 days’); - 调用工具执行并返回结果。
这就是“上下文感知”的力量:AI不再是机械地操作数据,而是像一个真正理解你业务的新手同事,能根据你提供的文档做出正确判断。
6. 高级用法与多数据库支持
对于更复杂的生产环境或使用多种数据库的开发者,MCP SQL Bridge的“Pro”特性提供了强大的支持。
6.1 连接PostgreSQL与MySQL
连接非SQLite数据库时,你需要提供两个关键参数:
backend: 指定数据库类型,“postgres”或“mysql”。connection_string: 标准的数据库连接URL。
PostgreSQL连接示例:
{ “backend”: “postgres”, “connection_string”: “postgresql://myuser:mypassword@localhost:5432/mydatabase” }安全提示:在生产环境或团队共享配置中,永远不要将密码明文写在配置文件里。应该使用环境变量,或者利用MCP主机(如Cursor)支持的环境变量注入功能。连接字符串可以写为
postgresql://myuser@localhost:5432/mydatabase,然后通过PGPASSWORD环境变量或.pgpass文件提供密码。
MySQL连接示例:
{ “backend”: “mysql”, “connection_string”: “mysql://myuser:mypassword@localhost:3306/mydatabase” }6.2 在Cursor中配置多数据库连接
你可以在项目的.cursor/mcp.json中预定义多个“配置”,方便快速切换。这需要对MCP配置格式有更深的理解。项目examples/目录下提供了高级配置模板(mcp-config-pro.json)。
其核心思想是利用MCP的“参数化工具”概念。你可以在配置中为工具预设几组不同的参数(如db1_config,db2_config),然后在对话中直接让AI使用某个配置。例如,你可以预设一个连接生产只读副本的配置和一个连接本地测试库的配置。
6.3 其他实用工具详解
除了两个核心工具,服务器还提供了一些辅助工具,在特定场景下非常有用:
schema_summary: 当你有一个包含几十张表的大型数据库时,list_tables的输出可能太长。这个工具会生成一个更紧凑的概览,只列出表名和关键列,帮你快速定位感兴趣的表。sample_rows: 在编写查询条件时,知道字段里具体有什么值至关重要。这个工具可以快速获取指定表的若干行样本数据,让你了解数据格式和分布。explain_database: 这个工具会尝试让AI(服务器端)基于schema信息,生成一段对数据库用途和关系的描述,对于理解陌生数据库很有帮助。suggest_indexes_for_query: 输入一个SELECT查询,它会基于启发式规则(如WHERE子句中的字段、JOIN条件)给出潜在的索引建议。请注意,这只是建议,实际创建索引前需要仔细评估。
7. 故障排除与常见问题实录
即使设计得再完善,在实际操作中总会遇到各种问题。下面是我在开发和日常使用中总结的一些典型故障和解决方法。
7.1 服务器启动失败
问题现象:Cursor或Claude Desktop提示无法连接MCP服务器,或日志中出现启动错误。
- 检查点1:路径是否正确?
- 症状:错误信息包含“No such file or directory”、“Poetry not found”或“Invalid working directory”。
- 解决:反复检查配置文件中的
cwd或command路径是否为绝对路径,并且指向正确的mcp-sql-bridge项目根目录。在终端中进入该目录执行pwd,复制输出结果。
- 检查点2:依赖是否安装?
- 症状:错误信息提到缺失模块,如
ImportError: No module named ‘mcp’。 - 解决:确保在项目目录下正确运行了
poetry install。如果配置中直接指向可执行文件,请确认虚拟环境已激活且安装成功。
- 症状:错误信息提到缺失模块,如
- 检查点3:Python版本是否兼容?
- 症状:语法错误,特别是与类型注解相关的错误。
- 解决:确认当前环境Python版本≥3.11。使用
poetry env info检查虚拟环境使用的Python解释器。
7.2 工具调用失败或返回空
问题现象:AI可以列出工具,但调用时失败,或返回的结果为空。
- 检查点1:数据库文件路径与权限
- 症状:
list_tables返回错误,提示文件不是数据库或无法打开。 - 解决:
- 相对路径问题:配置中的
db_path是相对于MCP服务器工作目录(即cwd)的。如果你在/home/user/projectA配置了服务器,但db_path写的是../projectB/data.db,服务器会在/home/user/projectA/../projectB/data.db找文件。最稳妥的方法是使用绝对路径。 - 文件权限:确保运行Cursor/Claude的用户有读取该数据库文件的权限。
- SQLite文件有效性:用
sqlite3 your.db “.schema”命令验证文件是否有效。
- 相对路径问题:配置中的
- 症状:
- 检查点2:网络数据库连接问题
- 症状:连接PostgreSQL/MySQL时超时或认证失败。
- 解决:
- 网络可达:确保
localhost和端口(5432/3306)可以从运行MCP服务器的主机访问。如果数据库在Docker容器或远程主机,需相应调整主机地址。 - 认证信息:检查用户名、密码、数据库名是否正确。尝试用相同的连接字符串使用
psql或mysql命令行客户端连接,以排除基础连接问题。 - 防火墙/SELinux:有时本地防火墙规则会阻止连接。
- 网络可达:确保
- 检查点3:SQL查询语法错误
- 症状:
execute_readonly_query返回SQL语法错误。 - 解决:这通常是AI生成的SQL有误。仔细阅读错误信息,它通常会指出错误位置。你可以将AI生成的SQL复制到数据库客户端中手动执行调试,然后将修正后的逻辑反馈给AI。
- 症状:
7.3 AI助手“看不到”工具
问题现象:让AI列出工具,它说没有可用的工具。
- 检查点1:配置是否生效?
- 解决:修改MCP配置后,必须完全重启Cursor或Claude Desktop。仅仅重启插件或刷新页面是没用的。
- 检查点2:配置格式是否正确?
- 解决:检查你的JSON配置文件格式是否合法。可以使用在线JSON校验工具。确保没有多余的逗号,引号匹配。
- 检查点3:服务器进程是否在运行?
- 解决:查看Cursor/Claude Desktop的日志(通常可以在设置中找到“打开日志目录”的选项)。日志中可能会有MCP服务器启动失败的具体原因。
7.4 性能问题
问题现象:查询响应慢,或者AI调用工具超时。
- 检查点1:查询本身是否复杂?
- 解决:对于大数据表,没有索引的复杂聚合或全表扫描会很慢。尝试让AI先使用
sample_rows查看数据量,或使用EXPLAIN命令(可以通过execute_readonly_query执行)分析查询计划。考虑为常用查询条件添加索引。
- 解决:对于大数据表,没有索引的复杂聚合或全表扫描会很慢。尝试让AI先使用
- 检查点2:是否是第一次连接?
- 解决:连接远程数据库或大型SQLite文件时,首次建立连接可能会有延迟。后续查询会快很多。
- 检查点3:结果集是否过大?
- 解决:MCP协议和AI上下文窗口对返回文本大小有限制。如果查询结果行数太多,可能导致传输缓慢甚至被截断。让AI在查询中主动加上
LIMIT子句来控制返回的数据量。
- 解决:MCP协议和AI上下文窗口对返回文本大小有限制。如果查询结果行数太多,可能导致传输缓慢甚至被截断。让AI在查询中主动加上
8. 安全加固与生产环境考量
虽然MCP SQL Bridge设计为只读且本地运行,但在涉及敏感数据时,仍需保持警惕。
8.1 最小权限原则
- 对于PostgreSQL/MySQL:在数据库中专门创建一个只读用户,用于MCP连接。这个用户的权限应该仅限于对需要查询的表执行
SELECT操作,甚至可以通过视图(VIEW)来进一步限制其可访问的数据列。-- PostgreSQL示例:创建只读用户 CREATE USER mcp_readonly WITH PASSWORD ‘strong_password’; GRANT CONNECT ON DATABASE mydb TO mcp_readonly; GRANT USAGE ON SCHEMA public TO mcp_readonly; GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_readonly; - 对于SQLite:确保数据库文件本身的操作系统级访问权限仅限于必要的用户。避免将包含敏感信息的SQLite文件放在Web可访问的目录下。
8.2 连接信息保密
- 绝不硬编码密码:如前所述,连接字符串中的密码应通过环境变量传递。可以利用MCP主机(如Cursor)的配置能力,在配置文件中引用环境变量,例如
“connection_string”: “postgresql://myuser:${DB_PASSWORD}@localhost/mydb”(具体语法取决于主机实现)。 - 使用配置文件模板:在团队中共享配置时,提供一份
mcp-config.example.json模板,将敏感字段用占位符(如<YOUR_DB_PASSWORD>)替换,并加入.gitignore,防止误提交。
8.3 输入验证与错误处理
MCP SQL Bridge本身已经做了大量输入验证(如SQL注入防护、路径遍历防护)。但作为使用者,你也应该:
- 谨慎对待AI生成的动态查询:虽然工具只允许
SELECT,但一个恶意的SELECT语句(如复杂笛卡尔积)仍可能耗尽数据库资源。在非常重要的生产数据环境,可以考虑使用更严格的数据库权限或在测试库中先行验证。 - 审查
README.md内容:记住,README.md的内容会被AI完全读取。确保其中不包含任何真正的敏感信息,如API密钥、内部IP地址等。
8.4 网络隔离
尽管MCP SQL Bridge使用本地stdio通信,但如果你连接的是远程数据库(如公司的测试数据库),那么网络通信仍然是存在的。确保网络通道是安全的(如使用SSH隧道、数据库SSL连接),尤其是在不可信的网络环境中。
最后,工具的价值在于提升效率,而非替代严谨性。对于涉及核心业务逻辑或财务数据的查询,即使有AI辅助,也建议在最终执行前,由开发者进行人工复核。将MCP SQL Bridge视为一个强大的“副驾驶”,它能帮你快速探索、起草和验证想法,但方向盘和最终决策权,始终应该掌握在你自己手中。
