# 数据库管理平台 - MCP 工具设计方案

> 基于平台现有功能，设计可供外部 AI Agent 通过 MCP 协议调用的工具集。
> 目标：**用户脱离平台界面，通过 MCP 调用即可使用数据库管理平台的核心功能。**

---

## 一、设计原则

1. **按用户场景分组**：不是简单映射 API，而是围绕用户真实工作流组织工具
2. **最小化调用链**：复杂操作尽量合并为一个 tool，减少多轮调用
3. **读写分离**：查询类工具可安全暴露，写操作需明确提示
4. **环境感知**：所有操作默认携带环境参数(prod/test)，内置数据源特有
5. **权限前置**：调用方需提供 apiKeyId 或等效凭证，工具内部自动鉴权

---

## 二、工具清单

### 🗄️ 数据源管理

#### 1. `list_datasources`
- **用途**：获取数据源列表，支持搜索和状态筛选
- **对应前端**：DataSourceList.vue
- **对应 API**：`getConnectionList` ✅ 已实现
  - **端点**：`GET /api/datasource/connection/list`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| datasourceName | string | 否 | 数据源名称模糊搜索 |
| status | int | 否 | 0=运行中, 1=已停止, 不传=全部 |
| sourceType | string | 否 | builtin/external |
| pageNum | int | 否 | 默认 1 |
| pageSize | int | 否 | 默认 20 |

**返回**：数据源列表（含名称、类型、状态、库数、表数、创建时间等）

---

#### 2. `get_datasource_detail`
- **用途**：获取单个数据源的完整详情
- **对应前端**：DatabaseDetail.vue 头部
- **对应 API**：
  - `getConnectionDetail(id)` ✅ 已实现 — `GET /api/datasource/connection/{id}`
  - `getConnectionConfig(id)` ✅ 已实现 — `GET /api/datasource/config/{id}`
  - `getConnectionRealtimeStructure(id)` ✅ 已实现 — `GET /api/datasource/connection/realtime/structure/{id}`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| datasourceId | string | 是 | 数据源 ID |

**返回**：数据源详情 + 数据库配置列表 + 实时结构（数据库列表、表列表、字段信息）

---

#### 3. `create_datasource`
- **用途**：创建外部数据源连接
- **对应前端**：CreateDataSource.vue
- **对应 API**：
  - `testConnection(data)` ✅ 已实现 — `POST /api/datasource/connection/test`
  - `postConnectionDetail(data)` ✅ 已实现 — `POST /api/datasource/connection`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| datasourceName | string | 是 | 数据源名称（3-20字） |
| datasourceType | string | 是 | mysql/postgresql/oracle/sqlserver/dameng |
| host | string | 是 | 数据库地址 |
| port | int | 是 | 端口号 |
| databaseName | string | 是 | 要连接的数据库名 |
| username | string | 是 | 数据库用户名 |
| password | string | 否 | 密码 |
| remark | string | 否 | 数据源描述 |
| connectionType | string | 否 | user_password/ssl，默认 user_password |
| test_first | bool | 否 | 是否先测试连接，默认 true |

**返回**：创建结果，含数据源 ID

---

#### 4. `update_datasource`
- **用途**：更新数据源连接信息
- **对应 API**：`putConnectionDetail(data)` ✅ 已实现 — `PUT /api/datasource/connection`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | string | 是 | 数据源 ID |
| datasourceName | string | 否 | 更新名称 |
| host | string | 否 | 更新地址 |
| port | int | 否 | 更新端口 |
| databaseName | string | 否 | 更新数据库名 |
| username | string | 否 | 更新用户名 |
| password | string | 否 | 新密码（不传则不变） |
| remark | string | 否 | 更新描述 |

**返回**：更新结果

---

#### 5. `toggle_datasource_status`
- **用途**：启用/停用数据源
- **对应 API**：`putConnectionChangeStatus(data)` ✅ 已实现 — `PUT /api/datasource/connection/changeStatus`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | string | 是 | 数据源 ID |
| status | int | 是 | 0=启用, 1=停用 |

**返回**：操作结果

---

#### 6. `delete_datasource`
- **用途**：删除数据源（运行中会自动先停用）
- **对应 API**：
  - `putConnectionChangeStatus(data)` ✅ 已实现 — `PUT /api/datasource/connection/changeStatus`
  - `deleteConnection(id)` ✅ 已实现 — `DELETE /api/datasource/connection/{id}`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | string | 是 | 数据源 ID |

**返回**：删除结果

