199 lines
11 KiB
Markdown
199 lines
11 KiB
Markdown
# OpsxDB AI / MCP / Agent 任务书
|
||
|
||
> 更新:2026-10-15 · 用户拍板:**先 MCP,再内部会话,最后 GUI 联动**
|
||
> 对标:优先 [DBX MCP](https://github.com/t8y2/dbx)(`packages/mcp-server` / `crates/dbx-mcp`);架构思路参考 oh-my-pi;可选对照 Google MCP Toolbox for Databases、DBHub、官方 MCP SDK。
|
||
|
||
## 产品结论(已采纳用户补充)
|
||
|
||
### 2026-10-15 产品 / PM / 设计确认(锁定)
|
||
|
||
| 项 | 决议 |
|
||
|----|------|
|
||
| 顺序 | MCP-first → 内部会话共用 Tools → GUI 插入/回写 |
|
||
| 首版引擎 | **仅** MySQL 族 + PostgreSQL + Redis;其它库不进 P0 |
|
||
| 写操作 | **P0 纯只读**;「确认后才可写」复用现有 dangerConfirm,进 **P1**,MCP 首版不可写 |
|
||
| 代码边界 | 只动根级 `src` + `server`;禁止 `packages/ui`(死树) |
|
||
| Redis | 对齐现有精确 TYPE / 集群 SCAN,不另起搜键 |
|
||
| UI | P0 无新重界面;Ask\|Agent Seg / 步骤时间线 / MCP 状态点属阶段 2–4(见文末设计备忘) |
|
||
| 冲突 | 与未推「补偿包」冲突先停报,勿 silently 覆盖 |
|
||
|
||
| 问题 | 结论 |
|
||
|------|------|
|
||
| 能不能用 AI 做 MySQL/Redis 等操作? | 能。底座 `/api/db/*` + danger 已有,缺的是工具层。 |
|
||
| 借鉴谁? | **优先 DBX**(MCP 工具粒度、只读/可写、连接 scope、审计)。oh-my-pi 借工具调用/会话规范,不当成 DB 产品抄。 |
|
||
| 要不要先做 MCP? | **要,优先做 MCP**。内部 AI 会话与 Cursor/Claude/Codex/omp **共用同一套 Tools**,避免两套逻辑。 |
|
||
| 形态 | GUI 管连接与会话;MCP 暴露安全的数据操作;Gin 仍是官网/docs,**不是**远程协作后端。 |
|
||
|
||
|
||
## P0 / P1 边界(2026-10-15 收紧)
|
||
|
||
| 阶段 | 范围 |
|
||
|------|------|
|
||
| **P0(本轮)** | **纯只读**。`execute_query` 只允许 SELECT/SHOW/EXPLAIN/DESCRIBE/PRAGMA/WITH…SELECT;任何写/DDL **一律拒绝**(**不做** write mode / confirm token)。Redis 仅白名单读命令(GET/SCAN/TYPE/TTL…);FLUSH*/KEYS/写命令拒。MCP stdio + tool runtime + 连接落盘 + 审计。 |
|
||
| **P1** | 可写 + 确认令牌/策略;内部 Ask \| Agent UI(设计阶段 2,**先只记文档不实现**);GUI 联动(插入编辑器 / 结果网格);设置页 MCP 白名单 UI。 |
|
||
|
||
设计阶段 2(内部会话 Ask \| Agent):Agent 调同一 `aitools` runtime;Ask 保持现有生成/解释/优化。**本轮不实现 UI。**
|
||
|
||
## 落地顺序(锁定)
|
||
|
||
1. **核心 MCP Tools(最小集)** + 连接落盘可读
|
||
2. **安全策略**:默认只读、危险 SQL 拦截、连接白名单、审计日志
|
||
3. **内部 AI 会话**:Ask \| Agent;Agent 调同一工具层(进程内调用,不必绕 stdio)
|
||
4. **GUI 联动**:SQL 一键插入编辑器;结果可回写网格 / 展示
|
||
|
||
## P0 工具契约
|
||
|
||
| Tool | 说明 | 安全默认 |
|
||
|------|------|----------|
|
||
| `opsxdb_list_connections` | 列出可见连接(id/name/driver/host,无密码) | 受白名单过滤 |
|
||
| `opsxdb_list_databases` | 列库 | 连接须在白名单 |
|
||
| `opsxdb_list_tables` | 列表/视图(及引擎等价物) | 只读 |
|
||
| `opsxdb_describe_table` | 字段与表元数据 | 只读 |
|
||
| `opsxdb_get_schema_context` | 紧凑 schema 文本,供模型上下文 | 截断上限(与现 AI schema cap 对齐,约 4k) |
|
||
| `opsxdb_execute_query` | 执行 SQL;最多 N 行(建议 100) | **P0 纯只读**(非读语句直接拒绝);可写+确认 = P1 |
|
||
| `opsxdb_execute_redis_command` | 执行一条 Redis 命令 | **P0 仅读命令白名单**;FLUSH*/KEYS/写一律拒;P1 再开确认写 |
|
||
|
||
首版引擎验收:**MySQL 族 + PostgreSQL + Redis(单机)**;其余引擎有连接即可试,不阻塞发版。
|
||
|
||
## 安全策略(MCP 层统一)
|
||
|
||
- **P0 强制只读**:`execute_query` 非读类 SQL 一律拒绝;`mcp.json` 的 `mode=read_write` 本轮不生效(P1 才启用写+确认)
|
||
- 复用 `server/internal/db/danger.go` 的危险词表;无 WHERE 的 DELETE/UPDATE 拦截
|
||
- **连接白名单**(配置文件 `~/.opsxdb/mcp.json`:`allowed_connection_ids`;空=拒绝全部或仅显式 allow——首版建议「空=拒绝」,避免默认放开)
|
||
- **行数 / 字节上限**;超时;取消
|
||
- **审计**:`~/.opsxdb/logs/mcp-audit.jsonl`(时间、tool、connection_id、只读/写、摘要、错误;不含密码/全文大结果)
|
||
- 不暴露:增删连接、原始密码、远程 HTTP 无 token 的开放端口(stdio 默认;本机 HTTP 可选且必须 bearer)
|
||
|
||
## 连接存储(MCP 可读)
|
||
|
||
现状:连接在桌面 `localStorage`(`opsxdb.connections.v1`),独立 MCP 进程读不到。
|
||
|
||
**本轮必做:** GUI `saveConnections` 同步写 `~/.opsxdb/connections.json`(脱敏字段完整、密码仍按现有混淆策略;MCP 与桌面同钥/同解码逻辑,或 MCP 仅经本机已打开的 session——优先**文件同步 + 现有 secrets 解码**,与 DBX「读桌面连接库」同构)。
|
||
|
||
## 内部会话与 MCP 的关系
|
||
|
||
```
|
||
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
|
||
│ Cursor/omp │───▶│ opsxdb-mcp │───▶│ tool runtime │
|
||
└─────────────┘ │ (stdio/HTTP) │ │ (db.* API) │
|
||
└──────────────────┘ └──────┬──────┘
|
||
┌─────────────┐ ┌──────────────────┐ │
|
||
│ 侧栏 Agent │───▶│ 同一 tool runtime │◀───────────┘
|
||
└─────────────┘ └──────────────────┘
|
||
```
|
||
|
||
侧栏 **不要**再直接拼 prompt 假装执行;Agent 模式只通过 tool runtime。Ask 模式保持现有生成/解释/优化(可不调执行工具)。
|
||
|
||
## GUI 联动(第 4 步,可薄)
|
||
|
||
- 工具结果中的 SQL →「插入当前编辑器」
|
||
- `execute_query` 结果 → 可选「在结果网格打开」(限行)
|
||
- 设置页:MCP 开关说明、白名单、只读/可写、复制 Cursor `mcp.json` 片段
|
||
|
||
## 刻意首版不做
|
||
|
||
- MCP 增删连接、Kafka/MQ、桌面 `open_table` 远程遥控(可后置)
|
||
- 把 Gin `:8788` 做成公网 Agent 后端
|
||
- 两套危险策略(GUI 一套、MCP 一套)
|
||
|
||
## 验收清单
|
||
|
||
- [x] `opsxdb-mcp` stdio:`tools/list` 含上表工具(二进制 + 单测注册表)
|
||
- [x] 白名单外连接调用失败且有明确错误(空白名单=拒绝全部)
|
||
- [x] 只读模式下 `DELETE`/`DROP`/写 SQL 被拒;审计写 `mcp-audit.jsonl`
|
||
- [x] 通路代码就绪;单测用 sqlite 覆盖 list/describe/exec;MySQL/PG 真库待桌面验收
|
||
- [x] Redis 读白名单 + FLUSH*/KEYS/写拒(单测);真库待验
|
||
- [ ] 侧栏 Agent 调同一 runtime(**P1 / 设计阶段 2,本轮不做 UI**)
|
||
- [x] 文档:`docs/mcp-cursor.example.json` + 本文件
|
||
|
||
## 参考路径(本机)
|
||
|
||
- DBX:`/Users/logan/devops/demo/db-gui/dbx/packages/mcp-server`、`crates/dbx-mcp`
|
||
- oh-my-pi:`/Users/logan/devops/demo/ai-agent/oh-my-pi/docs/mcp-*.md`、`docs/custom-tools.md`
|
||
- OpsxDB 现有:`server/internal/db/*`、`server/internal/ai/*`、`src/AiPanel.tsx`、`docs/DATABASE-OPERATIONS-AUDIT.md`
|
||
|
||
|
||
## P0 验收方式(命令行优先)
|
||
|
||
> 产品边界:P0 是 **MCP 工具层**,不是 Web 工作台。验收不走浏览器 `:5174`/官网;Web 只看文档。DeepSeek 侧栏 **Ask 写 SQL** 已可测生成;**Agent 调工具查真库**属阶段 2。
|
||
|
||
### 环境(本机已有)
|
||
|
||
| 库 | 端口 | 账号 | 说明 |
|
||
|----|------|------|------|
|
||
| MySQL 8.4 (`opsxdb-mysql`) | 3306 | root 或 opsx / `Demo@123`,库 `demo` | `tests/dbctl.sh up a` |
|
||
| Redis 7 (`opsxdb-redis`) | 6379 | 无密码 | `tests/dbctl.sh up f` |
|
||
|
||
### A. 单测(无真库也可)
|
||
|
||
```bash
|
||
cd /Users/logan/devops/opsxdb/server
|
||
go test ./internal/aitools/ -count=1
|
||
```
|
||
|
||
覆盖:白名单拒绝、只读挡 DROP/DELETE、Redis 危险命令拒绝。
|
||
|
||
### B. 真库 MCP(推荐主路径)
|
||
|
||
1. GUI 里保存 MySQL / Redis 连接一次(会双写 `~/.opsxdb/connections.json`),记下 `id`。
|
||
2. 写白名单:
|
||
|
||
```bash
|
||
mkdir -p ~/.opsxdb/logs
|
||
cat > ~/.opsxdb/mcp.json <<'EOF'
|
||
{
|
||
"mode": "read_only",
|
||
"allowed_connection_ids": ["<mysql-conn-id>", "<redis-conn-id>"]
|
||
}
|
||
EOF
|
||
```
|
||
|
||
3. 编译并跑:
|
||
|
||
```bash
|
||
cd /Users/logan/devops/opsxdb/server
|
||
go build -o ../bin/opsxdb-mcp ./cmd/opsxdb-mcp
|
||
# Cursor:mcp.json 指向该二进制;或用临时脚本对 stdio 发 initialize + tools/list + tools/call
|
||
```
|
||
|
||
4. 用例清单:
|
||
|
||
| # | 工具 | 期望 |
|
||
|---|------|------|
|
||
| 1 | list_connections | 只见白名单内连接,无密码字段 |
|
||
| 2 | list_tables(MySQL demo) | 有表名 |
|
||
| 3 | describe_table | 有列 |
|
||
| 4 | get_schema_context | 截断文本 |
|
||
| 5 | execute_query `SELECT … LIMIT 10` | 有行,≤100 |
|
||
| 6 | execute_query `DROP TABLE …` | **拒绝** + 审计 |
|
||
| 7 | execute_redis_command `PING` / `GET` | 成功 |
|
||
| 8 | execute_redis_command `FLUSHDB` | **拒绝** |
|
||
| 9 | 白名单外 connection_id | **拒绝** |
|
||
| 10 | 审计文件 | `~/.opsxdb/logs/mcp-audit.jsonl` 有记录 |
|
||
|
||
### C. DeepSeek(当前能验什么)
|
||
|
||
- **现在**:设置里选 DeepSeek → Ask「生成/解释」对当前 Tab SQL(不执行工具)。
|
||
- **阶段 2**:Agent 模式多轮调同一 MCP tool runtime,再验「让 AI 查 demo 表结构再写 SELECT」。
|
||
|
||
### D. 验收通过后交付物
|
||
|
||
在本机 `~/Downloads/` 生成:`AI-Agent接入GUI工具开发实践.md`,供 opsxapi / opsxshell 及其他项目复用(MCP-first、只读默认、连接落盘、Ask|Agent、危险确认)。
|
||
|
||
|
||
## 设计备忘(阶段 2–4,P0 不实现)
|
||
|
||
来源:设计师 2026-10-15。紧凑桌面、深浅主题;不抄 dbx 整屏工具条。
|
||
|
||
1. **Ask | Agent**:输入框上方同高同宽小分段;Ask/Agent 不同占位;危险写在执行前确认条(结果区顶或气泡内),Ask 不生成执行条;模式跟连接/Tab,切换不丢草稿。
|
||
2. **步骤时间线**:挂在该条 Agent 回复下,可折叠,默认最近 3 步;行内状态点+工具名+一行摘要+耗时;点开才见全文;无独立全高工具面板。
|
||
3. **插入/结果**:气泡底「插入当前查询」+「新开查询」;行列结果才给「在结果区打开」;默认不抢焦点。
|
||
4. **MCP 状态**:设置 → AI/MCP(开关+白名单);有活跃外部会话时标题旁小点「MCP」,悬停摘要,点开最近调用可断开;无活跃不显示。
|
||
|
||
落地次序:MCP 开关+白名单 → Ask|Agent Seg → 时间线与插入 → MCP 状态点。
|
||
|
||
|
||
### 真库验收 2026-10-15
|
||
|
||
MySQL 3306 demo + Redis 6379:`go run ./cmd/opsxdb-mcp-accept/` 全过。实践文档:`~/Downloads/AI-Agent接入GUI工具开发实践.md`。
|