From dca5666b18945a082b11b2cb3b60d0f5d5a0fb8e Mon Sep 17 00:00:00 2001 From: Gilles Ceyssat Date: Tue, 12 May 2026 08:13:13 +0400 Subject: [PATCH] fix(mcp-stdio): initialize result storage so query tools work MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The stdio MCP entrypoint (cmd/mcp-stdio/main.go) constructed the security Executor without calling SetResultStorage, leaving it nil. Any tool that goes through the query path — notably `exec` (the generic shell tool) and the YAML wrappers that emit large results — failed with: "错误: 结果存储未初始化" (Error: result storage not initialized) The full HTTP app at internal/app/app.go:118-147 initializes a FileResultStorage from cfg.Agent.ResultStorageDir and wires it via both agent.SetResultStorage and executor.SetResultStorage. The stdio entrypoint needs the same wiring. This replicates the storage init block in main.go so stdio-mode tool execution stops failing on the query path. Verified: before, `exec` calls returned the "结果存储未初始化" error. After, `exec nmap -p 22,80,443 127.0.0.1` (bridged through an external MCP client) returns the full nmap output as expected. --- cmd/mcp-stdio/main.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cmd/mcp-stdio/main.go b/cmd/mcp-stdio/main.go index 977d794f..6404cdd5 100644 --- a/cmd/mcp-stdio/main.go +++ b/cmd/mcp-stdio/main.go @@ -5,6 +5,7 @@ import ( "cyberstrike-ai/internal/logger" "cyberstrike-ai/internal/mcp" "cyberstrike-ai/internal/security" + "cyberstrike-ai/internal/storage" "flag" "fmt" "os" @@ -32,6 +33,23 @@ func main() { // 创建安全工具执行器 executor := security.NewExecutor(&cfg.Security, mcpServer, log.Logger) + // 初始化结果存储(与 internal/app/app.go 同样的逻辑)。 + // stdio 模式下原本不初始化,导致 'exec' 等查询型工具报"结果存储未初始化"。 + resultStorageDir := "tmp" + if cfg.Agent.ResultStorageDir != "" { + resultStorageDir = cfg.Agent.ResultStorageDir + } + if err := os.MkdirAll(resultStorageDir, 0755); err != nil { + fmt.Fprintf(os.Stderr, "创建结果存储目录失败: %v\n", err) + os.Exit(1) + } + resultStorage, err := storage.NewFileResultStorage(resultStorageDir, log.Logger) + if err != nil { + fmt.Fprintf(os.Stderr, "初始化结果存储失败: %v\n", err) + os.Exit(1) + } + executor.SetResultStorage(resultStorage) + // 注册工具 executor.RegisterTools(mcpServer)