---

### 📊 数据库与表管理

#### 7. `list_databases`
- **用途**：获取指定数据源下的数据库列表
- **对应 API**：`getConnectionConfigList(data)` ✅ 已实现 — `GET /api/datasource/config/list`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| datasourceId | string | 是 | 数据源 ID |

**返回**：数据库列表（ID、名称、类型、状态、表数）

---

#### 8. `list_tables`
- **用途**：获取指定数据库下的表列表
- **对应前端**：DatabaseDetail.vue 左侧表列表
- **对应 API**：`getTableList(data)` ✅ 已实现 — `GET /api/datasource/table/list`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| datasourceId | string | 是 | 数据源 ID |
| databaseName | string | 否 | 数据库名过滤 |
| keyword | string | 否 | 表名模糊搜索 |
| pageNum | int | 否 | 默认 1 |
| pageSize | int | 否 | 默认 20 |

**返回**：表列表（表名、注释、字段数、创建时间等）

---

#### 9. `get_table_detail`
- **用途**：获取表的完整结构信息
- **对应前端**：DatabaseDetail.vue 右侧字段列表
- **对应 API**：`getTableDetail(id)` ✅ 已实现 — `GET /api/datasource/table/{id}/detail`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| tableId | string | 是 | 表 ID |

**返回**：表名、表注释、字段列表（字段名、类型、长度、主键、可空、默认值、注释、AI训练状态）

---

#### 10. `create_table`
- **用途**：在指定数据库创建新表
- **对应前端**：CreateBuiltinDataSource.vue 表结构编辑器
- **对应 API**：`postCreateTable(connectionId, data)` ✅ 已实现 — `POST /api/datasource/connection/{connectionId}/create_table`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| datasourceId | string | 是 | 数据源 ID |
| databaseName | string | 是 | 目标数据库名 |
| tableName | string | 是 | 表名（小写字母+数字+下划线） |
| tableComment | string | 否 | 表注释 |
| columns | array | 是 | 字段定义数组 |
| columns[].columnName | string | 是 | 字段名 |
| columns[].columnType | string | 是 | 字段类型（VARCHAR/INTEGER/SERIAL等） |
| columns[].columnLength | int | 否 | 字段长度 |
| columns[].isPrimaryKey | bool | 否 | 是否主键 |
| columns[].isNullable | bool | 否 | 是否可空 |
| columns[].isAutoIncrement | bool | 否 | 是否自增 |
| columns[].columnComment | string | 否 | 字段注释 |
| columns[].defaultValue | string | 否 | 默认值 |

**返回**：创建结果，含表 ID

---

#### 11. `alter_table`
- **用途**：修改已有表结构（增/改/删字段）
- **对应 API**：`putAlterTable(connectionId, data)` ✅ 已实现 — `PUT /api/datasource/connection/{connectionId}/alter_table`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| tableId | string | 是 | 表 ID |
| columns | array | 是 | 字段变更数组 |
| columns[].operation | string | 是 | ADD_COLUMN / MODIFY_COLUMN / DROP_COLUMN |
| columns[].columnName | string | 是 | 字段名 |
| columns[].columnType | string | 否 | 字段类型（ADD/MODIFY） |
| columns[].columnLength | int | 否 | 字段长度 |
| columns[].isPrimaryKey | bool | 否 | 是否主键 |
| columns[].isNullable | bool | 否 | 是否可空 |
| columns[].columnComment | string | 否 | 字段注释 |
| columns[].defaultValue | string | 否 | 默认值 |
| newTableName | string | 否 | 新表名（重命名） |
| newTableComment | string | 否 | 新表注释 |

**返回**：修改结果

---

#### 12. `generate_table_by_description`
- **用途**：通过自然语言描述让 AI 生成表结构
- **对应前端**：CreateBuiltinDataSource.vue AI 生成表结构
- **对应 API**：`postGenerateTable(data)` ✅ 已实现 — `POST /api/datasource/connection/generate_table`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| description | string | 是 | 业务场景描述（至少6个字符） |

**返回**：AI 生成的表结构（表名、表注释、字段列表含类型/主键/注释等）

> **场景示例**：用户说"我需要一个商城系统，管理商品、分类和用户评价"，AI 返回完整的表结构设计。

---

### 📝 表数据操作 (内置数据源 CRUD)

