一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Database MCP Server 如何默认只读访问 SQLite、MySQL、MariaDB 和 PostgreSQL?

时间:2026-09-13 09:22:01 编辑:袖梨 来源:一聚教程网

database-mcp 是一组面向 SQL 数据库的 MCP Server,每种引擎使用独立安装包,覆盖 SQLite、libSQL、MySQL、MariaDB 和 PostgreSQL。所有包只暴露 execute_sql 与 search_objects 两个工具,默认开启保守 SQL 守卫、数据库会话级只读、返回行数上限和语句超时,并要求连接信息在启动时配置,不能由聊天中的工具调用临时传入。

这种设计的重点不是用一个巨大适配器隐藏所有差异,而是在统一接口下保留各数据库驱动与安全语义。SQLite 用户不必下载 PostgreSQL 驱动,MySQL 与 MariaDB 可以分别发布和测试。TypeScript npm 包与 Python PyPI 包还运行同一套语言无关的一致性测试,避免两种实现逐渐产生不同的安全行为。

为什么每个引擎一个包

数据库驱动通常体积大、依赖不同,并可能包含原生扩展。按引擎拆包能让用户只安装实际需要的代码。

攻击面也更小。SQLite 进程没有连接 MySQL 或 PostgreSQL 的驱动与配置解析路径,不会因无关依赖漏洞受影响。

发布与升级可以独立进行,但必须保持公共行为一致。项目用跨实现一致性测试定义共同契约。

支持的五类数据库

本地 SQLite 适合文件型项目数据库,libSQL 面向兼容 SQLite 的远程服务,MySQL 与 MariaDB 覆盖常见 Web 数据库,PostgreSQL 支持更丰富关系型语法。

它们的只读会话、超时、参数语法和元数据目录不同。统一 execute_sql 名称不能抹掉这些差异。

部署前阅读所选引擎包的 README,并在目标数据库版本运行集成测试,不能只依赖根项目说明。

只有两个工具的价值

execute_sql 执行受控查询,search_objects 渐进探索数据库结构。后者无参数时列出表,指定表后返回列、索引和外键等信息。

小工具表面减少模型上下文占用,也降低误选管理命令的概率。Agent 不需要在十几个相近工具中猜测。

工具少不等于权限天然小。execute_sql 是宽能力入口,仍必须在服务和数据库两层限制。

渐进式模式发现

模型先获取对象列表,再针对相关表请求结构,不必一次把全库 schema 放进上下文。

这样能减少 token 和敏感元数据暴露,也让审计看出 Agent 探索了哪些对象。

search_objects 自身应遵守数据库授权,不返回账号无权查询的 schema、表和列。

默认只读的第一层

保守 SQL 守卫分析输入,拒绝写入、DDL、多语句和无法确认安全的结构。项目特别强调会阻止数据修改 CTE。

例如 WITH 子句内部执行 DELETE,再由外层 SELECT 返回结果,不能因最终语句看起来是读取而放行。

守卫应倾向失败关闭。复杂合法语法被误拒绝,可以通过明确扩展与测试解决,不能把未知输入默认发送到生产。

默认只读的第二层

项目还使用数据库自身的会话级只读设置。即使 SQL 守卫漏判,数据库引擎仍有机会拒绝修改。

具体机制因引擎而异。PostgreSQL 与 MySQL 有事务或会话只读,SQLite 可使用只读连接或文件 URI,远程 libSQL 依赖服务权限。

会话只读仍不能替代最小权限账号。配置错误、驱动差异和未来代码变更都可能削弱这一层。

数据库账号仍需最小权限

网络数据库使用专用只读账号,只授予批准数据库、schema、表或视图的查询权限。

只读防止修改,不防止读取敏感数据。认证、支付、个人信息和内部审计对象应完全排除或通过脱敏视图暴露。

检查函数执行、系统目录、默认权限和角色继承,避免 SELECT 调用高权限函数或跨 schema 访问。

SQLite 的特殊边界

SQLite 没有服务器角色,安全依赖文件系统权限和打开方式。生产只读分析最好使用快照副本,并只读挂载文件与目录。

关闭扩展加载,限制 ATTACH 和进程可访问路径。否则一条查询可能扩大到其他文件或本地代码能力。

数据库文件、WAL、journal 和临时目录都要考虑,不能只把主 db 文件 chmod 为只读。

libSQL 的远程边界

libSQL 使用 URL 与认证 token。网络服务的权限模型、分支与副本行为需要按提供商配置验证。

LIBSQL_AUTH_TOKEN 属于高价值秘密,通过环境或挂载文件提供,不进入 MCP 客户端聊天和日志。

远程连接使用 TLS,并限制 token 到特定数据库与只读操作。服务端权限是会话设置之外的最终边界。

MySQL 与 MariaDB 分开发布

两种数据库高度兼容,但版本、注释、函数、系统目录和只读事务行为并不完全相同。独立包便于针对差异适配。

账号撤销 FILE、PROCESS、管理与写权限,只开放批准表 SELECT。检查视图 SQL SECURITY 和存储函数。

