Skip to content

feat: add standard MCP tool support#212

Merged
lizhengfeng101 merged 4 commits into
mainfrom
feat/mcp-support
Jul 1, 2026
Merged

feat: add standard MCP tool support#212
lizhengfeng101 merged 4 commits into
mainfrom
feat/mcp-support

Conversation

@lizhengfeng101

Copy link
Copy Markdown
Collaborator

Summary

This PR introduces standard MCP (Model Context Protocol) tool support for OpenCodeReview, enabling extensible context capabilities for the review agent.

  • Add MCP tool integration framework with standard protocol support
  • CodeGraph will likely be the first built-in MCP extension, providing structural code analysis (symbol definitions, callers, callees, impact radius)

🚧 Work in Progress — implementation is under evaluation.

Closes #210

@github-actions

Copy link
Copy Markdown
Contributor

OpenCodeReview: No supported files changed.

@lizhengfeng101
lizhengfeng101 marked this pull request as ready for review July 1, 2026 05:25
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.
@lizhengfeng101 lizhengfeng101 changed the title [WIP] feat: add standard MCP tool support feat: add standard MCP tool support Jul 1, 2026
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.
@MuoDoo
MuoDoo requested a review from Copilot July 1, 2026 08:27
@lizhengfeng101
lizhengfeng101 requested review from MuoDoo and css521 July 1, 2026 08:33

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/mcp client/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.

Comment thread internal/mcp/client.go
Comment on lines +78 to +80
if result.IsError {
return fmt.Sprintf("MCP tool %q returned an error: %s", name, contentToText(result.Content)), nil
}
Comment thread internal/mcp/client.go
Comment on lines +37 to +41
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)
}
Comment thread internal/mcp/provider.go
Comment on lines +38 to +48
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()
Comment on lines +96 to +98
if err := c.Close(); err != nil {
t.Errorf("Close: %v", err)
}
}

c := &Client{name: "test-srv", session: session, tools: toolsResult.Tools}
defer c.Close()
Comment on lines +225 to +229
t.Run("Close", func(t *testing.T) {
if err := c.Close(); err != nil {
t.Errorf("Close: %v", err)
}
})
@lizhengfeng101

Copy link
Copy Markdown
Collaborator Author

已处理 Copilot 提出的全部 7 条评审建议,修复提交:56b9d54

错误处理(2 条)

  • client.go:80CallToolIsError=true 时现在返回非 nil error,调用方和遥测能正确识别工具失败
  • client.go:41Connect 失败时显式 kill 已启动的子进程,防止孤儿进程泄漏

健壮性(1 条)

  • provider.go:48RegisterAll 增加空工具名防护,跳过并打印警告,避免后续 tool.Dynamic("") panic

测试 double-close(4 条)

  • stdio_test.go:71,98 + client_test.go:116,229 — 移除多余的 defer c.Close(),保留显式 close 断言,避免 double-close 导致的 flaky 行为

@lizhengfeng101

Copy link
Copy Markdown
Collaborator Author

已处理 Copilot 提出的全部 7 条评审建议,修复提交:56b9d54

错误处理(2 条)

  • client.go:80CallToolIsError=true 时现在返回非 nil error,调用方和遥测能正确识别工具失败
  • client.go:41Connect 失败时显式 kill 已启动的子进程,防止孤儿进程泄漏

健壮性(1 条)

  • provider.go:48RegisterAll 增加空工具名防护,跳过并打印警告,避免后续 tool.Dynamic("") panic

测试 double-close(4 条)

  • stdio_test.go:71,98 + client_test.go:116,229 — 移除多余的 defer c.Close(),保留显式 close 断言,避免 double-close 导致的 flaky 行为

@MuoDoo

@MuoDoo
MuoDoo requested a review from Copilot July 1, 2026 09:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 23 changed files in this pull request and generated 8 comments.

Comment thread internal/mcp/client.go
Comment on lines +78 to +80
if result.IsError {
return fmt.Sprintf("MCP tool %q returned an error: %s", name, contentToText(result.Content)), nil
}
Comment thread internal/mcp/provider.go
Comment on lines +68 to +77
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()
Comment on lines +96 to +98
if err := c.Close(); err != nil {
t.Errorf("Close: %v", err)
}
session: session,
tools: toolsResult.Tools,
}
defer c.Close()
Comment on lines +225 to +229
t.Run("Close", func(t *testing.T) {
if err := c.Close(); err != nil {
t.Errorf("Close: %v", err)
}
})
Comment thread go.mod
module github.com/open-code-review/open-code-review

go 1.25.0
go 1.25.5
Comment on lines +216 to +223
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()

@MuoDoo MuoDoo left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@lizhengfeng101
lizhengfeng101 merged commit 6adcb1e into main Jul 1, 2026
7 checks passed
@lizhengfeng101
lizhengfeng101 deleted the feat/mcp-support branch July 1, 2026 11:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add optional CodeGraph structural context tool

3 participants