#### 13. `query_table_data`
- **用途**：查询内置表数据（分页）
- **对应前端**：CustomizeDbTable.vue 线上/调试数据视图
- **对应 API**：`getBuiltinTableData(tableId, params)` ✅ 已实现 — `GET /api/datasource/connection/builtin/table/{tableId}`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| tableId | string | 是 | 表 ID |
| target | string | 否 | prod/test，默认 prod |
| pageNum | int | 否 | 默认 1 |
| pageSize | int | 否 | 默认 10 |

**返回**：表结构信息 + 数据行（二维数组转换后的对象数组） + 总数

---

#### 14. `insert_table_row`
- **用途**：向内置表插入一行数据
- **对应 API**：`postBuiltinTableRows(tableId, data, params)` ✅ 已实现 — `POST /api/datasource/connection/builtin/table/{tableId}/rows`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| tableId | string | 是 | 表 ID |
| target | string | 否 | prod/test，默认 prod |
| data | object | 是 | 行数据（键值对，键为字段名） |

**返回**：插入结果

---

#### 15. `update_table_row`
- **用途**：更新内置表的指定行
- **对应 API**：`putBuiltinTableRows(tableId, data, params)` ✅ 已实现 — `PUT /api/datasource/connection/builtin/table/{tableId}/rows`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| tableId | string | 是 | 表 ID |
| target | string | 否 | prod/test，默认 prod |
| primaryKey | object | 是 | 主键值（如 {"id": 1}） |
| data | object | 是 | 要更新的字段值 |

**返回**：更新结果

---

#### 16. `delete_table_rows`
- **用途**：删除内置表的指定行
- **对应 API**：`deleteBuiltinTableRows(tableId, data, params)` ✅ 已实现 — `DELETE /api/datasource/connection/builtin/table/{tableId}/rows`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| tableId | string | 是 | 表 ID |
| target | string | 否 | prod/test，默认 prod |
| primaryKeys | array | 是 | 主键数组（如 [{"id": 1}, {"id": 2}]） |

**返回**：删除结果

---

#### 17. `export_table_excel`
- **用途**：导出表数据为 Excel 文件
- **对应 API**：`getBuiltinTableExportExcel(tableId, params)` ✅ 已实现 — `GET /api/datasource/connection/builtin/table/{tableId}/export/excel`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| tableId | string | 是 | 表 ID |
| target | string | 否 | prod/test，默认 prod |

**返回**：Excel 文件（二进制 blob）+ 文件名（从 Content-Disposition 解析）

---

### 🔑 API 密钥与权限管理

#### 18. `list_api_keys`
- **用途**：获取 API 密钥列表
- **对应前端**：DataSourceKeys.vue
- **对应 API**：`getApiKeyList(data)` ✅ 已实现 — `GET /api/datasource/api_key/list`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| apiKeyName | string | 否 | 密钥名称模糊搜索 |
| pageNum | int | 否 | 默认 1 |
| pageSize | int | 否 | 默认 20 |

**返回**：密钥列表（名称、Key、状态、创建时间）

---

#### 19. `create_api_key`
- **用途**：创建新的 API 密钥
- **对应 API**：`postApiKey(data)` ✅ 已实现 — `POST /api/datasource/api_key`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| apiKeyName | string | 是 | 密钥名称（最多50字） |

**返回**：密钥信息（含 API Key 明文、ID）

---

#### 20. `toggle_api_key_status`
- **用途**：启用/禁用 API 密钥
- **对应 API**：`putApiKey(data)` ✅ 已实现 — `PUT /api/datasource/api_key`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | string | 是 | 密钥 ID |
| status | int | 是 | 0=启用, 1=禁用 |

**返回**：操作结果

---

#### 21. `delete_api_key`
- **用途**：删除 API 密钥
- **对应 API**：`deleteApiKey(ids)` ✅ 已实现 — `DELETE /api/datasource/api_key/{ids}`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | string | 是 | 密钥 ID |

**返回**：删除结果

---

#### 22. `get_api_key_permissions`
- **用途**：查看指定密钥的权限配置
- **对应 API**：`getApiKeyPermission(apiKeyId)` ✅ 已实现 — `GET /api/datasource/api_key/permission/{apiKeyId}`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| apiKeyId | string | 是 | 密钥 ID |

**返回**：三级权限（connectionPermissions / databasePermissions / tablePermissions）

---

#### 23. `grant_api_key_permissions`
- **用途**：批量为 API 密钥授予权限
- **对应前端**：DataSourceKeySetting.vue
- **对应 API**：`postApiKeyPermissionGrantBatch(data)` ✅ 已实现 — `POST /api/datasource/api_key/permission/grant_batch`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| apiKeyId | string | 是 | 密钥 ID |
| batchDatas | array | 是 | 权限批量数据数组 |
| batchDatas[].connectionId | string | 是 | 数据源 ID |
| batchDatas[].permissionLevel | string | 是 | connection/database/table |
| batchDatas[].permissionType | string | 是 | 权限类型（逗号分隔） |
| batchDatas[].databaseName | string | 否 | 数据库名（level=database/table 时） |
| batchDatas[].tableName | string | 否 | 表名（level=table 时） |

**返回**：授权结果

---

### 🤖 技能与工具管理 (内置数据源 AI 能力)

#### 24. `get_skill_by_datasource`
- **用途**：根据数据源获取技能信息
- **对应 API**：`getSkillByDatasource(id)` ✅ 已实现 — `GET /api/datasource/skill/getByDatasource/{id}`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| datasourceId | string | 是 | 数据源 ID |

**返回**：技能信息（含 skillBool 标识）

---

#### 25. `get_skill_tools`
- **用途**：获取技能下的工具列表
- **对应 API**：`getSkillBySkillId(id)` ✅ 已实现 — `GET /api/datasource/skill/getBySkillId/{id}`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| skillId | string | 是 | 技能 ID |

**返回**：工具列表（名称、描述、SQL模板、参数定义、业务场景）

---

#### 26. `create_skill`
- **用途**：为数据源创建技能
- **对应 API**：`postSkillCreateOrGet(data)` ✅ 已实现 — `POST /api/datasource/skill/createOrGet`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| datasourceId | string | 是 | 数据源 ID |
| name | string | 否 | 技能名称（不传则自动生成） |
| description | string | 否 | 技能描述 |

**返回**：技能 ID

---

#### 27. `create_sql_tool`
- **用途**：将 SQL 查询创建为可复用工具
- **对应前端**：SqlControllerMsg.vue 添加到工具功能
- **对应 API**：`postSqlSkillConfirmTools(data)` ✅ 已实现 — `POST /api/datasource/skill/confirmTools`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| skillId | string | 是 | 技能 ID |
| name | string | 是 | 工具名称 |
| businessDescription | string | 是 | 业务描述 |
| sqlTemplate | string | 是 | SQL 模板（支持 #{param} 参数占位） |
| sqlParams | string | 否 | 参数 JSON Schema（默认空对象） |
| resultType | string | 否 | single/list，默认 list |
| businessScenario | string | 否 | 业务场景描述 |

**返回**：工具创建结果

---

#### 28. `delete_skill_tool`
- **用途**：删除技能下的工具
- **对应 API**：`postDeleteSkillTool(skillToolId)` ✅ 已实现 — `DELETE /api/datasource/skill/tskilltool/{skillToolId}`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| skillToolId | string | 是 | 工具 ID |

**返回**：删除结果

---

#### 29. `update_skill_config`
- **用途**：更新技能配置（如 MCP Server 配置模板）
- **对应 API**：`putSkillUpdateOrGet(data)` ✅ 已实现 — `POST /api/datasource/skill/updateOrGet`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| datasourceId | string | 是 | 数据源 ID |
| configTemplate | string | 是 | 配置模板 JSON 字符串 |

**返回**：更新结果

---

### 📥 数据导入

#### 30. `preview_import_data`
- **用途**：上传 Excel 文件，AI 智能识别并预览表结构/数据
- **对应前端**：TableRecognition.vue
- **对应 API**：`postImportDocumentPreview(connectionId, file, target)` ✅ 已实现 — `POST /api/datasource/connection/{connectionId}/import_document/preview`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| connectionId | int | 是 | 数据源 ID |
| target | string | 否 | prod/test，默认 test |
| file | binary | 是 | Excel 文件 (.xlsx/.xls, <500KB) |

**返回**：识别结果（表结构 + 数据预览）

---

#### 31. `confirm_import_data`
- **用途**：确认导入 AI 识别后的数据
- **对应 API**：`postImportDocumentConfirm(connectionId, data, params)` ✅ 已实现 — `POST /api/datasource/connection/{connectionId}/import_document/confirm`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| connectionId | int | 是 | 数据源 ID |
| target | string | 否 | prod/test |
| data | object | 是 | 导入数据（含 tableStructure + allData） |

**返回**：导入结果

---

### 🏷️ 表订阅

