From 02314efbe0c906ef80cc387cd1263cfe308321d1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 12 Jan 2026 22:03:08 +0000 Subject: [PATCH 1/2] Initial plan From 345584c9cab36dd4acd789f0b70d4853ad820596 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 12 Jan 2026 22:14:50 +0000 Subject: [PATCH 2/2] Rename NewServerToolWithRawContextHandler to NewServerTool - Renamed deprecated NewServerTool[In, Out] to NewServerToolWithDeps[In, Out] - Updated dynamic_tools.go to use NewServerToolWithDeps (for special case with DynamicToolDependencies) - Renamed NewServerToolWithRawContextHandler to NewServerTool - Updated all call sites in dependencies.go and registry_test.go - All tests pass, linter passes Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com> --- pkg/github/dependencies.go | 2 +- pkg/github/dynamic_tools.go | 5 ++--- pkg/inventory/registry_test.go | 4 ++-- pkg/inventory/server_tool.go | 13 +++++++------ 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pkg/github/dependencies.go b/pkg/github/dependencies.go index b41bf0b87..5658d6518 100644 --- a/pkg/github/dependencies.go +++ b/pkg/github/dependencies.go @@ -182,7 +182,7 @@ func NewToolFromHandler( requiredScopes []scopes.Scope, handler func(ctx context.Context, deps ToolDependencies, req *mcp.CallToolRequest) (*mcp.CallToolResult, error), ) inventory.ServerTool { - st := inventory.NewServerToolWithRawContextHandler(tool, toolset, func(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) { + st := inventory.NewServerTool(tool, toolset, func(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) { deps := MustDepsFromContext(ctx) return handler(ctx, deps, req) }) diff --git a/pkg/github/dynamic_tools.go b/pkg/github/dynamic_tools.go index 5c7d31d4e..422d8fc89 100644 --- a/pkg/github/dynamic_tools.go +++ b/pkg/github/dynamic_tools.go @@ -28,10 +28,9 @@ type DynamicToolDependencies struct { // NewDynamicTool creates a ServerTool with fully-typed DynamicToolDependencies. // Dynamic tools use a different dependency structure (DynamicToolDependencies) than regular -// tools (ToolDependencies), so they intentionally use the closure pattern. +// tools (ToolDependencies), so they use NewServerToolWithDeps which creates closures. func NewDynamicTool(toolset inventory.ToolsetMetadata, tool mcp.Tool, handler func(deps DynamicToolDependencies) mcp.ToolHandlerFor[map[string]any, any]) inventory.ServerTool { - //nolint:staticcheck // SA1019: Dynamic tools use a different deps structure, closure pattern is intentional - return inventory.NewServerTool(tool, toolset, func(d any) mcp.ToolHandlerFor[map[string]any, any] { + return inventory.NewServerToolWithDeps(tool, toolset, func(d any) mcp.ToolHandlerFor[map[string]any, any] { return handler(d.(DynamicToolDependencies)) }) } diff --git a/pkg/inventory/registry_test.go b/pkg/inventory/registry_test.go index cc0b89e31..c80dadbfd 100644 --- a/pkg/inventory/registry_test.go +++ b/pkg/inventory/registry_test.go @@ -28,7 +28,7 @@ func testToolsetMetadataWithDefault(id string, isDefault bool) ToolsetMetadata { // mockToolWithDefault creates a mock tool with a default toolset flag func mockToolWithDefault(name string, toolsetID string, readOnly bool, isDefault bool) ServerTool { - return NewServerToolWithRawContextHandler( + return NewServerTool( mcp.Tool{ Name: name, Annotations: &mcp.ToolAnnotations{ @@ -45,7 +45,7 @@ func mockToolWithDefault(name string, toolsetID string, readOnly bool, isDefault // mockTool creates a minimal ServerTool for testing func mockTool(name string, toolsetID string, readOnly bool) ServerTool { - return NewServerToolWithRawContextHandler( + return NewServerTool( mcp.Tool{ Name: name, Annotations: &mcp.ToolAnnotations{ diff --git a/pkg/inventory/server_tool.go b/pkg/inventory/server_tool.go index e94afc2b6..cfd319228 100644 --- a/pkg/inventory/server_tool.go +++ b/pkg/inventory/server_tool.go @@ -115,13 +115,14 @@ func (st *ServerTool) RegisterFunc(s *mcp.Server, deps any) { s.AddTool(&toolCopy, handler) } -// NewServerTool creates a ServerTool from a tool definition, toolset metadata, and a typed handler function. +// NewServerToolWithDeps creates a ServerTool from a tool definition, toolset metadata, and a typed handler function. // The handler function takes dependencies (as any) and returns a typed handler. // Callers should type-assert deps to their typed dependencies struct. // -// Deprecated: This creates closures at registration time. For better performance in -// per-request server scenarios, use NewServerToolWithContextHandler instead. -func NewServerTool[In any, Out any](tool mcp.Tool, toolset ToolsetMetadata, handlerFn func(deps any) mcp.ToolHandlerFor[In, Out]) ServerTool { +// This function creates closures at registration time and should only be used for special cases +// where the deps structure differs from the standard ToolDependencies (e.g., dynamic tools). +// For regular tools, use NewServerToolWithContextHandler or NewServerTool instead. +func NewServerToolWithDeps[In any, Out any](tool mcp.Tool, toolset ToolsetMetadata, handlerFn func(deps any) mcp.ToolHandlerFor[In, Out]) ServerTool { return ServerTool{ Tool: tool, Toolset: toolset, @@ -163,13 +164,13 @@ func NewServerToolWithContextHandler[In any, Out any](tool mcp.Tool, toolset Too } } -// NewServerToolWithRawContextHandler creates a ServerTool with a raw handler that receives deps via context. +// NewServerTool creates a ServerTool with a raw handler that receives deps via context. // This is the preferred approach for tools that use mcp.ToolHandler directly because it doesn't // create closures at registration time. // // The handler function is stored directly without wrapping in a deps closure. // Dependencies should be injected into context before calling tool handlers. -func NewServerToolWithRawContextHandler(tool mcp.Tool, toolset ToolsetMetadata, handler mcp.ToolHandler) ServerTool { +func NewServerTool(tool mcp.Tool, toolset ToolsetMetadata, handler mcp.ToolHandler) ServerTool { return ServerTool{ Tool: tool, Toolset: toolset,