feat(mcp): P0 只读 MCP tool runtime + opsxdb-mcp stdio
- aitools 共用 runtime:list/describe/schema/query/redis(纯只读,无写确认) - 白名单 ~/.opsxdb/mcp.json;审计 mcp-audit.jsonl;复用 danger.go - 桌面 connections 双写 ~/.opsxdb/connections.json(ox1. 解码) - Cursor 配置示例与任务书验收勾选更新;写操作与 Agent UI 留 P1
This commit is contained in:
1 parent
5c17d32647
commit
0b68c8344d
19 files changed
+1989
-79
No files matched your search
@@ -0,0 +1,56 @@
|
||||
package aitools
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AuditEntry MCP/Agent 工具审计;不含密码与大结果全文。 // Logan.Li
|
||||
type AuditEntry struct {
|
||||
Time string `json:"time"`
|
||||
Tool string `json:"tool"`
|
||||
ConnectionID string `json:"connection_id,omitempty"`
|
||||
Mode string `json:"mode"`
|
||||
OK bool `json:"ok"`
|
||||
Summary string `json:"summary,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
var auditMu sync.Mutex
|
||||
|
||||
func AuditPath() (string, error) {
|
||||
dir, err := opsxdbDir()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(dir, "logs", "mcp-audit.jsonl"), nil
|
||||
}
|
||||
|
||||
// AppendAudit 追加一行 JSONL;失败静默(不影响工具主路径)。
|
||||
func AppendAudit(e AuditEntry) {
|
||||
if e.Time == "" {
|
||||
e.Time = time.Now().Format(time.RFC3339)
|
||||
}
|
||||
path, err := AuditPath()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
auditMu.Lock()
|
||||
defer auditMu.Unlock()
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
|
||||
return
|
||||
}
|
||||
b, err := json.Marshal(e)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
_, _ = f.Write(append(b, '\n'))
|
||||
}
|
||||
Reference in new issue
Block a user