diff --git a/coderd/mcp/mcp.go b/coderd/mcp/mcp.go index 84cbfdda2cd9f..f17ab5ae7cd93 100644 --- a/coderd/mcp/mcp.go +++ b/coderd/mcp/mcp.go @@ -79,11 +79,15 @@ func (s *Server) RegisterTools(client *codersdk.Client) error { return xerrors.Errorf("failed to initialize tool dependencies: %w", err) } - // Register all available tools + // Register all available tools, but exclude tools that require dependencies not available in the + // remote MCP context for _, tool := range toolsdk.All { + if tool.Name == toolsdk.ToolNameReportTask { + continue + } + s.mcpServer.AddTools(mcpFromSDK(tool, toolDeps)) } - return nil } diff --git a/codersdk/toolsdk/toolsdk.go b/codersdk/toolsdk/toolsdk.go index 670b5af145786..862d0c34a5316 100644 --- a/codersdk/toolsdk/toolsdk.go +++ b/codersdk/toolsdk/toolsdk.go @@ -253,6 +253,10 @@ ONLY report an "idle" or "failure" state if you have FULLY completed the task. if len(args.Summary) > 160 { return codersdk.Response{}, xerrors.New("summary must be less than 160 characters") } + // Check if task reporting is available to prevent nil pointer dereference + if deps.report == nil { + return codersdk.Response{}, xerrors.New("task reporting not available. Please ensure a task reporter is configured.") + } err := deps.report(args) if err != nil { return codersdk.Response{}, err diff --git a/codersdk/toolsdk/toolsdk_test.go b/codersdk/toolsdk/toolsdk_test.go index 5e4a33ba67575..c201190bd3456 100644 --- a/codersdk/toolsdk/toolsdk_test.go +++ b/codersdk/toolsdk/toolsdk_test.go @@ -686,3 +686,57 @@ func TestMain(m *testing.M) { os.Exit(code) } + +func TestReportTaskNilPointerDeref(t *testing.T) { + t.Parallel() + + // Create deps without a task reporter (simulating remote MCP server scenario) + client, _ := coderdtest.NewWithDatabase(t, nil) + deps, err := toolsdk.NewDeps(client) + require.NoError(t, err) + + // Prepare test arguments + args := toolsdk.ReportTaskArgs{ + Summary: "Test task", + Link: "https://example.com", + State: string(codersdk.WorkspaceAppStatusStateWorking), + } + + _, err = toolsdk.ReportTask.Handler(t.Context(), deps, args) + + // We expect an error, not a panic + require.Error(t, err) + require.Contains(t, err.Error(), "task reporting not available") +} + +func TestReportTaskWithReporter(t *testing.T) { + t.Parallel() + + // Create deps with a task reporter + client, _ := coderdtest.NewWithDatabase(t, nil) + + called := false + reporter := func(args toolsdk.ReportTaskArgs) error { + called = true + require.Equal(t, "Test task", args.Summary) + require.Equal(t, "https://example.com", args.Link) + require.Equal(t, string(codersdk.WorkspaceAppStatusStateWorking), args.State) + return nil + } + + deps, err := toolsdk.NewDeps(client, toolsdk.WithTaskReporter(reporter)) + require.NoError(t, err) + + args := toolsdk.ReportTaskArgs{ + Summary: "Test task", + Link: "https://example.com", + State: string(codersdk.WorkspaceAppStatusStateWorking), + } + + result, err := toolsdk.ReportTask.Handler(t.Context(), deps, args) + require.NoError(t, err) + require.True(t, called) + + // Verify response + require.Equal(t, "Thanks for reporting!", result.Message) +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy