Skip to content

feat: support custom tools via Model Context Protocol (MCP)#60

Merged
menny merged 6 commits intomainfrom
feat/prebuilt-binaries
Apr 21, 2026
Merged

feat: support custom tools via Model Context Protocol (MCP)#60
menny merged 6 commits intomainfrom
feat/prebuilt-binaries

Conversation

@menny
Copy link
Copy Markdown
Owner

@menny menny commented Apr 21, 2026

This PR introduces support for the Model Context Protocol (MCP) in Cassandra, allowing the reviewer to connect to custom local or remote tools to extend its capabilities.

Features

  • New CLI flag --mcp-config to provide an mcp.json configuration file.
  • Support for local stdio servers (subprocesses) and remote sse (HTTP) servers.
  • Automatic environment variable expansion (os.ExpandEnv) for all configuration values (commands, URLs, headers).
  • Discovery and registration of tools from MCP servers.
  • Integration into the GitHub Action with a new mcp_config input.
  • Comprehensive documentation and examples in README.md.

Fixes #43

Introduce MCP support in Cassandra, allowing the reviewer to utilize custom
tools during the review process. This includes:
- A new CLI flag '--mcp-config' to provide an 'mcp.json' configuration file.
- Support for local 'stdio' servers and remote 'sse' (HTTP) servers.
- Automatic environment variable expansion (os.ExpandEnv) for all configuration values.
- Discovery and registration of tools from MCP servers.
- Integration into the GitHub Action with a new 'mcp_config' input.
- Detailed documentation and usage examples in README.md.
- Unit tests for configuration expansion and tool registration.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 21, 2026

This is an exceptionally well-executed revision. The extraction of main logic into run(ctx) robustly resolves the unexecuted deferred calls issue. Correctly cloning the http.Request in the RoundTripper, applying a strict timeout, capturing error outputs, and expanding test coverage significantly improve stability and reliability.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

The PR introduces a great addition for codebase analysis via the MCP spec, but has critical safety and resilience issues including http.RoundTripper contract violations and indefinite blocking risks that must be fixed before approval.

Comment thread tools/mcp/client.go