在每个实际版本测试注释、反引号、反斜杠、版本条件注释和 CTE,不把 MySQL 测试结果直接套给 MariaDB。

PostgreSQL 的只读注意点

专用角色只拥有 CONNECT、目标 schema USAGE 与对象 SELECT,不授予超级用户、建库、建角色、复制和绕过行级安全能力。

检查 SECURITY DEFINER 函数、search_path 与 PUBLIC 权限。SELECT 函数可能产生副作用或扩大数据可见范围。

使用只读事务、statement_timeout 和行级安全共同约束,而不是只扫描 SQL 第一个关键词。

默认一千行上限

项目默认把返回行数限制为一千,避免完整大表进入 MCP 响应和模型上下文。

限制应作用于最终结果,并返回截断标记,让模型知道结果不完整。已有 LIMIT、CTE、UNION 和各方言尾部语法都需要测试。

行数上限不限制扫描成本。COUNT、排序和 JOIN 可能返回很少,却读取大量数据。

默认三十秒超时

语句超时防止错误查询长期占用数据库。应由服务器端或驱动取消真实查询,不只是让 MCP 客户端停止等待。

超时后回滚事务、关闭游标并归还干净连接。坚控数据库活动,确认没有后台残留语句。

还要限制连接池、并发和累计查询额度。大量短查询同样可能造成资源压力。

启动时配置而非聊天配置

连接详情来自命令参数、YAML 或环境变量,工具调用不接受临时 DSN。这样模型不能把服务改连到任意数据库。

配置由操作者或部署系统控制,和不可信提示隔离。连接变更需要重启或受控配置流程。

启动后工具响应不回显完整 DSN、密码和 token,只显示必要的数据库标识。

SQLite 快速启动

npm 用户可以启动 @database-mcp/sqlite,并通过 --dsn 指定绝对数据库文件路径。

npx -y @database-mcp/sqlite --dsn /absolute/path/to/database.db

Python 路线使用 uvx 与 database-mcp-sqlite。两种实现的标志、环境变量和 YAML 配置保持一致。

生产固定具体版本,不使用长期浮动最新版。路径指向只读副本,并限制工作目录权限。

网络数据库的秘密来源

MySQL、MariaDB、PostgreSQL 和 libSQL 支持各自环境变量,也支持 DATABASE_URL 等入口。

项目遵循容器秘密惯例,允许 MYSQL_PASSWORD_FILE 这类变量指向挂载文件。密码无需进入桌面客户端 JSON。

Kubernetes Secret 挂载目录只对容器用户可读,禁止应用把文件内容打印到启动日志。

YAML 环境变量展开

配置可引用环境变量,便于把非秘密结构与秘密分离。缺失必需变量时应启动失败。

展开后的配置不能写回磁盘或出现在调试输出。配置校验错误只显示字段名,不显示值。

生产策略禁止秘密使用弱默认值,避免环境注入失败后连接到意外账号。

秘密类型与日志边界

项目称密码保存在不可打印的秘密类型中,DSN 记录前会清洗,并在日志出口增加统一脱敏过滤器。

多层设计避免某个调用点忘记脱敏。任何对象格式化、错误堆栈或驱动消息经过日志边界时都再次过滤。

脱敏不能只替换固定字段。URL 编码密码、连接串副本和嵌套错误对象都要覆盖。

诱饵密码 CI 测试

作者说明在 CI 中植入 canary 密码,运行日志路径后断言该值从未出现。这把“秘密不进日志”从承诺变成回归测试。

测试应覆盖成功连接、认证失败、配置错误、超时、驱动异常和调试级日志,因为泄露常发生在错误路径。

还要测试 URL 编码、特殊字符和部分掩码,防止只匹配原始字符串而漏掉变体。

TypeScript 与 Python 双实现

每个引擎同时发布 npm 与 PyPI 包,方便不同运行环境。两条实现线会增加行为漂移风险。

同一份语言无关一致性套件对真实数据库验证工具 schema、只读、行数、超时和传输行为,使共同契约可执行。

某个修复只有在受影响服务器通过 conformance/run.mjs 后才能合并,测试结果比 README 描述更接近实际行为。

为什么要用真实数据库测试

mock 驱动无法证明数据库会话只读、超时取消和方言语法真实生效。CI 连接真实引擎能验证端到端路径。

测试应尝试普通写入、DDL、数据修改 CTE、多语句和副作用函数,并确认数据库状态没有变化。

版本矩阵仍需覆盖生产使用的主要版本。单一最新镜像不能代表所有兼容环境。

两种传输的一致性

项目在 stdio 与 Streamable HTTP 上运行同一一致性套件。安全策略不能因传输不同而缺失。

本地单客户端优先 stdio,减少端口。远程 HTTP 需要 TLS、身份验证、授权、限流和代理隔离。

工具结果、错误代码、超时和秘密脱敏在两种传输下应一致。

读取结果中的提示注入

SQL 只读不代表返回内容可信。数据库文本可能包含诱导模型改变规则或调用其他工具的指令。

宿主把结果标记为不可信数据,禁止其改变连接、权限和审批。跨工具动作重新经过独立授权。

