通过


SQL MCP Server 中的数据操纵语言(DML)工具

重要

SQL 模型上下文协议 (MCP) 服务器在数据 API 生成器版本 1.7 及更高版本中可用。

SQL 模型上下文协议 (MCP) 服务器向 AI 代理公开七种数据操作语言(DML)工具。 这些工具为数据库操作提供类型化的 CRUD 图面-创建、读取、更新和删除记录、聚合数据以及执行存储过程。 所有工具都遵循基于角色的访问控制(RBAC)、实体权限和配置中定义的策略。

什么是 DML 工具?

DML (数据操作语言) 工具处理数据操作:创建、读取、更新和删除记录、聚合数据以及执行存储过程。 与修改架构的 DDL (数据定义语言)不同,DML 仅在现有表和视图中的数据平面上运行。

七种 DML 工具包括:

  • describe_entities - 发现可用的实体和操作
  • create_record - 插入新行
  • read_records - 查询表和视图
  • update_record - 修改现有行
  • delete_record - 删除行
  • execute_entity - 运行存储过程
  • aggregate_records - 执行聚合查询

注释

本节中所述的 SQL MCP Server 2.0 功能目前处于预览状态,在正式发布之前可能会更改。 有关详细信息,请参阅 版本 2.0 中的新增功能。

全局和实体启用 DML 工具后,SQL MCP Server 会通过 MCP 协议公开它们。 代理永远不会直接与数据库架构交互 - 它们通过数据 API 生成器抽象层工作。

工具

list_tools响应

代理调用 list_tools时,SQL MCP Server 返回:

{
  "tools": [
    { "name": "describe_entities" },
    { "name": "create_record" },
    { "name": "read_records" },
    { "name": "update_record" },
    { "name": "delete_record" },
    { "name": "execute_entity" },
    { "name": "aggregate_records" }
  ]
}

describe_entities

返回当前角色能够使用的实体。 每个条目包括字段名称、说明和允许的操作。 此工具不会查询数据库。 而是从配置文件构建的内存配置中读取。

重要

fields describe_entities中的信息是根据您在fields配置中提供的数据而生成的。 由于字段元数据是可选的,如果不包含字段元数据,代理只会看到具有空 fields 数组的实体名称。 最佳做法是在配置中包含字段名称和字段说明。 此元数据为代理提供更多上下文来生成准确的查询和更新。 在此处了解有关 字段说明的详细信息。

注释

响应包括配置中的字段 namedescription 值。 当前响应中不包括数据类型和主键指示器。 存储过程参数也未列出。 代理依赖实体和字段描述以及错误反馈来确定正确的使用方法。

参数

参数 类型 必需 说明
nameOnly 布尔 true 时,返回实体名称和描述的简洁列表,而不包含字段元数据。
entities 字符串数组 限制对指定实体的响应。 省略后,将返回所有已启用 MCP 的实体。

示例请求

{
  "method": "tools/call",
  "params": {
    "name": "describe_entities",
    "arguments": {
      "entities": ["Products"]
    }
  }
}

示例响应

{
  "entities": [
    {
      "name": "Products",
      "description": "Product catalog with pricing and inventory",
      "fields": [
        {
          "name": "ProductId",
          "description": "Unique product identifier"
        },
        {
          "name": "ProductName",
          "description": "Display name of the product"
        },
        {
          "name": "Price",
          "description": "Retail price in USD"
        }
      ],
      "operations": [
        "read_records",
        "update_record"
      ]
    }
  ]
}

注释

任何 CRUD 和执行 DML 工具使用的实体选项都直接来自 describe_entities。 附加到每个工具的内部语义说明强制实施这两个步骤流。

创建记录

在表中创建新行。 需要对当前角色的实体创建权限。 该工具根据实体架构验证输入,强制实施字段级权限,应用创建策略,并返回具有任何生成的值的已创建记录。

参数

参数 类型 必需 说明
entity 字符串 是的 要在其中创建记录的实体名称。
data 对象 是的 新记录的字段名称和值的键值对。

read_records

查询表或视图。 支持筛选、排序、分页和字段选择。 该工具从结构化参数生成确定性的 SQL,应用读取权限和字段投影,并强制实施行级安全策略。

参数

参数 类型 必需 说明
entity 字符串 是的 要从中读取的实体名称。
select 字符串 要返回的字段名称的逗号分隔列表(例如, "id,title,price")。
filter 字符串 OData 风格筛选表达式(例如 "Price gt 10 and Category eq 'Books'")。
orderby 字符串数组 对表达式进行排序。 每个元素都是具有可选方向的字段名称(例如 ["Price desc", "Name asc"])。
first 整数 要返回的最大记录数。
after 字符串 分页的上一个响应的延续游标。

