-
Notifications
You must be signed in to change notification settings - Fork 684
feat(get-server-tools): add GetTools method for retrieve MCPServer.tools #437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughA new method, Changes
Suggested labels
Suggested reviewers
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 golangci-lint (1.64.8)Error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2 ✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
server/server.go
(1 hunks)server/server_test.go
(1 hunks)
🔇 Additional comments (2)
server/server_test.go (2)
2026-2380
: Excellent comprehensive test coverage.The test suite covers all important scenarios including edge cases, concurrency, and complex schemas. The test structure with subtests is well-organized and the assertions are thorough.
2210-2259
: Improve concurrent test to avoid potential race conditions.The current concurrent test has timing issues where multiple goroutines add tools concurrently, but the verification logic doesn't guarantee all tools are added before
GetTools
is called in each goroutine.Consider this improved approach:
t.Run("ConcurrentAccess", func(t *testing.T) { server := NewMCPServer("test-server", "1.0.0") - // Number of goroutines for testing - numGoroutines := 100 - numToolsPerGoroutine := 10 + // Pre-add some tools to test concurrent reads + for i := 0; i < 50; i++ { + server.AddTool(mcp.Tool{ + Name: fmt.Sprintf("pre-tool-%d", i), + Description: fmt.Sprintf("Pre-added tool %d", i), + }, nil) + } - // Channel to collect results - results := make(chan map[string]ServerTool, numGoroutines) + numGoroutines := 100 + results := make(chan map[string]ServerTool, numGoroutines) + var wg sync.WaitGroup - // Start goroutines that concurrently call GetTools + // Test concurrent reads (no race conditions in test logic) for i := 0; i < numGoroutines; i++ { + wg.Add(1) go func(id int) { - // Add some tools specific to this goroutine - for j := 0; j < numToolsPerGoroutine; j++ { - toolName := fmt.Sprintf("tool-%d-%d", id, j) - server.AddTool(mcp.Tool{ - Name: toolName, - Description: fmt.Sprintf("Tool %d from goroutine %d", j, id), - }, nil) - } - - // Get tools + defer wg.Done() tools, err := server.GetTools() assert.NoError(t, err) results <- tools }(i) } + wg.Wait() + close(results) + // Collect all results var allResults []map[string]ServerTool - for i := 0; i < numGoroutines; i++ { - result := <-results + for result := range results { allResults = append(allResults, result) } // Verify that no data races occurred and all results are valid for _, result := range allResults { assert.NotNil(t, result) - // Each result should have at least some tools (may not have all due to timing) - assert.Greater(t, len(result), 0) + assert.Equal(t, 50, len(result), "All concurrent reads should return same number of tools") } - - // Final check - get all tools at the end - finalTools, err := server.GetTools() - assert.NoError(t, err) - assert.NotNil(t, finalTools) - // Should have exactly numGoroutines * numToolsPerGoroutine tools - assert.Equal(t, numGoroutines*numToolsPerGoroutine, len(finalTools)) })Likely an incorrect or invalid review comment.
2cd60ac
to
d13b0ed
Compare
@coderabbitai review |
✅ Actions performedReview triggered.
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
server/server.go (1)
496-510
: Consider returning empty map instead of error for no tools.The current implementation returns an error when no tools are registered, but this may not align with Go conventions. Typically, empty collections return empty maps rather than errors unless the absence of data represents a true error condition.
Consider this approach instead:
-// GetTools retrieves the currently registered tools -func (s *MCPServer) GetTools() (map[string]ServerTool, error) { - s.toolsMu.RLock() - defer s.toolsMu.RUnlock() - // Create a copy to prevent external modification - if len(s.tools) == 0 { - return nil, fmt.Errorf("no tools registered") - } - toolsCopy := make(map[string]ServerTool, len(s.tools)) - for name, tool := range s.tools { - toolsCopy[name] = tool - } - return toolsCopy, nil -} +// GetTools retrieves the currently registered tools +func (s *MCPServer) GetTools() (map[string]ServerTool, error) { + s.toolsMu.RLock() + defer s.toolsMu.RUnlock() + // Create a copy to prevent external modification + toolsCopy := make(map[string]ServerTool, len(s.tools)) + for name, tool := range s.tools { + toolsCopy[name] = tool + } + return toolsCopy, nil +}However, if the current error behavior is intentional for your API design, the implementation is otherwise correct with proper concurrency safety and data encapsulation.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
server/server.go
(1 hunks)server/server_test.go
(2 hunks)
🔇 Additional comments (2)
server/server_test.go (2)
11-11
: Good addition of sync import for concurrent testing.The
sync
import is appropriately added to support the concurrent access testing in the new test suite.
2027-2419
: Excellent comprehensive test suite for GetTools method.This test suite is exceptionally well-designed and thorough, covering:
- Edge cases: Empty server state, single and multiple tools
- State modifications: Tool deletion and replacement via SetTools
- Concurrency safety: 100 goroutines testing thread safety
- Data integrity: Verification that copies are returned, not references
- Complex scenarios: Complex tool schemas with nested properties and annotations
- Consistency: Multiple calls returning identical results
The concurrent test properly uses goroutines with synchronization to collect results and verify no data races occur. The copy verification test effectively demonstrates that external modifications don't affect the server's internal state.
Key strengths:
- Proper use of
sync.WaitGroup
for concurrent testing- Comprehensive assertion coverage with meaningful error messages
- Tests validate both data correctness and behavioral expectations
- Good separation of concerns with focused sub-tests
Hello @ezynda3, could you please take a look |
Description
This PR adds the GetTools method for retrieving the MCPServer.tools.
Initially, I was developing the custom
tools manager
for my project, but faced the issue that I couldn't synchronizeMCPServer.tools
with the customTools manager
list of tools, which could possibly lead to issues.Fixes #<issue_number> (if applicable)
Type of Change
Checklist
MCP Spec Compliance
Additional Information
This PR adds comprehensive tests for the
GetTools
method in the MCPServer.Changes
Test Coverage
All tests pass and integrate well with the existing test suite.
Summary by CodeRabbit
New Features
Tests