---
name: lzwcai-agile-db
description: AgileDB 数据库管理平台的 MCP 技能。为 AI Agent 提供完整的数据库操作工作流指导，适合零基础用户。
metadata:
  version: 0.4.2
---

# 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 密钥授予权限 | **危险** |
| `revoke_api_key_permissions` | 撤销/删除已授予的权限（按权限记录 ID） | **危险** |

### 九、技能与工具管理（7 个工具）

| 工具 | 功能 | 危险等级 |
|------|------|----------|
| `get_skill_by_datasource` | 根据数据源获取技能信息 | 安全 |
| `get_skill_tools` | 获取技能下的工具列表 | 安全 |
| `create_skill` | 为数据源创建技能 | 中等 |
| `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`），三者都要用户点头。

---

### 一、执行工具前的风险评估

当执行以下类型的操作时，**必须先询问用户确认**，不得擅作主张：

1. **删除操作**：删除数据源、删除表数据、删除 API 密钥、删除技能工具等
   - 说明：此操作不可恢复，数据将永久丢失

2. **泄密风险操作**：导出包含敏感数据的表、创建 API 密钥、查看密钥详情等
   - 说明：可能导致敏感信息泄露，需确认用户授权

3. **政治敏感操作**：涉及政治相关数据的查询、修改、删除等
   - 说明：可能涉及合规风险，需确认用户意图

4. **疑似违规内容**：涉及色情、暴力、违法等内容的操作
   - 说明：可能违反法律法规，必须拒绝执行并告知用户

#### 确认格式

执行上述操作前，必须使用以下格式向用户确认：

```
⚠️ 安全提醒：此操作存在 [具体风险类型] 风险。
具体说明：[说明可能的后果]
请确认是否继续？（回复"确认"继续，或取消操作）
```

**只有在用户明确确认后才能继续执行。**

---

### 二、多步骤场景必须逐步确认

当完成任务需要调用多个工具时（如：先查询表结构 → 插入数据 → 确认结果），**不得一次性自动连续执行**：

1. **每完成一步后暂停**，向用户展示当前步骤的结果
2. **询问用户是否继续下一步**，等待确认后再执行
3. **不要假设用户的意图**，即使用户的请求看似明确，也需要分步确认

**示例**：
```
用户："帮我新增一个用户"

❌ 错误做法：自动调用 get_table_detail → insert_table_row → 返回结果（一次性执行完）

✅ 正确做法：
  1. 调用 get_table_detail 了解表结构
  2. 展示必填字段清单，询问用户："请提供以下必填字段的值：..."
  3. 用户回复后，展示将要插入的数据预览
  4. 询问："确认插入以上数据？"
  5. 用户确认后才调用 insert_table_row
```

---

### 三、遇到多项选择时必须询问用户

当执行任务过程中遇到需要选择的场景时，**AI 不得擅自做主选择**：

1. **列出所有可选方案**，说明每个方案的优缺点或适用场景
2. **等待用户明确选择**，不要猜测用户意图
3. **不要默认选择第一个**或看似最合理的选项

#### 常见需要询问的选择场景：
- 有多个数据源可选时
- 有多个数据库可选时
- 有多个表可选时
- 有多种操作方式可选时（如：用 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 注入）；工具内部映射为后端的 `parameters`
- `target` 可选：`test`=测试环境（默认），`prod`=生产环境
- **执行危险操作（DELETE/DROP/TRUNCATE）前，必须向用户确认**
- 如果查询结果超过 100 行，建议用户使用 `query_table_data` 代替
- 对于只读查询（SELECT），可以直接执行；对于写操作（INSERT/UPDATE/DELETE），必须二次确认

---

## 场景 4：增删改数据

当用户需要修改表中的数据时，使用此流程。

### 4.1 插入数据

```
用户请求: "新增一个用户，用户名是 test_user"
    ↓
1. 先调用 get_table_detail(tableId="xx") 了解表结构
    ↓
2. 确认必填字段（非空字段、无默认值字段）
    ↓
3. 调用 insert_table_row(tableId="xx", data={...})
    ↓
4. 确认插入成功
```

