Skip to content

Conversation

@aatchison
Copy link
Collaborator

🐛 Problem

The registerDefaultHandlers() function was unconditionally overriding custom handlers that servers had already registered. This prevented servers from implementing custom tools/list, prompts/list, and resources/list handlers.

Impact:

  • Servers couldn't provide custom tool lists
  • Custom MCP protocol implementations were being overwritten
  • Framework was not respecting the principle of "custom handlers first"

🔧 Solution

Modified registerDefaultHandlers() to check if handlers already exist before registering defaults:

func (s *Server) registerDefaultHandlers() {
    // Only register default handlers if custom ones don't exist
    if s.toolsListHandler == nil {
        s.toolsListHandler = s.handleToolsList
    }
    if s.promptsListHandler == nil {
        s.promptsListHandler = s.handlePromptsList  
    }
    if s.resourcesListHandler == nil {
        s.resourcesListHandler = s.handleResourcesList
    }
}

✅ Benefits

  1. Preserves Custom Handlers - Servers can register custom handlers before calling Start()
  2. Backward Compatible - Servers not using custom handlers continue to work unchanged
  3. Follows Best Practices - Custom implementations take precedence over defaults
  4. Enables Advanced Use Cases - Servers can now provide dynamic tool lists, custom prompts, etc.

🧪 Testing

Before Fix:

// Custom handler gets overwritten
server.RegisterHandler("tools/list", customHandler)
server.Start() // Overwrites with default handler

After Fix:

// Custom handler is preserved
server.RegisterHandler("tools/list", customHandler) 
server.Start() // Keeps custom handler

📁 Files Changed

  • pkg/mcp/server.go: Modified registerDefaultHandlers() to check for existing handlers

🔗 Related Issues

This enables the mcp-server-devpod project to provide custom tools/list handlers that include both framework tools (echo) and DevPod-specific tools, fixing Claude Desktop compatibility issues.

✅ Verification

  • Backward compatibility maintained
  • Custom handlers are preserved
  • Default handlers still work when no custom handlers exist
  • No breaking changes to existing API

- Modified registerDefaultHandlers() to check if handlers already exist
- Prevents overriding custom tools/list, prompts/list, resources/list handlers
- Allows servers to register custom handlers before calling Start()
- Maintains backward compatibility for servers not using custom handlers
- Added TestServerCustomHandlersPreserved to validate the fix
- Tests that custom tools/list, prompts/list, and resources/list handlers
  are not overridden by registerDefaultHandlers()
- Verifies custom handlers are called and return expected results
- Ensures backward compatibility and proper handler precedence
- Updated echo tool implementation to match test expectations
- Tests expect 'Echo: [message]' but tool was returning just '[message]'
- This fixes both STDIO and HTTP Streams transport test failures
@aatchison aatchison marked this pull request as ready for review June 9, 2025 02:03
@aatchison aatchison merged commit b306edc into main Jun 9, 2025
14 checks passed
@aatchison aatchison deleted the fix-handler-override branch June 9, 2025 02:03
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.

3 participants