数据操作工具
MCP 服务向 AI 代理暴露七个 DML(数据操作语言)工具。这些工具构成了一个类型化的 CRUD 操作表面,代理通过它们安全地与数据库交互,所有操作都受到权限配置的约束。
工具概览
| 工具 | 操作 | 适用对象 |
|---|---|---|
describe_entities | 发现可用实体和字段 | 全部 |
read_records | 查询数据 | 表、视图 |
create_record | 创建记录 | 表 |
update_record | 更新记录 | 表、视图 |
delete_record | 删除记录 | 表、视图 |
execute_entity | 执行存储过程 | 存储过程 |
aggregate_records | 聚合查询 | 表、视图 |
代理通过 tools/list 发现工具,通过 tools/call 执行操作。引擎根据调用参数生成确定性的 SQL,代理不需要理解 SQL 语法。
describe_entities — 发现数据 schema
这是代理最常用的入口工具。它列出当前角色有权限访问的所有实体及其字段、描述和可执行操作。
代理调用 describe_entities
↓
返回实体列表 + 字段 schema + 描述 + 操作权限
↓
代理根据用户意图匹配实体和字段
↓
代理调用 read_records / create_record 等工具describe_entities 返回的实体范围取决于当前角色——只有该角色有至少一个操作权限的实体才会出现。这确保了代理不会看到无权访问的数据。
参数
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
nameOnly | boolean | 否 | 为 true 时仅返回实体名和描述,不返回字段元数据 |
entities | string 数组 | 否 | 仅返回指定实体,省略时返回全部启用 MCP 的实体 |
NOTE
当前响应中只包含来自配置的字段 name 和 description。数据类型和主键标志暂不会出现在响应中,存储过程参数也不会列出。代理需要依靠实体与字段说明,以及错误反馈,来推断正确用法。
read_records — 查询数据
{
"entity": "Product",
"filter": { "UnitPrice": { "gt": 50 }, "Discontinued": { "eq": false } },
"orderBy": { "UnitPrice": "DESC" },
"first": 20
}支持的查询能力:
filter:条件筛选,OData 风格表达式。orderby:排序,必须是字符串数组(如["Price desc", "Name asc"]),传入单个字符串会触发UnexpectedError。first/after:游标分页,后续还有结果时响应中包含after游标。select:字段选择,只返回指定字段。
NOTE
read_records 为单表或单视图设计,不支持 JOIN 操作。复杂查询推荐使用视图替代,或通过 execute_entity 执行存储过程封装参数化查询。
未指定参数时返回所有可访问字段、默认分页大小(100 条)。
create_record — 创建记录
{
"entity": "Product",
"data": {
"ProductName": "新产品",
"UnitPrice": 99.9,
"UnitsInStock": 100
}
}data 对象中的键为实体的 API 字段名(alias 或原始字段名)。创建成功返回新记录。
update_record — 更新记录
{
"entity": "Product",
"keys": { "ProductID": 42 },
"fields": {
"UnitPrice": 129.9
}
}keys 指定要更新的记录,fields 中只传需要更新的字段。未传字段保持原值。
delete_record — 删除记录
{
"entity": "Product",
"keys": { "ProductID": 42 }
}按主键删除单条记录。
execute_entity — 执行存储过程
{
"entity": "GetOrdersByDateRange",
"parameters": {
"StartDate": "2024-01-01",
"EndDate": "2024-12-31",
"CustomerID": null
}
}parameters 对象中的键为存储过程参数名。有默认值的参数可以省略。只返回第一个结果集。
aggregate_records — 聚合统计
{
"entity": "Product",
"function": "avg",
"field": "UnitPrice",
"filter": "Discontinued eq false",
"groupby": ["CategoryID"],
"having": { "gt": 2 },
"orderby": ["count desc"],
"first": 10
}支持 count、sum、avg、min、max 聚合函数。对 count 可使用 "*" 作为 field。聚合查询受独立超时设置控制(aggregate-records.query-timeout,1–600 秒,默认 30)。仅 SQL Server 支持。
参数
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
entity | string | 是 | 要聚合的实体名 |
function | string | 是 | 聚合函数:count、sum、avg、min 或 max |
field | string | 是 | 要聚合的字段,count 可使用 "*" |
filter | string | 否 | 聚合前应用的 OData 风格筛选 |
distinct | boolean | 否 | 为 true 时聚合前先去重 |
groupby | string 数组 | 否 | 分组字段,如 ["Category", "Status"] |
having | object | 否 | 对聚合结果分组后的过滤,支持 eq、neq、gt、gte、lt、lte、in |
orderby | string 数组 | 否 | 对分组结果排序,如 ["count desc"] |
first | integer | 否 | 返回的最大分组结果数 |
after | string | 否 | 用于分页分组结果的 continuation cursor |
权限约束
所有工具调用都经过权限检查:
- 代理只能调用当前角色被授权执行的操作。
- 配置中
fields.exclude排除的字段不出现在工具输入和输出中。 - 数据库策略(行级过滤)在
read_records中生效。 - 实体级
mcp.dml-tools: false的实体不对代理暴露。
如果代理尝试执行未授权的操作,工具调用会返回权限错误。
工具开关
可以通过全局 dml-tools 配置逐项关闭不需要的工具:
{
"runtime": {
"mcp": {
"dml-tools": {
"describe-entities": true,
"read-records": true,
"create-record": true,
"update-record": false,
"delete-record": false,
"execute-entity": true,
"aggregate-records": true
}
}
}
}即使角色和实体权限允许某项操作,被关闭的工具也不会出现在 tools/list 中。这在需要严格操作边界时很有用——例如从运行时层面完全禁用删除能力。