**示例**:

**用户**: "新增一个用户，用户名 test_user，邮箱 test@test.com"

```
调用: get_table_detail(tableId="5")
返回: {columns: [{name: "id", isPrimaryKey: true, isAutoIncrement: true}, {name: "username", isNullable: false}, ...]}

调用: 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. 调用 update_table_row(tableId="xx", primaryKey={主键}, data={要更新的字段})
    ↓
3. 确认更新成功
```

**示例**:

**用户**: "把 ID 为 5 的用户邮箱改成 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 插入行数）
```

### 注意事项
- 文件大小限制：< 500KB
- 支持格式：.xlsx / .xls
- 导入前默认使用 `test` 环境（安全做法）
- 如果用户要导入到正式环境，必须二次确认
- `file_url` 要求 http/https 可下载链接，且文件大小 < 500KB
- `file_url` 对应的文件扩展名需为 `.xlsx` / `.xls`
- **`confirm_import_data` 必须传 `databaseName`**（落库目标库）；`data` 直接传 `preview_import_data` 的返回原文即可，工具内部会自动解包并组装成 `{tableStructure(含databaseName), allData}`
- AI 识别会把中文表头转成英文列名（如「姓名」→`name`）；若导入数据键名与生成的列名对不上会报「未找到 XX 字段」，此时需按预览返回的列名核对

---

## 场景 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`：表级别权限

### 7.7 撤销权限

```
调用: get_api_key_permissions(apiKeyId="7")
返回: {
  "data": {
    "connectionPermissions": [{"id": "101", "connectionId": "58", "permissionType": "read"}],
    "databasePermissions": [...],
    "tablePermissions": [...]
  }
}

调用: revoke_api_key_permissions(permissionIds=["101"])
```

> 说明：`revoke_api_key_permissions` 按权限记录的 `id` 删除，需先从 `get_api_key_permissions` 获取。

---

## 场景 8：技能与工具管理

当用户需要创建和管理自定义技能时，使用此流程。

### 8.1 查看数据源关联的技能

```
调用: get_skill_by_datasource(datasourceId="58")
```

### 8.2 创建技能

```
调用: create_skill(datasourceId="58", name="订单查询技能", description="用于订单数据的常用查询")
```

### 8.3 查看技能下的工具

```
调用: get_skill_tools(skillId="xx")
```

### 8.4 将 SQL 创建为可复用工具

```
调用: create_sql_tool(
  skillId="xx",
  tableIds=["5"],
  suggestions=[{
    "name": "查询活跃用户",
    "businessDescription": "查询所有状态为活跃的用户",
    "sqlTemplate": "SELECT * FROM users WHERE status = #{status}",
    "sqlParams": {"status": {"type": "string", "default": "active"}},
    "resultType": "list",
    "businessScenario": "用于查看当前活跃用户列表"
  }]
)
```

### 8.5 删除技能工具

```
⚠️ 删除前确认：
⚠️ 安全提醒：此操作存在删除风险。
说明：技能工具删除后不可恢复。
请确认是否继续？

调用: delete_skill_tool(skillToolId="xx")
```

### 8.6 更新技能配置

```
调用: update_skill_config(
  datasourceId="58",
  configTemplate='{"mcpServer": "..."}'  // 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` - 内置 PostgreSQL
- `external` - 外部数据库（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` | 指定表 |

---

## 快速开始

如果用户说"帮我查一下数据库"，按以下步骤操作：

1. 调用 `list_datasources()` 获取数据源列表
2. 展示列表，让用户选择目标数据源（**多个候选时必须让用户选，不得默认第一个**；只有一个候选也要先说明"我将使用 XXX"再继续）
3. 调用 `get_datasource_detail(datasourceId="xx")` 获取数据库和表信息
4. 引导用户选择要操作的表
5. 根据用户意图调用相应的工具：
   - 想看数据 → `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`