#### 32. `toggle_table_subscription`
- **用途**：切换表的订阅状态
- **对应前端**：DatabaseDetail.vue 订阅按钮
- **对应 API**：`postDatasourceSubscriptionToggle(data)` ✅ 已实现 — `POST /api/datasource/subscription/toggle`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| tableId | string | 是 | 表 ID |
| datasourceId | string | 是 | 数据源 ID |
| subscribe | bool | 是 | true=订阅, false=取消订阅 |

**返回**：操作结果

---

### 🔧 SQL 执行

#### 33. `execute_sql`
- **用途**：执行原生 SQL 查询
- **对应 API**：`executeSql(data)` ✅ 已实现 — `POST /api/datasource/sqlExecutionLog/testSqlWithSchema`

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| datasourceId | string | 是 | 数据源 ID |
| sql | string | 是 | SQL 语句 |
| target | string | 否 | prod/test，默认 prod |
| params | object | 否 | 参数对象 |

**返回**：查询结果（表头、数据行、业务名称、描述等）

---

## 三、推荐使用场景

### 场景 1：外部 AI Agent 管理数据库

```
用户: "帮我查一下有哪些数据源"
Agent: 调用 list_datasources()

用户: "看看 mall_db 有哪些表"
Agent: 调用 list_tables(datasourceId="xx", databaseName="mall_db")

用户: "users 表结构给我看一下"
Agent: 调用 get_table_detail(tableId="xx")
```

### 场景 2：通过 AI 描述自动生成表结构

```
用户: "我需要一个订单系统，包含订单、订单明细、支付方式"
Agent: 调用 generate_table_by_description(description="我需要一个订单系统...")
Agent: 返回 AI 生成的表结构，用户确认后调用 create_table() 批量创建
```

### 场景 3：管理 API 密钥和权限

```
用户: "帮我创建一个叫'第三方报表系统'的 API Key"
Agent: 调用 create_api_key(apiKeyName="第三方报表系统")

用户: "给它开通 mall_db 数据库的读取权限"
Agent: 调用 grant_api_key_permissions(apiKeyId="xx", batchDatas=[{...}])
```

### 场景 4：管理表数据

```
用户: "查一下 users 表前 10 条数据"
Agent: 调用 query_table_data(tableId="xx", pageNum=1, pageSize=10)

用户: "新增一个用户，用户名是 test_user"
Agent: 调用 insert_table_row(tableId="xx", data={"user_name": "test_user", ...})
```

### 场景 5：创建 SQL 工具

```
用户: "把这个查询保存为工具，叫'按地区统计订单'"
Agent: 调用 create_sql_tool(skillId="xx", name="按地区统计订单", 
         sqlTemplate="SELECT region, COUNT(*) FROM orders GROUP BY region", ...)
```

### 场景 6：导入 Excel 数据

```
用户: "帮我导入这份 Excel 到测试环境"
Agent: 调用 preview_import_data(connectionId=xx, target="test", file=...)
Agent: 展示识别结果，用户确认后调用 confirm_import_data(...)
```

---

## 四、工具优先级建议

| 优先级 | 工具 | 理由 |
|--------|------|------|
| **P0 核心** | list_datasources, list_tables, get_table_detail, execute_sql, query_table_data | 覆盖 80% 查询场景 |
| **P1 常用** | create_datasource, create_table, generate_table_by_description, create_api_key, grant_api_key_permissions | 管理核心操作 |
| **P2 扩展** | insert/update/delete_table_row, export_table_excel, create_sql_tool, toggle_table_subscription | 数据操作与 AI 能力 |
| **P3 完整** | preview/confirm_import_data, update_skill_config, alter_table, delete_skill_tool | 高级功能 |

---

## 五、实现建议

1. **MCP Server 实现**：建议用 Python + `mcp` 库或 Node.js + `@modelcontextprotocol/sdk`
2. **鉴权方式**：工具内部复用平台现有的 API Key 鉴权机制，调用方传入 apiKeyId
3. **错误处理**：统一错误格式 `{ success: false, error: "描述" }`，与平台 API 拦截器保持一致
4. **环境默认值**：所有 target 参数默认 prod，调用方显式指定 test 才能操作测试数据
5. **批量操作**：对于 create_table 等可能涉及多表的场景，支持批量参数或循环调用
6. **AI 工具调用**：generate_table_by_description 等 AI 工具需要调用平台的 AI 服务接口（agent generic / aiTextGenerator）
7. **前端 API 映射**：所有 33 个 MCP 工具均已在前端 `src/server/database.ts` 中实现对应函数，可直接复用