最小对象权限与行数上限能缩小暴露,但不能替代 Agent 编排层防护。

生产验收测试

分别安装目标引擎的 npm 与 Python 包,核对只暴露两个工具且 schema 一致。

尝试 DML、DDL、多语句、修改 CTE、危险函数和方言边界,确认 SQL 守卫与数据库账号独立拒绝。

执行大结果和慢查询,确认一千行与三十秒默认值真实生效,响应带截断状态,服务器没有残留会话。

植入唯一秘密,触发所有错误路径并扫描 stdout、stderr、日志和 MCP 响应,确认没有明文或编码变体。

核验包来源与 provenance

项目把 npm 包发布在 database-mcp 组织下,Python 包使用相应的 database-mcp 前缀,并在 MCP Registry 列出两种安装方式。安装前核对包名、发布者、仓库链接和版本,避免同名仿冒。

生产锁定精确版本和完整性摘要,不让 npx、uvx 或依赖解析在每次启动时自动选择新版本。供应链升级先在隔离数据库运行一致性测试和秘密扫描。

包 provenance 可以证明发布流程与源码仓库的关联,但不能证明代码没有安全缺陷。仍要审查依赖、安装脚本、权限请求和实际构建产物。

配置优先级必须明确

同一连接可能同时出现在命令参数、YAML 和环境变量中。如果覆盖顺序不清楚,操作者看到的只读账号可能被另一来源替换。

部署规范只选择一种主要配置来源,启动时输出脱敏后的有效配置摘要,例如引擎、主机别名、数据库名、只读状态、行数与超时,不显示密码。

配置文件和环境缺失时失败关闭。不能自动连接本机默认数据库,也不能从工作目录加载未审查文件。

客户端项目配置可能被仓库内容修改,用户级配置又可能覆盖项目值。上线测试从实际子进程环境与启动参数核对,而不是只读某一个 JSON。

跨语言版本如何保持同步

TypeScript 与 Python 包应对同一输入返回等价的 MCP 内容、结构化字段、错误代码和截断标识。仅都能执行 SELECT 不足以称为一致。

安全修复需要同时确认两条实现线。若某语言版本尚未修复绕过,应暂停该包发布或在注册表标出最低安全版本。

一致性套件的测试向量独立于实现语言,包含合法与拒绝样例。新增方言特性时先扩展契约,再分别修改实现,避免根据某一代码库反向定义规则。

失败关闭怎么测试

让 SQL 守卫抛出异常、只读会话设置失败、超时配置无效、秘密文件不可读和日志过滤器初始化失败,服务都应拒绝启动或拒绝查询。

不能在数据库不支持某个会话命令时静默跳过第二层只读。若某引擎只能依赖文件权限或账号角色,应在启动诊断中明确显示已验证的替代边界。

查询过程中断网络、终止客户端和取消请求,确认数据库端事务结束、游标关闭且连接不带污染状态返回池中。

日志系统故障通常不应泄露秘密或阻塞所有低风险读取,但高保证审计场景可以选择失败关闭。该选择需要显式配置并纳入演练。

如何选择 npm 或 Python

已有 Node.js 工具链和桌面客户端时,npm 包安装路径直接;Python 环境可用 uvx 隔离运行。选择依据运维标准,而不是功能差异。

无论哪条路线,都用专用运行用户、最小环境变量和只读工作目录。不要在同一客户端同时启用两套指向相同数据库的实例,避免重复工具和审计混淆。

迁移实现语言时,用同一测试库执行 conformance,并比较工具 schema、拒绝原因、超时与日志,再切换生产配置。

统一接口不应隐藏数据类型差异

SQLite 的动态类型、MySQL 的无符号整数、MariaDB 扩展类型和 PostgreSQL 数组、JSON、时间类型在序列化时可能不同。

execute_sql 响应应稳定表达 null、二进制、大整数、日期和时区,避免模型因字符串化丢失精度。敏感二进制字段与大对象默认不返回。

search_objects 返回引擎原生类型与约束,同时提供统一字段。Agent 需要知道差异,不能假设所有数据库都支持同一 DDL 或查询语法。

上线检查清单

确认只安装所需引擎包,固定 TypeScript 或 Python 版本,生产数据库版本通过一致性与负向测试。

确认 SQL 守卫与数据库会话只读同时开启,连接账号只有批准对象的读取权限。

确认连接信息只在启动时配置,密码使用环境或挂载文件,不进入聊天、项目配置和日志。

确认行数、语句超时、并发和响应字节上限适合负载,读取结果按不可信数据处理。

确认 stdio 与 HTTP 行为一致,远程入口有认证与网络隔离,升级后复跑真实数据库测试。

database-mcp 用“每个引擎一个包、每个包两个工具”保持依赖与工具表面精简,再用 SQL 守卫和数据库会话设置实现双层只读,以行数和超时限制资源,以统一一致性套件约束 TypeScript 与 Python 行为。它的可靠性来自这些层共同验证,而不是抽象地宣称跨库通用。配合最小权限账号和秘密管理,才能在 SQLite、libSQL、MySQL、MariaDB 与 PostgreSQL 上获得一致且可审计的只读访问。

热门栏目