警告

orderby 参数必须是 字符串数组,而不是单个字符串。 传递字符串值会导致UnexpectedError。 使用 ["Name asc"] 而不是 "Name asc"

分页响应

当有更多结果可用时,响应将包含一个after游标。 将此值作为 after 下一个请求中的参数传递,以提取下一页。

{
  "value": [ ... ],
  "after": "W3siRW50aXR5TmFtZ..."
}

该字段的存在 after 指示存在更多页面。 当 after 缺席时,你已经到达最后一页。

重要

使用数据 API 生成器的缓存系统对来自 read_records 的结果进行自动缓存。 可以全局或每个实体配置缓存生存时间(TTL),以减少数据库负载。

连接操作

该工具 read_records 专为单个表或视图设计。 因此,此工具不支持JOIN操作。 此设计有助于隔离责任、提高性能,并限制对会话上下文窗口的影响。

但是,JOIN 操作并不是特殊情况,并且数据 API 生成器(DAB)已经支持通过 GraphQL 端点进行复杂的查询。 对于更复杂的查询,我们建议使用视图而不是表。 还可以使用该工具 execute_entity 运行存储过程来封装参数化查询。

更新记录

修改现有行。 需要主键和字段才能更新。 该工具验证主键是否存在,执行更新权限和策略,并且仅更新当前角色可以修改的字段。

参数

参数 类型 必需 说明
entity 字符串 是的 要更新的实体名称。
keys 对象 是的 标识记录(例如, {"id": 42})的键值对。
fields 对象 是的 字段名称和新值的键值对。

删除记录

删除现有行。 需要主键。 该工具验证主密钥是否存在、强制实施删除权限和策略,并使用事务支持执行安全删除。

参数

参数 类型 必需 说明
entity 字符串 是的 要从中删除的实体名称。
keys 对象 是的 标识记录(例如, {"id": 42})的键值对。

注释

某些生产方案全局禁用此工具以广泛约束模型。 此选项由你决定,值得记住的是,实体级权限仍然是控制访问权限的最重要方式。 delete-record即使启用了此功能,如果某个角色对实体没有删除权限,该角色也不能对该实体使用此工具。

执行实体

运行存储过程。 支持输入参数和输出结果。 该工具根据过程签名验证输入参数,强制实施执行权限,并安全地传递参数。

参数

参数 类型 必需 说明
entity 字符串 是的 存储过程实体名称。
parameters 对象 输入参数名称和值的键值对。

聚合记录

对表和视图执行聚合查询。 支持常见的聚合函数,例如 count、sum、average、minimum 和 maximum。 该工具从结构化参数生成确定性的 SQL,应用读取权限和字段投影,并强制实施行级安全策略。

参数

参数 类型 必需 说明
entity 字符串 是的 要聚合的实体名称。
function 字符串 是的 聚合函数:count、、sumavgminmax
field 字符串 是的 要聚合的字段。 使用 "*" 代替 count.
filter 字符串 聚合之前应用的 OData 样式筛选器。
distinct 布尔 true聚合之前,删除重复值。
groupby 字符串数组 用作分组结果的字段名称(例如,["Category", "Status"])。
having 对象 按聚合值筛选组。 使用运算符:eq、、neqgtgteltltein
orderby 字符串数组 对分组结果的表达式进行排序(例如 ["count desc"], )。
first 整数 要返回的最大分组结果数。
after 字符串 分页分组结果的延续游标。

示例:使用 groupby 和 having 进行计数

{
  "method": "tools/call",
  "params": {
    "name": "aggregate_records",
    "arguments": {
      "entity": "Todo",
      "function": "count",
      "field": "*",
      "groupby": ["UserId"],
      "having": { "gt": 2 }
    }
  }
}

aggregate-records该工具可配置为布尔值或具有更多设置的对象:

{
  "runtime": {
    "mcp": {
      "dml-tools": {
        "aggregate-records": {
          "enabled": true,
          "query-timeout": 30
        }
      }
    }
  }
}

query-timeout 属性指定最大执行时间(以秒为单位)(范围:1–600)。 此设置有助于防止长时间运行的聚合查询消耗过多的资源。

运行时配置

的运行时部分中,全局配置 DML 工具。

