feat(lzwcai-agile-db): 更新版本至0.4.4并优化数据库管理技能文档 - 更新版本号从0.4.2到0.4.4 - 优化API密钥权限管理说明,明确grant_api_key_permissions仅支持追加不支持撤销 - 新增add_sql_tool_to_datasource工具,提供一键创建SQL工具功能 - 调整create_sql_tool说明,强调需技能已存在 - 强化数据写操作安全机制,插入/更新/删除前必须预览并等待用户确认 - 完善导入数据功能说明,详细解释confirm_import_data参数传递方式 - 补充技能与工具管理流程,提供更清晰的操作指引 - 新增数字员工平台数据库技能配置指南文档 ```
46 KiB
name, description, metadata
| name | description | metadata | ||
|---|---|---|---|---|
| lzwcai-agile-db | AgileDB 数据库管理平台的 MCP 技能。为 AI Agent 提供完整的数据库操作工作流指导,适合零基础用户。 |
|
lzwcai-agile-db
AgileDB 数据库管理平台的 MCP 技能。为 AI Agent 提供完整的数据库操作工作流指导,适合零基础用户。
完整工具清单(57 个工具)
本 skill 基于 lzwcai_mcp_agile_db MCP Server,共提供 57 个工具,分为 12 大类。
⚠️ 契约提示(2026-06 真机验证):以下契约文档曾写错、已按真机修正,调用时务必遵守:
target默认test(不是 prod)。写线上库必须显式传target="prod"。alter_table的 operation 只有 3 种:ADD_COLUMN/MODIFY_COLUMN/DROP_COLUMN。其余(RENAME_COLUMN/ALTER_COLUMN_TYPE/SET_NOT_NULL...)后端不支持。alter_database改名字段是newName(不是 newDatabaseName)。generate_table_by_description是异步:返回 taskId,需用get_ai_training_detail轮询。list_tables_with_ai的datasourceId实为「库/配置 ID」(list_databases 返回的 config id),不是连接 ID。
一、数据源管理(10 个工具)
| 工具 | 功能 | 危险等级 |
|---|---|---|
list_datasources |
获取数据源列表 | 安全 |
get_datasource_detail |
获取数据源详情(含数据库、表结构) | 安全 |
create_datasource |
创建外部数据源连接(可选先测连接) | 安全 |
update_datasource |
更新数据源连接信息 | 中等 |
toggle_datasource_status |
启用/停用数据源 | 中等 |
delete_datasource |
删除数据源 | 危险 |
test_connection |
测试外部数据库连接(不创建) | 安全 |
get_realtime_structure |
实时探测远端库表结构 | 安全 |
create_builtin_datasource |
创建内置 PostgreSQL 连接(建库表链路第一步) | 安全 |
update_builtin_datasource |
修改内置 PostgreSQL 连接 | 中等 |
二、数据库与表管理(9 个工具)
| 工具 | 功能 | 危险等级 |
|---|---|---|
list_databases |
获取数据源下的数据库列表 | 安全 |
list_tables |
获取数据源下的表列表(基础) | 安全 |
list_tables_with_ai |
获取表元数据列表(含 AI 训练描述,内置库主列表) | 安全 |
get_table_detail |
获取表结构详情(字段、类型、主键) | 安全 |
create_database |
在内置源下创建数据库(建表前置) | 危险 |
create_table |
在指定库创建新表 | 危险 |
create_database_table |
一次性建库+表(合并接口) | 危险 |
alter_table |
修改表结构(仅 ADD/MODIFY/DROP_COLUMN) | 危险 |
alter_database |
修改数据库(改名,字段 newName) | 危险 |
三、AI 训练与生成(4 个工具)
| 工具 | 功能 | 危险等级 |
|---|---|---|
generate_table_by_description |
AI 自然语言生成表结构(异步,返回 taskId) | 安全(仅生成,不创建) |
get_ai_training_detail |
查询/轮询 AI 训练任务详情 | 安全 |
list_ai_trainings |
AI 补全训练任务列表 | 安全 |
create_ai_training_by_selected |
按选中表创建 AI 补全训练 | 中等 |
四、表数据 CRUD(5 个工具,target 默认 test)
| 工具 | 功能 | 危险等级 |
|---|---|---|
query_table_data |
查询表数据(分页) | 安全 |
insert_table_row |
插入一行数据 | 中等 |
update_table_row |
更新一行数据 | 中等 |
delete_table_rows |
删除数据行(按主键) | 危险 |
export_table_excel |
导出表数据为 Excel(base64) | 安全 |
五、SQL 执行(1 个工具)
| 工具 | 功能 | 危险等级 |
|---|---|---|
execute_sql |
执行原生 SQL 查询(入参 sql,target 默认 prod) |
中等/危险 |
六、数据导入(2 个工具)
| 工具 | 功能 | 危险等级 |
|---|---|---|
preview_import_data |
从 URL 下载 Excel 文件,AI 智能识别并预览 | 安全 |
confirm_import_data |
确认导入(需传 databaseName,自动组装结构) | 危险 |
七、表订阅(1 个工具)
| 工具 | 功能 | 危险等级 |
|---|---|---|
toggle_table_subscription |
切换表的订阅状态(configId+tableName+subscribe) | 中等 |
八、API 密钥管理(7 个工具)
| 工具 | 功能 | 危险等级 |
|---|---|---|
list_api_keys |
获取 API 密钥列表 | 安全 |
create_api_key |
创建新的 API 密钥 | 中等 |
toggle_api_key_status |
启用/禁用 API 密钥 | 中等 |
delete_api_key |
删除 API 密钥 | 危险 |
get_api_key_permissions |
查看指定密钥的权限配置 | 安全 |
grant_api_key_permissions |
批量为 API 密钥授予权限(仅追加,不可撤销) | 危险 |
九、技能与工具管理(7 个工具)
| 工具 | 功能 | 危险等级 |
|---|---|---|
add_sql_tool_to_datasource |
把 SQL 沉淀为工具(一步到位,自动建技能+配模板+建工具,去重幂等)唯一推荐入口 | 中等 |
get_skill_by_datasource |
根据数据源获取技能信息 | 安全 |
get_skill_tools |
获取技能下的工具列表 | 安全 |
create_sql_tool |
将 SQL 创建为可复用工具(底层积木,需技能已存在) | 中等 |
delete_skill_tool |
删除技能下的工具 | 危险 |
update_skill_config |
更新技能配置(名称/描述/模板) | 中等 |
update_skill_tool |
修改技能工具(id+description+uniqueName) | 中等 |
十、库表关联配置(3 个工具,外置源纳管/内置删库)
| 工具 | 功能 | 危险等级 |
|---|---|---|
create_connection_config |
建库表关联(外置源建连后选库选表的最后一步) | 中等 |
update_connection_config |
改库表关联范围 | 中等 |
delete_connection_config |
删库表关联(也是「删内置库」的实现) | 危险 |
十一、MQTT 字段关联同步(8 个工具,内置源专属)
| 工具 | 功能 | 危险等级 |
|---|---|---|
list_mqtt_configs |
MQTT 同步配置列表 | 安全 |
get_mqtt_config_detail |
配置详情 | 安全 |
list_mqtt_target_tables |
可同步目标表列表 | 安全 |
list_mqtt_target_table_columns |
目标表字段列表 | 安全 |
create_mqtt_config |
新增同步配置 | 中等 |
update_mqtt_config |
修改同步配置 | 中等 |
delete_mqtt_config |
删除同步配置 | 危险 |
refresh_mqtt_config_cache |
刷新配置缓存 | 安全 |
核心概念说明
数据源是什么?
数据源 = 一个数据库连接。它可以是:
builtin:内置 PostgreSQL 数据库(系统自带)external:外部数据库(MySQL、PostgreSQL、Oracle、SQL Server、达梦等)
数据源状态
0= 运行中(正常)1= 已停止(不可用)
环境参数 target
prod= 生产环境(正式数据)test= 测试环境(调试数据)
重要:表数据 CRUD(query/insert/update/delete/export)的
target默认test(安全优先)。要操作正式数据必须显式传target="prod"。 例外:execute_sql的 target 默认prod(沿用原行为)。
主键 primaryKey
主键是唯一标识一行数据的字段。例如 {"id": 1} 表示删除/更新 id=1 的那行数据。
connectionId vs datasourceId
datasourceId:用于数据源列表、数据库列表、表列表等浏览类操作connectionId:用于创建表、修改表、数据导入等需要直接操作连接的操作- 两者通常指向同一个东西,但 API 设计不同,请按照工具说明使用
⚠️ 安全确认原则(必须遵守)
〇、目标资源不得擅自选择(最高优先级铁律)
定位操作目标的参数(datasourceId / connectionId / databaseName / tableId / tableName / apiKeyId / skillId 等),永远不得猜测、编造或"随手挑一个":
- 多个候选 → 列出全部,让用户选;严禁默认第一个或自认为"最合理"的那个。
- 唯一候选 → 先声明"我将使用 XXX",给用户否决机会;创建/写入/删除类仍需用户确认后执行。
- 没有候选 / 信息不足 → 直接问用户,不得编造。
当你发现自己正在"替用户决定用哪个数据源/数据库/表"时,立刻停下来改成提问。
创建类操作(create_table / create_datasource 等)执行前必须逐项确认落点,绝不"随便找个数据源就建"。例如建表须确认:数据源(connectionId)+ 数据库(databaseName)+ 表名(tableName),三者都要用户点头。
一、执行工具前的风险评估
当执行以下类型的操作时,必须先询问用户确认,不得擅作主张:
-
数据写操作(增 / 删 / 改):插入数据(
insert_table_row)、更新数据(update_table_row)、删除数据(delete_table_rows)、导入数据(confirm_import_data)等- 说明:写操作会改变库中数据,执行前必须把将要写入/修改/删除的具体内容预览给用户,等待用户明确确认后才执行;删除不可恢复
-
删除操作:删除数据源、删除表数据、删除 API 密钥、删除技能工具等
- 说明:此操作不可恢复,数据将永久丢失
-
泄密风险操作:导出包含敏感数据的表、创建 API 密钥、查看密钥详情等
- 说明:可能导致敏感信息泄露,需确认用户授权
-
政治敏感操作:涉及政治相关数据的查询、修改、删除等
- 说明:可能涉及合规风险,需确认用户意图
-
疑似违规内容:涉及色情、暴力、违法等内容的操作
- 说明:可能违反法律法规,必须拒绝执行并告知用户
确认格式
执行上述操作前,必须使用以下格式向用户确认:
⚠️ 安全提醒:此操作存在 [具体风险类型] 风险。
具体说明:[说明可能的后果]
请确认是否继续?(回复"确认"继续,或取消操作)
只有在用户明确确认后才能继续执行。
二、多步骤场景必须逐步确认
当完成任务需要调用多个工具时(如:先查询表结构 → 插入数据 → 确认结果),不得一次性自动连续执行:
- 每完成一步后暂停,向用户展示当前步骤的结果
- 询问用户是否继续下一步,等待确认后再执行
- 不要假设用户的意图,即使用户的请求看似明确,也需要分步确认
示例:
用户:"帮我新增一个用户"
❌ 错误做法:自动调用 get_table_detail → insert_table_row → 返回结果(一次性执行完)
✅ 正确做法:
1. 调用 get_table_detail 了解表结构
2. 展示必填字段清单,询问用户:"请提供以下必填字段的值:..."
3. 用户回复后,展示将要插入的数据预览
4. 询问:"确认插入以上数据?"
5. 用户确认后才调用 insert_table_row
三、遇到多项选择时必须询问用户
当执行任务过程中遇到需要选择的场景时,AI 不得擅自做主选择:
- 列出所有可选方案,说明每个方案的优缺点或适用场景
- 等待用户明确选择,不要猜测用户意图
- 不要默认选择第一个或看似最合理的选项
常见需要询问的选择场景:
- 有多个数据源可选时
- 有多个数据库可选时
- 有多个表可选时
- 有多种操作方式可选时(如:用 SQL 查询 vs 用表数据查询工具)
- 有多种字段类型可选时
- 用户描述模糊,存在多种理解方式时
示例:
用户:"查一下订单数据"
❌ 错误做法:直接选择第一个数据源和第一个订单表进行查询
✅ 正确做法:
"找到以下数据源包含订单相关表:
1. HMD产品 → order_db → orders 表(156 条记录)
2. 测试数据源 → test_db → test_orders 表(10 条记录)
请问您想查询哪个?"
场景 1:浏览数据源(新手入门第一步)
当用户想了解系统里有哪些数据库或表时,使用此流程。
工作流程
用户请求: "有哪些数据源?" / "看看 XX 数据源有哪些表?" / "帮我查一下数据库"
↓
1. 调用 list_datasources()
↓
2. 展示数据源列表(名称、类型、状态、数据库数、表数)
↓
3. 用户选择数据源后,调用 get_datasource_detail(datasourceId="xx")
↓
4. 展示数据库列表和实时表结构
示例
用户: "帮我看看有哪些数据源"
调用: list_datasources()
返回: {
"total": 14,
"rows": [
{"id": "58", "datasourceName": "HMD产品", "host": "host.docker.internal", "port": 5432, "status": 0, ...},
...
]
}
回复: 共找到 14 个数据源:
1. HMD产品(PostgreSQL, host.docker.internal:5432, 运行中)
2. ...
请告诉我你想看哪个数据源?
用户: "看看 HMD 产品有哪些表"
调用: get_datasource_detail(datasourceId="58")
返回: {
"detail": {...},
"config": {...},
"structure": {
"databases": [
{"name": "order_db", "tables": [
{"tableName": "orders", "columns": [...]},
...
]}
]
}
}
回复: HMD产品 数据源包含以下数据库和表:
order_db:
- orders (订单表, 15 个字段)
- users (用户表, 8 个字段)
注意事项
- 数据源类型为
builtin表示系统内置数据库,类型为具体的数据库引擎名称(mysql、postgresql 等)表示外部数据源 - 如果用户只说"查一下数据库",先调用
list_datasources()再引导选择 - 已停止的数据源(status=1)无法访问其结构
场景 2:查询表数据
当用户想要查看某张表的具体数据记录时,使用此流程。
工作流程
用户请求: "查一下 users 表的数据" / "看看前 20 条订单"
↓
1. 如果不知道 tableId,先浏览数据源找到目标表
↓
2. 调用 query_table_data(tableId="xx", pageNum=1, pageSize=10, target="prod")
↓
3. 展示数据(表格形式,包含字段名和值)
↓
4. 如果数据量大,提示用户可翻页或调整 pageSize
示例
用户: "查一下 users 表前 10 条数据"
调用: query_table_data(tableId="5", pageNum=1, pageSize=10) // target 默认 test;查正式数据传 target="prod"
返回: {
"data": {
"tables": {
"tableName": "users",
"columns": [
{"columnName": "id", "columnType": "serial", "isPrimaryKey": true},
{"columnName": "username", "columnType": "varchar"}, ...
]
},
"content": [[1, "admin", "admin@test.com"], [2, "user1", "user1@test.com"], ...],
"total": 156
}
}
回复: users 表共 156 条记录,当前显示第 1-10 条:
| id | username | email |
|----|----------|-----------------|
| 1 | admin | admin@test.com |
| 2 | user1 | user1@test.com |
...
返回结构注意:列定义在
data.tables.columns[](字段名columnName、是否主键isPrimaryKey),行数据在data.content[]且是位置数组(按列顺序,不是键值对象)。展示/取主键时要把 content 的每个位置对到 columns 的同序字段。
注意事项
target参数:test=测试环境(默认),prod=生产环境(查正式数据须显式传)- 如果用户未指定数量,默认
pageSize=10 - 如果用户说"翻页",增加
pageNum参数 - 如果用户想看更多数据,可以增大
pageSize(最大根据 API 限制) - 行数据是位置数组(
data.content[]),需对照data.tables.columns[]的列顺序解析
场景 3:执行 SQL
当用户需要执行自定义 SQL 查询时,使用此流程。
工作流程
用户请求: "帮我执行 SQL..." / "查一下订单数大于 100 的用户"
↓
1. 如果用户直接提供 SQL,直接使用
如果用户提供自然语言需求,先转换为 SQL
↓
2. 调用 execute_sql(datasourceId="xx", sql="SELECT ...")
↓
3. 展示查询结果
↓
4. 如果 SQL 执行失败,展示错误信息并建议修正
示例
用户: "统计每个地区的订单数量"
转换为 SQL: SELECT region, COUNT(*) as order_count FROM orders GROUP BY region ORDER BY order_count DESC
调用: execute_sql(
datasourceId="58",
sql="SELECT region, COUNT(*) as order_count FROM orders GROUP BY region ORDER BY order_count DESC"
)
返回: {
"columns": [{"name": "region"}, {"name": "order_count"}],
"data": [{"region": "华东", "order_count": 1250}, {"region": "华南", "order_count": 980}, ...]
}
回复: 各地区订单统计:
| 地区 | 订单数 |
|------|--------|
| 华东 | 1,250 |
| 华南 | 980 |
| 华北 | 756 |
注意事项
datasourceId必须提供,如果用户未指定,先询问sqlTemplate可选,用于模板化查询params可选(对象),用于参数化查询(防止 SQL 注入);工具内部映射为后端的parameterstarget可选:test=测试环境(默认),prod=生产环境- 执行危险操作(DELETE/DROP/TRUNCATE)前,必须向用户确认
- 如果查询结果超过 100 行,建议用户使用
query_table_data代替 - 对于只读查询(SELECT),可以直接执行;对于写操作(INSERT/UPDATE/DELETE),必须二次确认
场景 4:增删改数据
当用户需要修改表中的数据时,使用此流程。
🔒 写操作统一规则(插入 / 更新 / 删除都适用):在调用
insert_table_row/update_table_row/delete_table_rows之前,必须先把将要写入/修改/删除的具体数据预览给用户,并等待用户明确确认后才执行。不得在用户未确认的情况下直接落库。
4.1 插入数据
用户请求: "新增一个用户,用户名是 test_user"
↓
1. 先调用 get_table_detail(tableId="xx") 了解表结构
↓
2. 确认必填字段(非空字段、无默认值字段)
↓
3. 向用户展示将要插入的数据,询问"确认插入以上数据?",等待用户确认
↓
4. 用户确认后,调用 insert_table_row(tableId="xx", data={...})
↓
5. 确认插入成功
示例:
用户: "新增一个用户,用户名 test_user,邮箱 test@test.com"
调用: get_table_detail(tableId="5")
返回: {columns: [{name: "id", isPrimaryKey: true, isAutoIncrement: true}, {name: "username", isNullable: false}, ...]}
回复: 即将向 users 表插入以下数据:
username = test_user, email = test@test.com
(id 自动生成)。确认插入吗?
用户: "确认"
调用: insert_table_row(
tableId="5",
data={"username": "test_user", "email": "test@test.com"}
)
回复: 已成功插入用户 test_user (ID 自动生成)
4.2 更新数据
用户请求: "把用户 test_user 的邮箱改成 new@test.com"
↓
1. 确认主键字段和要更新的值
↓
2. 向用户展示「目标行 + 改动前→改动后」的预览,询问"确认更新?",等待用户确认
↓
3. 用户确认后,调用 update_table_row(tableId="xx", primaryKey={主键}, data={要更新的字段})
↓
4. 确认更新成功
示例:
用户: "把 ID 为 5 的用户邮箱改成 new@test.com"
回复: 即将更新 users 表 ID=5 的记录:
email: old@test.com → new@test.com
确认更新吗?
用户: "确认"
调用: update_table_row(
tableId="5",
primaryKey={"id": 5},
data={"email": "new@test.com"}
)
回复: 已更新用户 ID=5 的邮箱为 new@test.com
4.3 删除数据
用户请求: "删除用户 test_user"
↓
1. ⚠️ 安全提醒:此操作存在删除风险。
说明:数据将永久删除,不可恢复。
请确认是否继续?
↓
2. ⚠️ 危险操作!先确认删除范围和影响
↓
3. 向用户展示将要删除的数据,请求确认
↓
4. 用户确认后,调用 delete_table_rows(tableId="xx", primaryKeys=[{主键}])
↓
5. 确认删除成功
示例:
用户: "删除 ID 为 10 的订单"
回复: ⚠️ 确认要删除以下记录吗?
订单 ID=10, 订单号=ORD-2024-0010, 金额=¥1,250.00
此操作不可恢复。请回复"确认删除"继续。
用户: "确认删除"
调用: delete_table_rows(
tableId="3",
primaryKeys=[{"id": 10}]
)
回复: 已成功删除订单 ID=10
注意:如果删除内容涉及敏感数据(如用户隐私、政治相关内容、疑似违规内容),必须额外说明后果并再次确认。
4.4 导出表数据为 Excel
用户请求: "把 users 表数据导出成 Excel"
↓
1. 调用 export_table_excel(tableId="xx", target="prod")
↓
2. 返回 base64 编码的 Excel 文件内容
↓
3. 提示用户解码 base64 获取文件
示例:
调用: export_table_excel(tableId="5")
返回: {
"success": true,
"file_base64": "UEsDBBQAAAAI...",
"message": "Excel 文件已导出,请解码 base64 内容获取文件"
}
回复: 已成功导出 users 表数据为 Excel 文件
文件内容已 base64 编码,请解码后保存为 .xlsx 文件
注意事项
- 写操作(插入/更新/删除)执行前必须先预览数据并等待用户确认;删除操作不可恢复,需格外谨慎
primaryKey必须是对象格式,如{"id": 1}primaryKeys是数组格式,如[{"id": 1}, {"id": 2}]data只包含要更新的字段,不需要提供全部字段- 插入数据时,自增主键不需要提供
- 如果操作涉及多行,使用批量操作或循环调用
- 增删改操作
target默认test(安全优先);要写正式数据必须显式传target="prod"
场景 5:AI 生成表结构
当用户需要创建新表但不知道如何设计表结构时,使用 AI 辅助生成。
工作流程
用户请求: "我需要一个用户表" / "帮我设计一个订单系统的表结构"
↓
1. 调用 generate_table_by_description(requirement="用户描述")
→ 返回 taskId(异步任务,此时还没有表结构)
↓
2. 轮询 get_ai_training_detail(taskId="xx") 直到 trainingStatus=2(已完成)
trainingStatus: 0 待训练 / 1 训练中 / 2 已完成 / 3 失败
完成后表结构在 createTableData.data.tables[] 里
↓
3. 展示 AI 生成的表结构(表名、字段、类型、注释)
↓
4. ⚠️ 确认落点:列出可用数据源,让用户选择 connectionId 和 databaseName
(多个数据源时必须让用户选,绝不擅自找一个;只有一个也要说明后再继续)
↓
5. 用户确认表结构 + 落点后,调用 create_table(connectionId="xx", databaseName="xx", tableName="xx", columns=[...])
↓
6. 确认创建成功
示例
用户: "帮我设计一个商品表,包含名称、价格、库存、分类"
调用: generate_table_by_description(
requirement="我需要一个商品表,包含商品名称、价格、库存、分类,用于电商系统"
)
返回: {"data": {"taskId": "831", "status": "0", "message": "任务已提交,等待AI生成表结构"}}
← 异步!返回的是 taskId,不是表结构
轮询: get_ai_training_detail(taskId="831")
返回(完成时): {
"data": {
"trainingStatus": "2", // 2=已完成
"progress": 100,
"createTableData": {"data": {"tables": [{
"tableName": "products",
"tableComment": "商品表",
"columns": [
{"columnName": "id", "columnType": "SERIAL", "isPrimaryKey": true, "columnComment": "主键ID"},
{"columnName": "name", "columnType": "VARCHAR", "columnLength": 200, "isNullable": false, "columnComment": "商品名称"},
{"columnName": "price", "columnType": "DECIMAL", "columnLength": 10, "columnComment": "价格"},
{"columnName": "stock", "columnType": "INTEGER", "columnComment": "库存数量"}
]
}]}}
}
}
回复: AI 已生成表结构设计:
表名: products (商品表)
字段:
- id (SERIAL, 主键) - 主键ID
- name (VARCHAR(200), 非空) - 商品名称
- price (DECIMAL(10)) - 价格
- stock (INTEGER) - 库存数量
是否需要在此基础上修改或直接创建?
用户: "直接创建到 order_db 数据库"
调用: create_table(
connectionId="58",
databaseName="order_db",
tableName="products",
tableComment="商品表",
columns=[...] // 使用轮询拿到的 createTableData.data.tables[0].columns
)
回复: 已成功创建表 products (商品表)
修改表结构(alter_table)
如果用户需要修改已有表的结构:
用户请求: "给 users 表加一个 phone 字段"
↓
1. 确认表结构和要修改的内容
↓
2. 构建 operations 数组(支持多种变更类型)
↓
3. 调用 alter_table(connectionId="xx", databaseName="xx", tableName="xx", operations=[...])
↓
4. 确认修改成功
可用的 operations 类型(真机验证,后端仅支持这 3 种):
ADD_COLUMN:添加字段MODIFY_COLUMN:修改字段(改类型/长度/可空/默认值/注释,整列重定义)DROP_COLUMN:删除字段
⚠️ 后端不支持
RENAME_COLUMN/ALTER_COLUMN_TYPE/SET_NOT_NULL/DROP_NOT_NULL/SET_DEFAULT/DROP_DEFAULT(会报「不支持的操作类型」)。改字段类型/约束统一用MODIFY_COLUMN传完整列定义。operations[].column是列定义对象,字段同建表(columnName/columnType/columnLength/isNullable/columnComment/defaultValue 等)。
注意事项
requirement参数应尽可能详细,包含业务场景和字段需求- AI 生成的表结构可能需要用户调整(如字段长度、类型)
- 创建表前需要确认
connectionId和databaseName - 常用字段类型:
VARCHAR,INTEGER,SERIAL(自增主键),DECIMAL,TIMESTAMP,TEXT,BOOLEAN - 如果用户描述模糊,先引导用户补充细节
场景 6:数据导入(Excel 到数据库)
当用户需要从 Excel 文件导入数据到数据库时,使用此流程。
工作流程
用户请求: "帮我导入这个 Excel 文件" / "把表格数据导入数据库"
↓
1. 拿到 Excel 文件的可下载 URL(http/https,<500KB,.xlsx/.xls)
↓
2. 调用 preview_import_data(connectionId="xx", file_url="https://example.com/data.xlsx", target="test")
↓
3. 展示 AI 识别的表结构和数据预览
↓
4. ⚠️ 安全提醒:此操作可能涉及数据安全风险。
说明:导入的数据将写入数据库,请确认数据来源合法合规,不包含敏感信息、政治内容或违规内容。
请确认是否继续?
↓
5. 用户确认无误后,调用 confirm_import_data(connectionId="xx", databaseName="目标库名", data=<预览返回的原文>, target="test")
(把 preview_import_data 的返回原样传给 data,工具会自动组装后端要求的结构;databaseName 是落库的目标库)
↓
6. 确认导入成功(返回含 insertedRows 插入行数)
confirm_import_data 的 data 传什么
把 preview_import_data 返回的 data 原文整块传给 data 参数即可,工具会自动解包组装。data 的标准形态(= preview 返回):
{
"tableStructure": {
"success": true,
"message": "Excel表结构生成成功",
"data": {
"tables": [
{
"tableName": "animals",
"tableComment": "宠物信息表",
"columns": [
{ "columnName": "id", "columnType": "SERIAL", "isPrimaryKey": true, "isAdditionField": true },
{ "columnName": "animal_name", "columnType": "VARCHAR", "columnLength": 5000 }
]
}
]
},
"allData": [
["id", "animal_name", "..."],
["1", "豆豆", "..."],
["2", "咪咪", "..."]
]
},
"databaseName": "pp_test",
"target": "prod"
}
tableStructure:preview 的表结构包装({success, message, data:{tables:[...]}}),工具会取tables[0]当单表对象,并把databaseName塞进去。databaseName/target既可放顶层参数,也可放在data里,工具都认。- ⚠️ allData 是二维数组,首行必须是「列名表头行」:
allData[0]= 各列的columnName(列名表头),真实数据从allData[1]起;- 每行(含表头行)都是按
columns顺序排列的位置数组,行宽 = 列总数(含SERIAL主键等所有列,不裁剪,主键列给占位值即可,后端自增时会忽略); - 若传入的 allData 没带表头行(首行就是数据),工具会据列名自动补一行表头——否则后端会把首行数据当成字段名,报「查询字段不存在/字段名称不正确」。
- ⚠️ columns / 表头列名必须对应目标表真实存在的字段:后端按列名拼 INSERT,
tableStructure.columns(以及 allData 首行表头)里的列名必须是目标表里确实存在的字段名,否则报「查询字段不存在 / 字段名称不正确」。- 导入到已有表时:不要直接用 Excel 识别出的列,应先
get_table_detail(tableId="xx")拿到目标表真实字段,再把 data 里的 columns、allData 首行表头、各行取值都对齐到这些真实字段(前端就是用目标表真实列覆盖 AI 识别列的)。
- 导入到已有表时:不要直接用 Excel 识别出的列,应先
注意事项
- 文件大小限制:< 500KB
- 支持格式:.xlsx / .xls
- 导入前默认使用
test环境(安全做法) - 如果用户要导入到正式环境,必须二次确认
file_url要求 http/https 可下载链接,且文件大小 < 500KBfile_url对应的文件扩展名需为.xlsx/.xlsconfirm_import_data必须传databaseName(落库目标库);data直接传preview_import_data的返回原文即可,工具内部会自动解包并组装成{tableStructure(含databaseName), allData}- AI 识别会把中文表头转成英文列名(如「姓名」→
name);若导入数据键名与生成的列名对不上会报「未找到 XX 字段」,此时需按预览返回的列名核对 - 后端报「插入数据失败(第N行):查询字段不存在/字段名称不正确」时,多半是 allData 缺了列名表头行(后端把首行数据当成了字段名),或某行列数与
columns对不上——确认首行是列名、每行值个数 = 列总数
场景 7:API 密钥管理
当用户需要管理 API 密钥时,使用此流程。
7.1 查看密钥列表
调用: list_api_keys()
返回: {
"total": 6,
"rows": [
{"id": "7", "apiKeyName": "AWINBEXT", "apiKey": "Lb8Lg...", "status": 0, "expireTime": "2027-06-06..."},
...
]
}
7.2 创建新密钥
调用: create_api_key(apiKeyName="新密钥名称")
返回: 包含新创建的密钥信息
7.3 启用/禁用密钥
调用: toggle_api_key_status(id="7", status=0) // 0=启用, 1=禁用
7.4 删除密钥
⚠️ 删除前确认:
⚠️ 安全提醒:此操作存在删除风险。
说明:API 密钥删除后不可恢复,依赖该密钥的服务将失效。
请确认是否继续?
回复: 确认要删除 API 密钥 "AWINBEXT" 吗?此操作不可恢复。
调用: delete_api_key(id="7")
7.5 查看密钥权限
调用: get_api_key_permissions(apiKeyId="7")
7.6 批量授权
调用: grant_api_key_permissions(
apiKeyId="7",
batchDatas=[
{
"connectionId": "58",
"permissionLevel": "connection",
"permissionType": "read,write"
},
{
"connectionId": "58",
"permissionLevel": "database",
"databaseName": "order_db",
"permissionType": "read"
}
]
)
权限级别说明:
connection:数据源级别权限database:数据库级别权限table:表级别权限
⚠️ 权限为「仅追加」模型:
grant_api_key_permissions只能新增权限,不会覆盖已有权限,且后端不支持撤销/删除已授予的权限。授权前务必确认范围,授错只能删掉整个密钥(delete_api_key)后重建。
7.7 调整权限(只能重建密钥)
# 后端不支持撤销单条权限。如需收回某密钥的权限,只能删除密钥后重新创建并重新授权:
调用: delete_api_key(id="7")
调用: create_api_key(apiKeyName="xxx")
调用: grant_api_key_permissions(apiKeyId="<新密钥ID>", batchDatas=[...])
说明:后端 permission 删除接口返回「不支持当前的调用方式」,无法撤销单条已授予权限。要缩小权限范围,走「删密钥 → 重建 → 重新授权」。
场景 8:技能与工具管理
当用户需要把 SQL 沉淀为数据源的可复用工具时,使用此流程。
🔒 核心约束:技能(skill)必须挂着工具才有效。后端/前端都没有「只建空技能」这个动作——单独建技能会留下一个无效的空技能。前端唯一入口是「添加工具」,它会按需把技能建好、配好,最后必定以创建工具收尾。
8.0 一步到位:把 SQL 沉淀为工具(推荐)
优先用 add_sql_tool_to_datasource,它一步完成整条链路,保证技能必有工具:
调用: add_sql_tool_to_datasource(
datasourceId="58",
name="查询活跃用户",
businessDescription="查询所有状态为活跃的用户",
sqlTemplate="SELECT * FROM users WHERE status = #{status}",
sqlParams={"type":"object","required":["status"],"properties":{"status":{"type":"string","description":"用户状态","examples":["active"]}}}, // 可选
resultType="list", // 可选,默认 list
businessScenario="用于查看当前活跃用户列表", // 可选
tableIds=["5"] // 可选
)
sqlParams 格式:标准 JSON Schema,形如
{"type":"object","required":[...],"properties":{"参数名":{"type":"...","description":"...","examples":[...]}}}。properties的键要与 SQL 模板里的#{参数名}占位符一一对应。传 dict 会自动序列化为 JSON 字符串;无参数可传{}。
内部流程(= 前端 handleAddToolSubmit):
读 skillBool(GET /datasource/config/{id})
├─ 技能已存在 → getByDatasource 拿 skillId → 按 sqlTemplate 去重 → confirmTools 建工具
└─ 技能不存在 → createOrGet 建技能 → getByDatasource 拿 skillId → 去重
→ updateOrGet 写 lzwcai-mcp-sqlexecutor 配置模板 → confirmTools 建工具
- 幂等:同 datasourceId 下若已有
sqlTemplate相同的工具(空白归一化后比较),返回skipped,不重复创建。 - skillId 来自 getByDatasource,不是 createOrGet 的返回(后端 createOrGet 不回可靠 id)。
8.1 查看数据源关联的技能
调用: get_skill_by_datasource(datasourceId="58")
8.3 查看技能下的工具
调用: get_skill_tools(skillId="xx")
分步操作(高级,一般不需要)
⚠️ 不要单独建空技能:技能必须挂着工具才有效,平时不会单独创建技能。常规「把 SQL 沉淀为工具」一律用
add_sql_tool_to_datasource(它会按需建技能+配模板+建工具)。下面的散工具仅用于「技能已存在」时单独加/改工具。
8.4 向已有技能添加 SQL 工具(底层积木,需技能已存在)
# 前提:技能已存在(用 get_skill_by_datasource 拿到 skillId);
# 若技能不存在,请直接用 add_sql_tool_to_datasource,别手动建空技能
调用: create_sql_tool(
skillId="xx",
tableIds=["5"],
suggestions=[{
"name": "查询活跃用户",
"businessDescription": "查询所有状态为活跃的用户",
"sqlTemplate": "SELECT * FROM users WHERE status = #{status}",
"sqlParams": {"type":"object","required":["status"],"properties":{"status":{"type":"string","description":"用户状态","examples":["active"]}}},
"resultType": "list",
"businessScenario": "用于查看当前活跃用户列表"
}]
)
8.5 删除技能工具
⚠️ 删除前确认:
⚠️ 安全提醒:此操作存在删除风险。
说明:技能工具删除后不可恢复。
请确认是否继续?
调用: delete_skill_tool(skillToolId="xx")
8.6 更新技能配置
# datasourceId + skillId 均必填(真实 ID,来自其他工具返回,不可臆造)
# 只给这两个 ID 即自动生成 lzwcai-mcp-sqlexecutor 标准配置模板
调用: update_skill_config(
datasourceId="58", // 来自 list_databases / list_tables_with_ai / get_connection_config_list
skillId="xx" // 来自 get_skill_by_datasource 返回
)
# 或:手动指定完整 configTemplate(覆盖自动生成)
调用: update_skill_config(
datasourceId="58",
skillId="xx",
configTemplate='{"mcpServers": {...}}' // JSON 字符串
)
说明:configTemplate 大部分是固定值,只有 mcpServerKey 后缀、
env.databaseId、env.skillId随 datasourceId / skillId 变化。两个 ID 都必填且必须是其他工具返回的真实值。不显式传 configTemplate 时,工具会按标准模板自动生成(与前端 SqlControllerMsg.vue 一致),无需手写整段 JSON。
8.7 修改技能下某个工具
调用: update_skill_tool(
id="2066468871151718402", // 工具 ID(来自 get_skill_tools 返回的 id)
description="改后的业务描述", // 可选
uniqueName="新展示名", // 可选(工具展示名)
sqlTemplate="SELECT ...", // 可选
resultType="list" // 可选:single / list
)
说明:后端实体真实字段为
id/uniqueName/description/sqlTemplate/resultType。旧参数名skillToolId/name/businessDescription仍有兼容映射,但建议直接用上面的真实字段名。businessScenario后端无此字段,会被丢弃。
场景 9:表订阅管理
用户请求: "订阅 orders 表" / "取消订阅 users 表"
调用: toggle_table_subscription(
configId="数据库配置ID",
tableName="orders",
subscribe=true // true=订阅, false=取消订阅
)
场景 10:库表关联配置(外置源纳管 / 内置删库)
「库表关联配置」是数据源能用于智能问数的最后一步:外置数据源建好连接后,必须选定要纳管的库与表,平台才会同步结构、允许后续问数。这一类有 3 个工具:create_connection_config / update_connection_config / delete_connection_config。
概念澄清:
- 配置(config)≠ 连接(connection)。
create_connection_config落库后产生的 config id,正是list_databases/list_tables_with_ai里要传的那个「库/配置 ID」(datasourceId参数实际指它,不是连接 ID)。delete_connection_config既是「删库表关联」,也是**「删除内置库」的唯一实现**——删内置库就是删掉它对应的那条配置。
10.1 外置源纳管(建连接后的收尾步骤)
用户请求: "把刚建的 MySQL 数据源接进来" / "让这个数据源能问数"
↓
1. 已有外置连接(create_datasource 返回的 connectionId)
↓
2. 调用 get_realtime_structure(datasourceId="连接ID") 探测真实库表
↓
3. ⚠️ 列出探测到的库和表,让用户勾选要纳管的范围
(多个库/表时必须让用户选,不得擅自全选或挑第一个)
↓
4. 调用 create_connection_config(connectionId="xx", databases=[{databaseName, tableNames:[...]}])
↓
5. 确认纳管成功(返回 config id,后续 list_tables_with_ai 用它)
示例:
用户: "把 mysql_test 数据源的 order_db 库接进来,纳管 orders 和 users 两张表"
调用: get_realtime_structure(datasourceId="58") // 先确认库表真实存在
调用: create_connection_config(
connectionId="58",
syncTables=true, // 默认 true,同步表结构
databases=[
{"databaseName": "order_db", "tableNames": ["orders", "users"]}
]
)
回复: 已纳管 order_db 库的 orders、users 两张表,该数据源现在可用于智能问数。
10.2 修改纳管范围
用户请求: "再把 products 表也纳管进来" / "改一下纳管的表"
↓
1. 先拿到该配置的 config id(list_databases 返回里的 id)
↓
2. ⚠️ 与用户确认最终要纳管的完整库表清单(这是全量覆盖,不是增量追加)
↓
3. 调用 update_connection_config(id="配置ID", connectionId="xx", databases=[...])
↓
4. 确认更新成功
⚠️ 全量覆盖语义:
databases传的是更新后的完整纳管范围,不是增量。漏传已有的表会导致那些表被移出纳管,务必带上全部要保留的表。
示例:
调用: update_connection_config(
id="123", // 配置 ID(编辑必传)
connectionId="58",
databases=[
{"databaseName": "order_db", "tableNames": ["orders", "users", "products"]}
]
)
回复: 已更新纳管范围,order_db 现纳管 orders、users、products 三张表。
10.3 删除配置(含删除内置库)
⚠️ 安全提醒:此操作存在删除风险。
说明:删除库表关联配置后,该库表将退出纳管、无法再问数;
若目标是内置库,则该库本身会被删除,库内数据永久丢失,不可恢复。
请确认是否继续?(回复"确认"继续,或取消操作)
↓
用户确认后,调用 delete_connection_config(ids=["配置ID1", "配置ID2"])
示例:
用户: "删掉那个测试内置库"
回复: ⚠️ 确认要删除内置库「test_db」(配置 ID=456)吗?
库内全部数据将永久删除,不可恢复。请回复"确认删除"继续。
用户: "确认删除"
调用: delete_connection_config(ids=["456"])
回复: 已删除配置 456(内置库 test_db)。
注意事项
databases每项是{databaseName, tableNames:[...]},tableNames是表名字符串数组(不是 tableId)syncTables默认true(纳管时同步表结构),一般无需手动传update_connection_config必传id(配置 ID),且databases为全量覆盖delete_connection_config的ids是数组,支持批量删;删内置库即删其对应配置 ID- 内置库删除属危险操作,务必先确认库名与影响后再执行
1. 安全第一
通用安全确认规则
-
执行任何工具前,评估是否存在删除、泄密、政治敏感、似黄等风险
-
存在风险时,必须询问用户确认,说明后果,不得擅作主张
-
用户未明确确认前,不得执行
-
执行任何写操作(INSERT/UPDATE/DELETE)前,先确认环境(prod vs test)
-
删除操作必须向用户展示将要删除的数据并二次确认
-
危险操作(DELETE/DROP/TRUNCATE/UPDATE 影响多行)前必须明确告知用户风险
-
数据导入时默认使用
test环境
2. 分步引导
- 新手可能不知道
datasourceId、tableId等参数,先通过列表工具引导获取 - 复杂操作分步执行,每步确认后继续
- 如果用户请求不完整(如未指定数据源),先引导补充信息
3. 数据展示
- 表格数据使用 Markdown 表格格式
- 长文本截断显示(最多 100 字符)
- 数字格式化(千位分隔符、货币符号)
- 时间格式化为可读格式
- 展示数据时包含字段名和类型
4. 错误处理
- API 错误:展示错误信息,建议重试或检查参数
- SQL 错误:展示 SQL 错误位置,建议修正
- 连接错误:检查数据源状态,建议启用或重新配置
- "登录过期":提示用户检查
API_KEY环境变量
5. 沟通方式
- 向小白用户解释时,避免使用技术术语(如 JSON Schema、SERIAL 等),用通俗语言
- 操作完成后告知结果(成功/失败/影响行数)
- 如果用户操作成功,给出明确的反馈信息
常用参数参考
数据源类型
builtin- 内置 PostgreSQLexternal- 外部数据库(MySQL/PostgreSQL/Oracle/SQL Server/达梦等)
数据源状态
0- 运行中1- 已停止
环境
test- 测试环境(表数据 CRUD 的默认值,安全优先)prod- 生产环境(操作正式数据须显式传target="prod";仅execute_sql默认 prod)
常用字段类型
| 类型 | 用途 | 示例 |
|---|---|---|
SERIAL |
自增主键 | id SERIAL PRIMARY KEY |
VARCHAR(n) |
短文本 | username VARCHAR(50) |
TEXT |
长文本 | description TEXT |
INTEGER |
整数 | stock INTEGER |
DECIMAL(m,n) |
精确小数 | price DECIMAL(10,2) |
TIMESTAMP |
时间戳 | created_at TIMESTAMP |
BOOLEAN |
布尔值 | is_active BOOLEAN |
表结构变更操作类型(alter_table)
| 类型 | 用途 | column 对象关键字段 |
|---|---|---|
ADD_COLUMN |
添加字段 | columnName, columnType, columnLength, isNullable, columnComment |
MODIFY_COLUMN |
修改字段(类型/长度/约束等,含改类型) | columnName, columnType, columnLength, ... |
DROP_COLUMN |
删除字段 | columnName |
后端只支持上述 3 种。
RENAME_COLUMN/ALTER_COLUMN_TYPE/SET_NOT_NULL/DROP_NOT_NULL/SET_DEFAULT/DROP_DEFAULT均会报「不支持的操作类型」(已真机验证)。改字段类型用MODIFY_COLUMN。
权限级别(API 密钥授权)
| 级别 | 范围 |
|---|---|
connection |
整个数据源 |
database |
指定数据库 |
table |
指定表 |
快速开始
如果用户说"帮我查一下数据库",按以下步骤操作:
- 调用
list_datasources()获取数据源列表 - 展示列表,让用户选择目标数据源(多个候选时必须让用户选,不得默认第一个;只有一个候选也要先说明"我将使用 XXX"再继续)
- 调用
get_datasource_detail(datasourceId="xx")获取数据库和表信息 - 引导用户选择要操作的表
- 根据用户意图调用相应的工具:
- 想看数据 →
query_table_data - 想执行 SQL →
execute_sql - 想新增数据 →
insert_table_row - 想修改数据 →
update_table_row - 想删除数据 →
delete_table_rows(需确认) - 想导出 Excel →
export_table_excel - 想创建表 →
generate_table_by_description+create_table - 想导入 Excel →
preview_import_data+confirm_import_data
- 想看数据 →