docs(ai): 真库验收记录 + mcp-accept 用例入口
MySQL demo / Redis 真库跑通只读 MCP;补充验收说明与 cmd/opsxdb-mcp-accept。实践长文在 ~/Downloads。
This commit is contained in:
1 parent
0b68c8344d
commit
b8134c4503
2 files changed
+109
No files matched your search
@@ -191,3 +191,8 @@ go build -o ../bin/opsxdb-mcp ./cmd/opsxdb-mcp
|
||||
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`。
|
||||
@@ -0,0 +1,104 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"opsxdb/server/internal/aitools"
|
||||
)
|
||||
|
||||
func must(ok bool, msg string) {
|
||||
if !ok {
|
||||
fmt.Println("FAIL:", msg)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("OK:", msg)
|
||||
}
|
||||
|
||||
func dump(v any) string {
|
||||
b, _ := json.MarshalIndent(v, "", " ")
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func main() {
|
||||
rt, err := aitools.DefaultRuntime()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mysqlID := "accept-mysql-demo"
|
||||
redisID := "accept-redis-demo"
|
||||
ctx := context.Background()
|
||||
|
||||
out, err := rt.Call(ctx, aitools.ToolListConnections, map[string]any{})
|
||||
s := dump(out)
|
||||
must(err == nil && strings.Contains(s, mysqlID) && !strings.Contains(s, `"password"`), "list_connections")
|
||||
|
||||
out, err = rt.Call(ctx, aitools.ToolListDatabases, map[string]any{"connection_id": mysqlID})
|
||||
s = dump(out)
|
||||
must(err == nil && strings.Contains(s, "demo"), "list_databases: "+fmt.Sprint(err)+" "+s)
|
||||
|
||||
out, err = rt.Call(ctx, aitools.ToolListTables, map[string]any{"connection_id": mysqlID, "database": "demo"})
|
||||
s = dump(out)
|
||||
must(err == nil, "list_tables: "+fmt.Sprint(err)+" "+s)
|
||||
fmt.Println(s[:min(600, len(s))])
|
||||
|
||||
var tables []string
|
||||
if m, ok := out.(map[string]any); ok {
|
||||
if arr, ok := m["tables"].([]any); ok {
|
||||
for _, x := range arr {
|
||||
tables = append(tables, fmt.Sprint(x))
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(tables) > 0 {
|
||||
t := tables[0]
|
||||
_, err = rt.Call(ctx, aitools.ToolDescribeTable, map[string]any{"connection_id": mysqlID, "database": "demo", "table": t})
|
||||
must(err == nil, "describe_table "+t+": "+fmt.Sprint(err))
|
||||
out, err = rt.Call(ctx, aitools.ToolGetSchemaContext, map[string]any{"connection_id": mysqlID, "database": "demo"})
|
||||
must(err == nil && len(dump(out)) > 20, "get_schema_context")
|
||||
_ = out
|
||||
}
|
||||
|
||||
out, err = rt.Call(ctx, aitools.ToolExecuteQuery, map[string]any{
|
||||
"connection_id": mysqlID,
|
||||
"database": "demo",
|
||||
"sql": "SELECT 1 AS n, DATABASE() AS db",
|
||||
})
|
||||
s = dump(out)
|
||||
must(err == nil && strings.Contains(s, "demo"), "execute_query SELECT: "+fmt.Sprint(err)+" "+s)
|
||||
fmt.Println(s[:min(500, len(s))])
|
||||
|
||||
_, err = rt.Call(ctx, aitools.ToolExecuteQuery, map[string]any{
|
||||
"connection_id": mysqlID,
|
||||
"sql": "DROP TABLE IF EXISTS __opsxdb_should_deny__",
|
||||
})
|
||||
must(err != nil, "DROP must fail, got nil")
|
||||
|
||||
out, err = rt.Call(ctx, aitools.ToolExecuteRedisCommand, map[string]any{
|
||||
"connection_id": redisID,
|
||||
"command": "PING",
|
||||
})
|
||||
s = dump(out)
|
||||
must(err == nil && strings.Contains(strings.ToUpper(s), "PONG"), "redis PING: "+fmt.Sprint(err)+" "+s)
|
||||
|
||||
_, err = rt.Call(ctx, aitools.ToolExecuteRedisCommand, map[string]any{
|
||||
"connection_id": redisID,
|
||||
"command": "FLUSHDB",
|
||||
})
|
||||
must(err != nil, "FLUSHDB must fail")
|
||||
|
||||
_, err = rt.Call(ctx, aitools.ToolListTables, map[string]any{"connection_id": "not-allowed"})
|
||||
must(err != nil, "whitelist reject")
|
||||
|
||||
fmt.Println("ALL ACCEPTANCE PASSED")
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
Reference in new issue
Block a user