res, err := session.CallTool(ctx, callParams)
if err != nil {
return "", fmt.Errorf("MCP tool call failed: %w", err)
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

MCP configuration should have timeout (in seconds) configuration (with 30 seconds default).

Comment thread tools/mcp/client.go
Comment thread tools/mcp/client.go

res, err := session.CallTool(ctx, callParams)
if err != nil {
return "", fmt.Errorf("MCP tool call failed: %w", err)
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

MCP configuration should have timeout (in seconds) configuration (with 30 seconds default).

Comment thread tools/mcp/client.go
- Fix http.RoundTripper contract violation by cloning the request in headerRoundTripper.
- Prevent indefinite blocking by adding a configurable timeout (default 30s) to MCP tool calls.
- Improve error visibility by returning the MCP tool's error content to the model for self-correction.
- Added TimeoutSeconds to ServerConfig in mcp.json schema.
@menny
Copy link
Copy Markdown
Owner Author

menny commented Apr 21, 2026

I've addressed the resilience and safety issues identified in the review:

  • http.RoundTripper Safety: Added request cloning in headerRoundTripper.RoundTrip to respect the http.RoundTripper contract and avoid mutation of the input request.
  • Indefinite Blocking: Added a configurable timeout for MCP tool calls (via timeoutCtx). The mcp.json schema now supports timeoutSeconds (defaulting to 30s).
  • Opaque Errors: Tool error content is now captured and returned to the LLM when res.IsError is true, allowing the model to potentially self-correct its parameters.

Verified with bazel test //tools/mcp:all and golangci-lint.

@github-actions github-actions Bot dismissed their stale review April 21, 2026 02:05

Superseded by a new AI review.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Good progress on resilience and safety, but requires fixes for test cleanup (goroutine leaks) and environment variable handling before merging.

… guidelines

- Use exec.CommandContext for MCP subprocesses to ensure they are reaped on context cancellation.
- Prevent goroutine leaks in tests by using cancelable contexts for mock servers.
- Use t.Setenv in tests for isolated and safe environment variable setup.
- Update RegisterServers to return errors if no servers could be registered, making the error check in main reachable.
- Fix unsafe exit in main.go by explicitly closing the MCP manager before os.Exit on failure.
- Document the map[string]any exception for MCP tool arguments in client.go and AGENTS.md.
- Add goroutine leak prevention guideline to AGENTS.md.
@menny
Copy link
Copy Markdown
Owner Author

menny commented Apr 21, 2026

I've addressed the second round of review feedback:

  • Subprocess Lifecycle: Replaced exec.Command with exec.CommandContext to ensure MCP subprocesses are reaped if the main context is canceled.
  • Testing Resilience: Fixed a goroutine leak in client_test.go by using a cancelable context for the mock server.
  • Isolated Tests: Switched to t.Setenv in config_test.go for safer, isolated environment setup.
  • Reachable Error Handling: Updated RegisterServers to return an error if all registrations fail, and fixed the unsafe exit in main.go to ensure mcpManager.Close() is called before os.Exit.
  • Guideline Documentation: Added documentation in client.go and AGENTS.md explaining the intentional use of map[string]any for MCP tool arguments.
  • New Guidelines: Added a new guideline to AGENTS.md regarding goroutine leak prevention in tests.

Verified with bazel test //tools/mcp:all and golangci-lint.

@github-actions github-actions Bot dismissed their stale review April 21, 2026 02:19

Superseded by a new AI review.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

The handling of the http.RoundTripper cloning, test isolations, and context scoping are much improved, but changes are requested to address two edge cases in tools/mcp/client.go regarding context cancellation and swallowed JSON errors.

Introduce support for the Model Context Protocol (MCP) to allow the AI
reviewer to utilize custom external tools. This includes:
- A new 'tools/mcp' package supporting stdio and SSE transports.
- Integration into the main review loop via the --mcp-config flag.
- Detailed configuration support with environment variable expansion.

Refactor the tool registry and core agent to support context forwarding.
This ensures that all tool executions, including local git operations and
remote MCP calls, respect application-level timeouts and cancellation
signals by using exec.CommandContext and proper context chaining.

Fixes several PR feedback items:
- SSE transport now correctly follows http.RoundTripper contracts.
- Improved error reporting for MCP server initialization failures.
- Ensured subprocesses are reaped on context cancellation.
@github-actions github-actions Bot dismissed their stale review April 21, 2026 13:57

Superseded by a new AI review.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Great work handling edge cases for resilience, but rejected due to missing test coverage for the real MCP tool handler and context propagation.

- Extract registerServerWithTransport to enable testing of the production MCP tool handler.
- Update tools/mcp/client_test.go to use the production handler and verify error handling.
- Add TestAgent_ExecuteToolCalls_ContextPropagation to core/agent_test.go to confirm that canceled contexts are correctly forwarded to tool dispatchers.
@github-actions github-actions Bot dismissed their stale review April 21, 2026 14:05

Superseded by a new AI review.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Previous feedback was well addressed, but there is a blocking issue regarding potential MCP subprocess leaks when log.Fatalf bypasses deferred cleanup calls.

Refactor cmd/ai_reviewer/main.go to move its core logic into a run() function.
This ensures that all deferred statements, such as mcpManager.Close(), are
executed before the process terminates via os.Exit. This prevents orphan MCP
subprocess issues on fatal errors.
@github-actions github-actions Bot dismissed their stale review April 21, 2026 14:59

Superseded by a new AI review.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

The revision perfectly addresses structural and edge-case issues, including robust error cleanup, request cloning, timeouts, error capturing, and expanded test coverage.

@menny menny merged commit b63212d into main Apr 21, 2026
2 checks passed
@menny menny deleted the feat/prebuilt-binaries branch April 21, 2026 15:02
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.

Support custom tools/mcps for the reviewer to use

1 participant