internal/mcp/client.go — MCP client

stdio/remote client、CallTool、工具白名單
套件:internal/mcp/(client.go + provider.go + stdio_test.go)

大方向

internal/mcp 是 OCR 的 MCP client 實作。它啟動外部 MCP server(stdio 子程序或遠端 HTTP),註冊其宣告的工具,供評審 agent 呼叫。核心是 ClientNewClient 建 stdio client、NewRemoteClient 建遠端 client、CallTool 把工具呼叫轉成 MCP 請求。


1. Client 建構

NewClient(ctx, name, command, args, env, dir, version) client.go啟動 stdio MCP server 子程序。

NewClientexec.CommandContext 啟動 command(如 npx),透過 stdin/stdout 走 MCP stdio 協議。30 秒初始化超時內完成 handshake,取得 server 宣告的工具清單(存進 c.tools)。失敗回傳錯誤——review 命令層會把錯誤記進 warning 並繼續。

NewRemoteClient(ctx, name, url, headers, version) client.go連遠端 MCP server(HTTP)。

遠端變體用 headerTransport(自訂 RoundTrip)注入認證 headers,走 HTTP MCP(SSE/streamable)。c.tools 同樣由 server 的 tools/list 填入。

2. 工具呼叫

CallTool(ctx, name, args) · contentToText() client.go把工具呼叫轉成 MCP 請求,內容轉純文字。

CallTooltools/call 請求,把回傳的 []mcp.Content(text/image/resource)用 contentToText 轉成單一字串——因為評審 agent 的工具介面只吃字串結果。

3. 與工具層整合

Tools() · Name() · Close() client.go對 review 命令層暴露的存取方法。

review_cmd.goinitMCPClients 依 config 建 client 後,用 Tools() 把每個 server 的工具註冊成 tool.Dynamic(name) 進 registry。工具名衝突時由 tool.IsReserved 攔截(見 internal/tool)。

看完這頁你應該能說出:MCP client 兩種變體(stdio/remote)、30 秒初始化握手、CallTool 為何要轉純文字、以及 client 如何透過 Dynamic 工具進評審 registry。

延伸閱讀:MCP 文件 · internal/tool · 回程式碼對照