🔍 Duplicate Code Pattern: MCP Session Validation Checks
Part of duplicate code analysis: #970
Summary
The internal/mcp/connection.go file contains 6 identical session nil checks across different MCP method wrappers. Each method performs the exact same validation before executing its SDK call.
Duplication Details
Pattern: Repeated Session Nil Validation
- Severity: Medium
- Occurrences: 6 instances
- Locations:
internal/mcp/connection.go:
- Line 821-823:
listTools()
- Line 833-835:
callTool()
- Line 867-869:
listResources()
- Line 879-881:
readResource()
- Line 901-903:
listPrompts()
- Line 913-915:
getPrompt()
Code Sample:
func (c *Connection) listTools() (*Response, error) {
if c.session == nil {
return nil, fmt.Errorf("SDK session not available for plain JSON-RPC transport")
}
result, err := c.session.ListTools(c.ctx, &sdk.ListToolsParams{})
if err != nil {
return nil, err
}
return marshalToResponse(result)
}
func (c *Connection) listResources() (*Response, error) {
if c.session == nil {
return nil, fmt.Errorf("SDK session not available for plain JSON-RPC transport")
}
result, err := c.session.ListResources(c.ctx, &sdk.ListResourcesParams{})
if err != nil {
return nil, err
}
return marshalToResponse(result)
}
// ... 4 more methods with identical session nil check
Impact Analysis
- Maintainability: Medium Impact - Error message changes require updating 6 locations
- Bug Risk: Medium - Risk of inconsistent error messages if updates are missed
- Code Bloat: ~18 lines of duplicate validation code (6 checks × 3 lines each)
- Consistency: Error messages could diverge over time if not carefully maintained
Refactoring Recommendations
1. Extract Session Validation Helper (Recommended)
Create a helper method to centralize the session validation:
// In connection.go
func (c *Connection) requireSession() error {
if c.session == nil {
return fmt.Errorf("SDK session not available for plain JSON-RPC transport")
}
return nil
}
// Updated methods use the helper:
func (c *Connection) listTools() (*Response, error) {
if err := c.requireSession(); err != nil {
return nil, err
}
result, err := c.session.ListTools(c.ctx, &sdk.ListToolsParams{})
if err != nil {
return nil, err
}
return marshalToResponse(result)
}
func (c *Connection) listResources() (*Response, error) {
if err := c.requireSession(); err != nil {
return nil, err
}
result, err := c.session.ListResources(c.ctx, &sdk.ListResourcesParams{})
if err != nil {
return nil, err
}
return marshalToResponse(result)
}
// ... other methods follow same pattern
- Location:
internal/mcp/connection.go (add requireSession helper method)
- Estimated Effort: 1 hour
- Benefits:
- Single point of truth for session validation
- Consistent error messages across all methods
- Easier to enhance validation logic (e.g., add logging, metrics)
- Reduces code by ~12 lines
2. Alternative: Method Decorator Pattern (More Complex)
For a more sophisticated approach, consider a decorator that wraps SDK calls:
type sdkCall func() (interface{}, error)
func (c *Connection) withSession(call sdkCall) (*Response, error) {
if c.session == nil {
return nil, fmt.Errorf("SDK session not available for plain JSON-RPC transport")
}
result, err := call()
if err != nil {
return nil, err
}
return marshalToResponse(result)
}
// Usage:
func (c *Connection) listTools() (*Response, error) {
return c.withSession(func() (interface{}, error) {
return c.session.ListTools(c.ctx, &sdk.ListToolsParams{})
})
}
- Estimated Effort: 2-3 hours
- Benefits: More DRY, but adds complexity with closures
Implementation Checklist
Parent Issue
See parent analysis report: #970
Related to #970
AI generated by Duplicate Code Detector
🔍 Duplicate Code Pattern: MCP Session Validation Checks
Part of duplicate code analysis: #970
Summary
The
internal/mcp/connection.gofile contains 6 identical session nil checks across different MCP method wrappers. Each method performs the exact same validation before executing its SDK call.Duplication Details
Pattern: Repeated Session Nil Validation
internal/mcp/connection.go:listTools()callTool()listResources()readResource()listPrompts()getPrompt()Code Sample:
Impact Analysis
Refactoring Recommendations
1. Extract Session Validation Helper (Recommended)
Create a helper method to centralize the session validation:
internal/mcp/connection.go(addrequireSessionhelper method)2. Alternative: Method Decorator Pattern (More Complex)
For a more sophisticated approach, consider a decorator that wraps SDK calls:
Implementation Checklist
requireSession()helper method in Connection structlistTools()to use helpercallTool()to use helperlistResources()to use helperreadResource()to use helperlistPrompts()to use helpergetPrompt()to use helpermake test-allto verify no functionality brokenmake lintto ensure code qualityParent Issue
See parent analysis report: #970
Related to #970