Skip to content

Commit 523ef78

Browse files
lpcoxCopilot
andcommitted
refactor: extract generic listMCPItems helper for list* MCP operations
The three list functions (listTools, listResources, listPrompts) shared identical boilerplate: session check, log, paginateAll call, and marshalToResponse. Extract this into a generic listMCPItems helper that accepts a fetch function and result builder, reducing ~51 lines of duplication to a single 15-line helper. Each list method now delegates to listMCPItems with its type-specific SDK calls, making future additions (e.g., listResourceTemplates) a one-liner instead of 17 lines. Fixes #3155 Fixes #3156 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 81fdf1e commit 523ef78

File tree

1 file changed

+52
-40
lines changed

1 file changed

+52
-40
lines changed

internal/mcp/connection.go

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -582,22 +582,40 @@ func paginateAll[T any](
582582
return all, nil
583583
}
584584

585-
func (c *Connection) listTools() (*Response, error) {
585+
// listMCPItems is a generic helper for the list* family of MCP operations.
586+
// It handles session validation, logging, pagination, and response marshalling,
587+
// eliminating the boilerplate that was previously duplicated across listTools,
588+
// listResources, and listPrompts.
589+
func listMCPItems[Item any, Result any](
590+
c *Connection,
591+
kind string,
592+
fetchPage func(cursor string) (paginatedPage[Item], error),
593+
buildResult func([]Item) Result,
594+
) (*Response, error) {
586595
if err := c.requireSession(); err != nil {
587596
return nil, err
588597
}
589-
logConn.Printf("listTools: requesting tool list from backend serverID=%s", c.serverID)
590-
tools, err := paginateAll(c.serverID, "tools", func(cursor string) (paginatedPage[*sdk.Tool], error) {
591-
result, err := c.getSDKSession().ListTools(c.ctx, &sdk.ListToolsParams{Cursor: cursor})
592-
if err != nil {
593-
return paginatedPage[*sdk.Tool]{}, err
594-
}
595-
return paginatedPage[*sdk.Tool]{Items: result.Tools, NextCursor: result.NextCursor}, nil
596-
})
598+
logConn.Printf("list %s: requesting %s list from backend serverID=%s", kind, kind, c.serverID)
599+
items, err := paginateAll(c.serverID, kind, fetchPage)
597600
if err != nil {
598601
return nil, err
599602
}
600-
return marshalToResponse(&sdk.ListToolsResult{Tools: tools})
603+
return marshalToResponse(buildResult(items))
604+
}
605+
606+
func (c *Connection) listTools() (*Response, error) {
607+
return listMCPItems(c, "tools",
608+
func(cursor string) (paginatedPage[*sdk.Tool], error) {
609+
result, err := c.getSDKSession().ListTools(c.ctx, &sdk.ListToolsParams{Cursor: cursor})
610+
if err != nil {
611+
return paginatedPage[*sdk.Tool]{}, err
612+
}
613+
return paginatedPage[*sdk.Tool]{Items: result.Tools, NextCursor: result.NextCursor}, nil
614+
},
615+
func(items []*sdk.Tool) *sdk.ListToolsResult {
616+
return &sdk.ListToolsResult{Tools: items}
617+
},
618+
)
601619
}
602620

603621
func (c *Connection) callTool(params interface{}) (*Response, error) {
@@ -616,21 +634,18 @@ func (c *Connection) callTool(params interface{}) (*Response, error) {
616634
}
617635

618636
func (c *Connection) listResources() (*Response, error) {
619-
if err := c.requireSession(); err != nil {
620-
return nil, err
621-
}
622-
logConn.Printf("listResources: requesting resource list from backend serverID=%s", c.serverID)
623-
resources, err := paginateAll(c.serverID, "resources", func(cursor string) (paginatedPage[*sdk.Resource], error) {
624-
result, err := c.getSDKSession().ListResources(c.ctx, &sdk.ListResourcesParams{Cursor: cursor})
625-
if err != nil {
626-
return paginatedPage[*sdk.Resource]{}, err
627-
}
628-
return paginatedPage[*sdk.Resource]{Items: result.Resources, NextCursor: result.NextCursor}, nil
629-
})
630-
if err != nil {
631-
return nil, err
632-
}
633-
return marshalToResponse(&sdk.ListResourcesResult{Resources: resources})
637+
return listMCPItems(c, "resources",
638+
func(cursor string) (paginatedPage[*sdk.Resource], error) {
639+
result, err := c.getSDKSession().ListResources(c.ctx, &sdk.ListResourcesParams{Cursor: cursor})
640+
if err != nil {
641+
return paginatedPage[*sdk.Resource]{}, err
642+
}
643+
return paginatedPage[*sdk.Resource]{Items: result.Resources, NextCursor: result.NextCursor}, nil
644+
},
645+
func(items []*sdk.Resource) *sdk.ListResourcesResult {
646+
return &sdk.ListResourcesResult{Resources: items}
647+
},
648+
)
634649
}
635650

636651
func (c *Connection) readResource(params interface{}) (*Response, error) {
@@ -646,21 +661,18 @@ func (c *Connection) readResource(params interface{}) (*Response, error) {
646661
}
647662

648663
func (c *Connection) listPrompts() (*Response, error) {
649-
if err := c.requireSession(); err != nil {
650-
return nil, err
651-
}
652-
logConn.Printf("listPrompts: requesting prompt list from backend serverID=%s", c.serverID)
653-
prompts, err := paginateAll(c.serverID, "prompts", func(cursor string) (paginatedPage[*sdk.Prompt], error) {
654-
result, err := c.getSDKSession().ListPrompts(c.ctx, &sdk.ListPromptsParams{Cursor: cursor})
655-
if err != nil {
656-
return paginatedPage[*sdk.Prompt]{}, err
657-
}
658-
return paginatedPage[*sdk.Prompt]{Items: result.Prompts, NextCursor: result.NextCursor}, nil
659-
})
660-
if err != nil {
661-
return nil, err
662-
}
663-
return marshalToResponse(&sdk.ListPromptsResult{Prompts: prompts})
664+
return listMCPItems(c, "prompts",
665+
func(cursor string) (paginatedPage[*sdk.Prompt], error) {
666+
result, err := c.getSDKSession().ListPrompts(c.ctx, &sdk.ListPromptsParams{Cursor: cursor})
667+
if err != nil {
668+
return paginatedPage[*sdk.Prompt]{}, err
669+
}
670+
return paginatedPage[*sdk.Prompt]{Items: result.Prompts, NextCursor: result.NextCursor}, nil
671+
},
672+
func(items []*sdk.Prompt) *sdk.ListPromptsResult {
673+
return &sdk.ListPromptsResult{Prompts: items}
674+
},
675+
)
664676
}
665677

666678
func (c *Connection) getPrompt(params interface{}) (*Response, error) {

0 commit comments

Comments
 (0)