feat: add standard MCP tool support#212
Conversation
|
✅ OpenCodeReview: No supported files changed. |
d1ffbc4 to
4ffc7f1
Compare
4ffc7f1 to
fc0c332
Compare
Add MCP client and provider packages that allow integrating external MCP tool servers into the review loop. Includes config commands for managing MCP servers, stdio subprocess integration tests, and comprehensive test coverage.
fc0c332 to
6c9ae5f
Compare
…ng Client receiver
The MCP server setup command was hardcoded to use `sh -c`, which fails on Windows. Extract a `shellCommand` helper behind build tags to use `cmd /c` on Windows and `sh -c` elsewhere.
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.
Adds MCP (Model Context Protocol) stdio-based tool integration so OpenCodeReview can discover/register external tools and execute them in the review loop, with corresponding CLI config and documentation updates.
Changes:
- Introduces an
internal/mcpclient/provider layer (connect, list tools, call tools, register into tool registry). - Extends tool definitions with reserved-name detection and dynamic tool creation.
- Adds CLI config support for
mcp_servers.*plus README updates across multiple languages.
Reviewed changes
Copilot reviewed 22 out of 23 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/tool/definitions.go | Adds reserved-name check and dynamic tool factory for MCP-discovered tools. |
| internal/tool/definitions_test.go | Adds tests for reserved-name detection and dynamic tool creation constraints. |
| internal/mcp/client.go | Adds MCP stdio client wrapper (connect, list tools, call tools). |
| internal/mcp/client_test.go | Adds unit/integration tests for client behavior and content rendering. |
| internal/mcp/provider.go | Adds MCP tool Provider adapter, tool registration, and tooldef collection. |
| internal/mcp/provider_test.go | Adds tests for MCP provider registration/filtering and tooldef conversion. |
| internal/mcp/stdio_test.go | Adds subprocess-backed stdio transport integration test. |
| internal/llmloop/loop.go | Enables executing dynamically-registered tools via the tool registry. |
| cmd/opencodereview/review_cmd.go | Initializes MCP clients from config, registers tools, and adds tool defs to agent. |
| cmd/opencodereview/shell_unix.go | Adds sh -c helper for running MCP setup commands on Unix. |
| cmd/opencodereview/shell_windows.go | Adds cmd /c helper for running MCP setup commands on Windows. |
| cmd/opencodereview/procattr_unix.go | Adds process-group handling to better kill setup command subprocess trees on Unix. |
| cmd/opencodereview/procattr_windows.go | Documents Windows limitation for process-tree cleanup. |
| cmd/opencodereview/config_cmd.go | Adds mcp_servers config schema, set/unset support, and config validation logic. |
| cmd/opencodereview/config_cmd_test.go | Adds tests for MCP server config set/unset behavior and validation. |
| cmd/opencodereview/flags.go | Updates CLI help text for MCP server config keys. |
| go.mod | Adds MCP SDK dependency and bumps Go version directive. |
| go.sum | Updates sums for new/updated dependencies. |
| README.md | Documents MCP server config keys and usage. |
| README.ja-JP.md | Documents MCP server config keys and usage (Japanese). |
| README.ko-KR.md | Documents MCP server config keys and usage (Korean). |
| README.ru-RU.md | Documents MCP server config keys and usage (Russian). |
| README.zh-CN.md | Documents MCP server config keys and usage (Chinese). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if result.IsError { | ||
| return fmt.Sprintf("MCP tool %q returned an error: %s", name, contentToText(result.Content)), nil | ||
| } |
| transport := &mcp.CommandTransport{Command: cmd} | ||
| session, err := client.Connect(ctx, transport, nil) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("connect to MCP server %q: %w", name, err) | ||
| } |
| for _, t := range c.Tools() { | ||
| if filtering { | ||
| if _, ok := allowed[t.Name]; !ok { | ||
| continue | ||
| } | ||
| matched[t.Name] = struct{}{} | ||
| } | ||
| if tool.IsReserved(t.Name) { | ||
| fmt.Fprintf(os.Stderr, "[ocr] WARNING: MCP server %q tool %q conflicts with built-in tool, skipping\n", c.Name(), t.Name) | ||
| continue | ||
| } |
| if err != nil { | ||
| t.Fatalf("NewClient: %v", err) | ||
| } | ||
| defer c.Close() |
| if err := c.Close(); err != nil { | ||
| t.Errorf("Close: %v", err) | ||
| } |
| } | ||
|
|
||
| c := &Client{name: "test-srv", session: session, tools: toolsResult.Tools} | ||
| defer c.Close() |
| t.Run("Close", func(t *testing.T) { | ||
| if err := c.Close(); err != nil { | ||
| t.Errorf("Close: %v", err) | ||
| } | ||
| }) |
|
已处理 Copilot 提出的全部 7 条评审建议,修复提交:56b9d54 错误处理(2 条)
健壮性(1 条)
测试 double-close(4 条)
|
|
| if result.IsError { | ||
| return fmt.Sprintf("MCP tool %q returned an error: %s", name, contentToText(result.Content)), nil | ||
| } |
| params := map[string]any{"type": "object"} | ||
|
|
||
| switch schema := t.InputSchema.(type) { | ||
| case map[string]any: | ||
| for k, v := range schema { | ||
| params[k] = v | ||
| } | ||
| if _, ok := params["type"]; !ok { | ||
| params["type"] = "object" | ||
| } |
| if err != nil { | ||
| t.Fatalf("NewClient: %v", err) | ||
| } | ||
| defer c.Close() |
| if err := c.Close(); err != nil { | ||
| t.Errorf("Close: %v", err) | ||
| } |
| session: session, | ||
| tools: toolsResult.Tools, | ||
| } | ||
| defer c.Close() |
| t.Run("Close", func(t *testing.T) { | ||
| if err := c.Close(); err != nil { | ||
| t.Errorf("Close: %v", err) | ||
| } | ||
| }) |
| module github.com/open-code-review/open-code-review | ||
|
|
||
| go 1.25.0 | ||
| go 1.25.5 |
| if serverCfg.Setup != "" { | ||
| fmt.Fprintf(os.Stderr, "[ocr] Running setup for MCP server %q: %s\n", name, serverCfg.Setup) | ||
| setupCtx, setupCancel := context.WithTimeout(ctx, 5*time.Minute) | ||
| setupCmd := shellCommand(setupCtx, serverCfg.Setup) | ||
| setupCmd.Dir = repoDir | ||
| configureProcessGroup(setupCmd) | ||
| output, err := setupCmd.CombinedOutput() | ||
| setupCancel() |
Summary
This PR introduces standard MCP (Model Context Protocol) tool support for OpenCodeReview, enabling extensible context capabilities for the review agent.
Closes #210