{
  "runtime": {
    "mcp": {
      "enabled": true,
      "path": "/mcp",
      "dml-tools": {
        "describe-entities": true,
        "create-record": true,
        "read-records": true,
        "update-record": true,
        "delete-record": true,
        "execute-entity": true,
        "aggregate-records": true
      }
    }
  }
}

下面的 runtime.mcp.dml-tools 每个工具属性接受 truefalse。 该工具aggregate-records还支持具有enabledquery-timeout的对象格式:

{
  "runtime": {
    "mcp": {
      "enabled": true,
      "dml-tools": {
        "describe-entities": true,
        "create-record": true,
        "read-records": true,
        "update-record": true,
        "delete-record": true,
        "execute-entity": true,
        "aggregate-records": {
          "enabled": true,
          "query-timeout": 30
        }
      }
    }
  }
}

若要一次性启用或禁用所有 DML 工具,请设置为"dml-tools"truefalse

使用 CLI

使用数据 API 生成器 CLI 单独设置属性:

dab configure --runtime.mcp.enabled true
dab configure --runtime.mcp.path "/mcp"
dab configure --runtime.mcp.dml-tools.describe-entities true
dab configure --runtime.mcp.dml-tools.create-record true
dab configure --runtime.mcp.dml-tools.read-records true
dab configure --runtime.mcp.dml-tools.update-record true
dab configure --runtime.mcp.dml-tools.delete-record true
dab configure --runtime.mcp.dml-tools.execute-entity true
dab configure --runtime.mcp.dml-tools.aggregate-records.enabled true
dab configure --runtime.mcp.dml-tools.aggregate-records.query-timeout 30

禁用工具

在运行时级别禁用某个工具时,无论实体权限或角色配置如何,它都不会显示给代理。 这个设置在您需要严格的操作边界时非常有用。

常见应用场景

  • 禁用 delete-record 以防止生产中数据丢失
  • 对只读报告端点禁用create-record
  • 在不使用存储过程时禁用execute-entity
  • 当不需要聚合查询时禁用aggregate-records

全局禁用工具时,该工具会隐藏在响应中 list_tools ,并且无法调用。

实体设置

除非对实体进行明确限制,否则它们会自动参与 MCP。 实体 mcp 上的属性控制其 MCP 参与。 使用对象格式进行明确控制。

对象格式

{
  "entities": {
    "Products": {
      "mcp": {
        "dml-tools": true
      }
    },
    "SensitiveData": {
      "mcp": {
        "dml-tools": false
      }
    }
  }
}

如果未在实体上指定 mcp ,则 DML 工具默认在全局启用 MCP 时启用。

存储过程的自定义工具

对于存储过程实体,请使用custom-tool属性将该过程注册为命名的MCP工具。

{
  "entities": {
    "GetBookById": {
      "source": {
        "type": "stored-procedure",
        "object": "dbo.get_book_by_id"
      },
      "mcp": {
        "custom-tool": true
      }
    }
  }
}

重要

custom-tool 属性仅适用于存储过程实体。 在表或视图实体上设置它会导致配置错误。

每个工具管控的范围

每个工具切换仅在下面的 runtime.mcp.dml-tools全局运行时级别进行配置。

在实体级别,mcp 是一个布尔门或具有 dml-toolscustom-tool 属性的对象。

{
  "entities": {
    "AuditLogs": {
      "mcp": {
        "dml-tools": false
      }
    }
  }
}
{
  "runtime": {
    "mcp": {
      "dml-tools": {
        "describe-entities": true,
        "create-record": true,
        "read-records": true,
        "update-record": true,
        "delete-record": false,
        "execute-entity": true,
        "aggregate-records": true
      }
    }
  }
}

仅当全局启用且实体允许 DML 工具时,工具才可用。

RBAC 集成

每个 DML 工具操作都会强制实施基于角色的访问控制规则。 代理的角色决定了哪些实体可见,允许哪些操作,包含哪些字段,以及行级策略是否适用。

如果anonymous角色仅允许对Products只具有读取权限:

  • describe_entities仅在操作中显示read_records
  • create_recordupdate_recorddelete_record 不可用
  • 仅允许 anonymous 在架构中显示的字段

dab-config.json中配置角色

{
  "entities": {
    "Products": {
      "permissions": [
        {
          "role": "anonymous",
          "actions": [
            {
              "action": "read",
              "fields": {
                "include": ["ProductId", "ProductName", "Price"],
                "exclude": ["Cost"]
              }
            }
          ]
        },
        {
          "role": "admin",
          "actions": [
            {
              "action": "*"
            }
          ]
        }
      ]
    }
  }
}