MCP与数据库
2368 字约 8 分钟
AIAgentMCP数据库
2026-07-24
MCP 可以让 Agent 安全地查询和操作数据库,但数据库接入是 MCP 中安全风险最高的场景之一。需要严格的权限控制、查询安全机制和审计策略。
一、基本定义
MCP 数据库接入是指通过 MCP Server 将数据库的查询和操作能力暴露给 AI 应用。核心设计问题:
- 数据库的哪些能力应该暴露为 Resource(可读取的数据)
- 哪些应该暴露为 Tool(可执行的操作)
- 如何防止 SQL 注入、数据泄漏和越权操作
二、为什么数据库接入需要特别设计
数据库接入的风险远高于一般 MCP 场景:
- SQL 注入可能破坏整个数据库
- 敏感数据可能通过模型上下文泄漏
- 写操作可能不可逆
- 查询性能可能影响生产系统
- 自然语言到 SQL 的转换可能产生意外结果
三、能力划分
数据库作为 Resource
适合暴露为 Resource 的数据:
- Schema 信息(表结构、字段说明)
- 配置数据(枚举值、系统参数)
- 只读报表数据
- 统计摘要
Resource 示例:
- db://schema/tables → 表列表
- db://schema/users → users 表结构
- db://config/enums → 枚举值列表数据库查询作为 Tool
适合暴露为 Tool 的操作:
- SELECT 查询(需要参数化)
- 数据搜索
- 聚合统计
- INSERT/UPDATE(需要授权)
Tool 示例:
- query_users(query, limit) → 搜索用户
- get_order(order_id) → 查询订单
- create_record(table, data) → 创建记录四、读写分离
原则:
- 只读操作使用只读数据库账户
- 写操作使用受限的读写账户
- 删除操作需要额外授权
五、安全设计
风险等级表
| 操作 | 风险等级 | 默认策略 |
|---|---|---|
| 查看 Schema | 低 | 可自动 |
| SELECT 受限查询 | 中低 | 限制行数 |
| 聚合查询 | 中 | 超时和成本限制 |
| INSERT/UPDATE | 高 | 显式授权 |
| DELETE | 很高 | 二次确认 |
| DDL(ALTER, DROP, CREATE) | 极高 | 默认禁止 |
SQL 注入防护
- 永远使用参数化查询,不使用字符串拼接
- 输入参数必须经过类型验证
- 限制查询语句长度
- 禁止多语句执行
- 使用白名单控制允许的查询模式
安全示例(概念示意):
✅ SELECT * FROM users WHERE id = $1 LIMIT $2
❌ SELECT * FROM users WHERE id = " + user_input + "查询白名单
对于高风险场景,可以限制允许的查询模式:
- 只允许 SELECT
- 只允许查询特定表
- 只允许使用特定字段作为条件
- 禁止子查询和 JOIN(如果不需要)
行级权限
- 根据用户身份过滤可访问的数据行
- 多租户场景下严格隔离数据
- 不允许跨租户查询
字段脱敏
敏感字段在返回给模型前需要脱敏:
| 字段类型 | 脱敏策略 |
|---|---|
| 手机号 | 138****1234 |
| 身份证号 | 前6后4 |
| 银行卡号 | 后4位 |
| 密码/密钥 | 不返回 |
| u***@example.com | |
| 地址 | 只返回城市级别 |
六、查询控制
分页
- 所有查询强制分页
- 设置默认和最大页面大小
- 使用 cursor-based 分页避免性能问题
查询超时
- 设置查询超时时间(如 30 秒)
- 慢查询自动终止
- 超时信息返回给模型
最大返回量
- 单次查询最多返回固定行数(如 100 行)
- 超过限制提示使用分页
- 防止大量数据进入模型上下文
查询成本限制
- 监控查询扫描行数
- 限制全表扫描
- 对大表查询强制要求索引条件
七、事务与幂等
事务管理
- 单个 Tool 调用默认在单事务中执行
- 跨 Tool 调用的事务需要特别设计
- 长事务可能导致锁等待
幂等性
- INSERT 操作使用幂等键
- UPDATE 操作使用条件检查
- 重试前检查操作是否已执行
八、审计
审计日志
每次数据库操作应该记录:
- 操作时间
- 操作类型(SELECT/INSERT/UPDATE/DELETE)
- 操作的表
- 查询参数(脱敏后)
- 操作者(用户或 Agent)
- 操作结果
- 耗时
慢查询监控
- 记录执行时间超过阈值的查询
- 分析查询模式
- 优化索引
九、数据库连接管理
连接池
- 使用连接池管理数据库连接
- 限制最大连接数
- 设置连接超时
- 定期健康检查
多租户
- 每个租户使用独立的数据库或 Schema
- 连接级别隔离
- 不允许跨租户查询
数据库类型差异
| 数据库 | 特殊考虑 |
|---|---|
| PostgreSQL | JSON 字段、数组字段处理 |
| MySQL | 字符集、SQL 模式 |
| SQLite | 文件锁、并发限制 |
| MongoDB | 文档结构、嵌套查询 |
十、自然语言到 SQL 的风险
模型生成 SQL 时的特殊风险:
- SQL 注入:模型可能被诱导生成恶意 SQL
- 错误查询:模型可能生成语法正确但逻辑错误的 SQL
- 性能问题:模型可能生成低效查询(全表扫描)
- 数据泄漏:模型可能查询不应该暴露的数据
- 数据破坏:模型可能生成破坏性的 DML/DDL
缓解策略:
- 使用参数化查询而非直接执行模型生成的 SQL
- 对模型生成的 SQL 进行语法和安全检查
- 使用查询白名单
- 只读账户 + 查询超时 + 行数限制
- 写操作需要人工确认
十一、数据库内容中的提示注入
数据库中存储的内容可能包含提示注入:
- 用户输入的评论、描述等字段
- 从外部导入的数据
- 历史日志记录
防护策略:
- 将数据库内容标记为"数据"而非"指令"
- 在返回给模型时添加隔离标记
- 对可疑内容进行过滤
十二、结构化结果
Tool 返回的数据库查询结果应该结构化:
- 列名和类型信息
- 行数统计
- 查询耗时
- 是否还有更多数据
- 格式化为模型可理解的表格或 JSON
十三、设计原则
- 最小权限:使用只读账户,只暴露必要的表和字段
- 参数化查询:永远不拼接 SQL
- 默认禁止写操作:写操作需要显式授权
- 强制分页和限制:防止大量数据和慢查询
- 完整审计:记录所有操作
- 敏感数据脱敏:返回前处理敏感字段
- 超时保护:所有查询设置超时
十四、常见误区
- 让模型直接生成和执行 SQL:应该参数化或白名单
- 使用管理员账户连接数据库:应该使用最小权限账户
- 不限制查询返回量:可能消耗大量 Token 和数据库资源
- 不处理敏感数据:密码、Token 等不应返回给模型
- 忽视审计:出问题无法追溯
- 允许 DDL 操作:DROP、ALTER 等操作应该默认禁止
- 不做查询超时控制:慢查询可能拖垮数据库
十五、实践检查清单
十六、完整示例
KnowledgeOS MCP Server 的数据库接入:
| 能力 | 类型 | 操作 | 风险 |
|---|---|---|---|
| 查看表结构 | Resource | 读取 Schema | 低 |
| 搜索笔记 | Tool | SELECT + 全文搜索 | 中低 |
| 查询标签 | Tool | SELECT DISTINCT | 低 |
| 创建笔记 | Tool | INSERT | 高 |
| 更新笔记 | Tool | UPDATE | 高 |
| 删除笔记 | Tool | DELETE | 很高 |
十七、与其他概念的关系
- MCP基础:数据库接入在 MCP 中的定位
- MCP Server设计:数据库 Server 的设计模式
- MCP安全边界:数据库安全的核心考量
- MCP权限设计:数据库权限的分级设计
- MCP认证与授权:数据库认证方式
- MCP工具接入:数据库操作封装为 Tool
- MCP资源模型:Schema 和配置数据暴露为 Resource
十八、适用边界
适用于:
- 需要 AI 辅助查询和分析数据
- 需要通过自然语言操作数据库
- 需要 Agent 自动化数据处理
不适用于:
- 高并发在线交易系统
- 需要复杂事务管理的场景
- 实时数据流处理
- 大规模数据迁移
十九、参考资料
- MCP 官方规范 - https://modelcontextprotocol.io/specification
- OWASP SQL 注入防护 - https://owasp.org/www-community/attacks/SQL_Injection
- 数据库安全最佳实践 - https://www.cisecurity.org/benchmark/database