Skip to content

Conversation

@aluzzardi
Copy link
Member

@aluzzardi aluzzardi commented Jul 9, 2025

Experiment. Only converted EnvironmentCreateTool and EnvironmentFileListTool

Signed-off-by: Andrea Luzzardi <[email protected]>
@aluzzardi aluzzardi force-pushed the tools-refactoring branch from eadc258 to 282173e Compare July 9, 2025 20:39
Signed-off-by: Andrea Luzzardi <[email protected]>
Comment on lines +57 to +58
ActualHandler func(ctx context.Context, request *R) (*ToolResponse[V], error)
Handler server.ToolHandlerFunc
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ActualHandler func(ctx context.Context, request *R) (*ToolResponse[V], error)
Handler server.ToolHandlerFunc
Handler func(ctx context.Context, request *R) (*ToolResponse[V], error)
MCPHandler server.ToolHandlerFunc

DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test

DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

@dagger dagger deleted a comment from DaggerAssistant Aug 1, 2025
@dagger dagger deleted a comment from DaggerAssistant Aug 1, 2025
DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

Copy link
Member Author

@aluzzardi aluzzardi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test

Copy link
Member Author

@aluzzardi aluzzardi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test2

DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

DaggerAssistant

This comment was marked as outdated.

Copy link
Contributor

@DaggerAssistant DaggerAssistant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Code Review

Summary

This PR introduces a generic tool abstraction for the MCP server, refactoring EnvironmentCreateTool and EnvironmentFileListTool to use the new pattern. The changes include new request/response types, generic Tool struct, and helper functions for consistent argument parsing.

Assessment

⚠️ The refactoring is a good architectural improvement that will provide consistency and type safety. However, there are several critical issues that need to be addressed before merging: missing import statements that will cause compilation failures, variable shadowing issues, potential runtime panics from unsafe type assertions, and inconsistent error handling patterns. The typo in 'explainationArgument' should also be fixed. Once these issues are resolved, this provides a solid foundation for further tool migrations.

@@ -0,0 +1,107 @@
package mcpserver

import (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Bug (High): Missing import for 'fmt' package. The file uses fmt.Errorf and fmt.Sprintf functions but doesn't import the fmt package.

Suggested change
import (
import (
"context"
"fmt"
"dagger.io/dagger"
"github.com/dagger/container-use/environment"
"github.com/dagger/container-use/repository"
"github.com/mark3labs/mcp-go/mcp"
)

import "github.com/mark3labs/mcp-go/mcp"

var (
explainationArgument = mcp.WithString("explanation",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎨 Style (Low): Typo in variable name 'explainationArgument' should be 'explanationArgument'

Suggested change
explainationArgument = mcp.WithString("explanation",
explanationArgument = mcp.WithString("explanation",

func newRepositoryTool(name string, description string, args ...mcp.ToolOption) mcp.Tool {
opts := []mcp.ToolOption{
mcp.WithDescription(description),
explainationArgument,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎨 Style (Low): Reference to typo variable name should be corrected to 'explanationArgument'

Suggested change
explainationArgument,
explanationArgument,

func newEnvironmentTool(name string, description string, args ...mcp.ToolOption) mcp.Tool {
opts := []mcp.ToolOption{
mcp.WithDescription(description),
explainationArgument,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎨 Style (Low): Reference to typo variable name should be corrected to 'explanationArgument'

Suggested change
explainationArgument,
explanationArgument,

}

func parseBaseRequest(request mcp.CallToolRequest) (BaseRequest, error) {
explanation, err := request.RequireString("explanation")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Bug (Medium): The parseBaseRequest function tries to use RequireString for 'explanation' but based on the args.go file, explanation is not required. This should use GetString with a default value instead.

Suggested change
explanation, err := request.RequireString("explanation")
func parseBaseRequest(request mcp.CallToolRequest) (BaseRequest, error) {
explanation := request.GetString("explanation", "")
return BaseRequest{
Explanation: explanation,
}, nil
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performance (Low): Inefficient slice allocation and appending in a loop. Pre-allocate the slice with known capacity to avoid multiple allocations.

Suggested change
if portList, ok := request.GetArguments()["ports"].([]any); ok {
req.Ports = make([]int, len(portList))
for i, port := range portList {
req.Ports[i] = int(port.(float64))
}
}

if portList, ok := request.GetArguments()["ports"].([]any); ok {
for _, port := range portList {
req.Ports = append(req.Ports, int(port.(float64)))
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Bug (Medium): Potential panic from type assertion without checking. The type assertion port.(float64) could panic if the port value is not a float64.

Suggested change
}
for _, port := range portList {
if portFloat, ok := port.(float64); ok {
req.Ports = append(req.Ports, int(portFloat))
} else {
return nil, fmt.Errorf("invalid port type: expected number, got %T", port)
}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 Maintainability (Low): Missing return value in the ToolResponse. The Data field is not populated for non-background command execution, which could be inconsistent with the generic pattern.

Suggested change
return &ToolResponse[environment.EndpointMappings]{
Data: environment.EndpointMappings{}, // Empty mappings for non-background commands
Message: fmt.Sprintf("%s\n\nAny changes to the container workdir (%s) have been committed and pushed to container-use/ remote", stdout, env.Config.Workdir),
}, nil

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔧 Maintainability (Medium): EnvironmentOpenTool is using the old Tool struct definition (Tool[Request, Response]) but hasn't been converted to the new generic pattern like EnvironmentCreateTool and EnvironmentFileListTool. This creates inconsistency in the codebase.

Suggested change
// This tool should be converted to the new generic pattern like EnvironmentCreateTool
// Consider creating a specific request struct and migrating to the new pattern

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎨 Style (Low): Inconsistent indentation in multi-line string. The description should maintain consistent indentation.

Suggested change
`Creates a new development environment.
The environment is the result of a the setups commands on top of the base image.
Read carefully the instructions to understand the environment.
DO NOT manually install toolchains inside the environment, instead explicitly call environment_update`,

@aluzzardi
Copy link
Member Author

/cc @dagger

dagger[bot]

This comment was marked as outdated.

@aluzzardi
Copy link
Member Author

/cc @dagger

@aluzzardi
Copy link
Member Author

@dagger /review

dagger[bot]

This comment was marked as outdated.

@aluzzardi
Copy link
Member Author

@dagger /review

1 similar comment
@aluzzardi
Copy link
Member Author

@dagger /review

dagger[bot]

This comment was marked as outdated.

@aluzzardi
Copy link
Member Author

@dagger /review

dagger[bot]

This comment was marked as outdated.

@aluzzardi
Copy link
Member Author

@dagger /review

dagger[bot]

This comment was marked as outdated.

@aluzzardi
Copy link
Member Author

@dagger review

2 similar comments
@aluzzardi
Copy link
Member Author

@dagger review

@aluzzardi
Copy link
Member Author

@dagger review

dagger[bot]

This comment was marked as outdated.

@aluzzardi
Copy link
Member Author

@dagger review

dagger[bot]

This comment was marked as outdated.

@aluzzardi
Copy link
Member Author

@dagger review

dagger[bot]

This comment was marked as outdated.

@aluzzardi
Copy link
Member Author

@dagger keep the typos

dagger[bot]

This comment was marked as outdated.

@aluzzardi
Copy link
Member Author

@dagger you're wrong about the missing json import

dagger[bot]

This comment was marked as outdated.

@aluzzardi
Copy link
Member Author

@dagger please review

dagger[bot]

This comment was marked as outdated.

@aluzzardi
Copy link
Member Author

@dagger keep the typo

@aluzzardi
Copy link
Member Author

@dagger review

1 similar comment
@aluzzardi
Copy link
Member Author

@dagger review

dagger[bot]

This comment was marked as outdated.

@aluzzardi
Copy link
Member Author

Test

Copy link

@dagger dagger bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Code Review

Summary

This PR introduces a generic tool abstraction pattern for the MCP server, refactoring only two tools (EnvironmentCreateTool and EnvironmentFileListTool) to demonstrate the new architecture. The changes include creating type-safe request/response structures, separating concerns through different files (args.go, mcpserver.go), and introducing generic handler types.

Assessment

⚠️ This is a well-structured refactoring that introduces better type safety and separation of concerns. However, there are several issues that need attention:

Positives:

  • Good architectural direction: The generic Tool[R Request, V Response] pattern provides better type safety than the previous untyped approach
  • Better separation of concerns: Moving common argument definitions to args.go and shared utilities to mcpserver.go improves code organization
  • Improved error handling: Using fmt.Errorf with %w verb for proper error wrapping

Issues Found:

  1. Critical bug: Variable shadowing of json package import in tools.go:112
  2. Missing import: mcpserver.go uses fmt.Errorf but doesn't import fmt
  3. Typo: "explainationArgument" should be "explanationArgument" throughout
  4. Required field validation bug: Title field is marked as required but uses optional extraction

The refactoring pattern looks solid but needs these fixes before merging.

return mcp.NewToolResultError(err.Error()), nil
}

json, err := json.Marshal(response.Data)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Bug (High): Variable shadowing of json package import: The variable json on line 112 shadows the imported encoding/json package, which will cause compilation errors or unexpected behavior.

// Current problematic code:
json, err := json.Marshal(response.Data)  // 'json' shadows the package

This prevents access to the json.Marshal function and will likely cause a compilation error.

Suggested change
json, err := json.Marshal(response.Data)
data, err := json.Marshal(response.Data)
if err != nil {
return mcp.NewToolResultErrorFromErr("failed to marshal response", err), nil
}
body := string(data)

@@ -0,0 +1,107 @@
package mcpserver

import (
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Bug (High): Missing import for fmt package: The file uses fmt.Errorf in multiple error handling locations (lines where functions return formatted errors), but the fmt package is not imported.

For example, the code uses fmt.Errorf("unable to open the repository: %w", err) pattern in the refactored tools, but fmt is not available in this file's scope.

Suggested change
import (
import (
"context"
"fmt"
"dagger.io/dagger"
"github.com/dagger/container-use/environment"
"github.com/dagger/container-use/repository"
"github.com/mark3labs/mcp-go/mcp"
)

import "github.com/mark3labs/mcp-go/mcp"

var (
explainationArgument = mcp.WithString("explanation",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎨 Style (Medium): Typo in variable name: explainationArgument should be explanationArgument (missing 'n'). This typo is used consistently throughout the file on lines 6, 22, 33.

Suggested change
explainationArgument = mcp.WithString("explanation",
explanationArgument = mcp.WithString("explanation",
mcp.Description("One sentence explanation for why this directory is being listed."),
)

return mcp.NewToolResultErrorFromErr("dagger client not found in context", nil), nil
return &EnvironmentCreateToolRequest{
BaseRepositoryRequest: base,
Title: request.GetString("title", ""),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐛 Bug (Medium): Required field validation inconsistency: The title field is defined as mcp.Required() in the tool definition (line 262), but the ParseRequest function uses request.GetString("title", "") which returns an empty string if the field is missing, rather than request.RequireString("title") which would return an error.

This means required field validation is bypassed, potentially allowing empty titles when they should be mandatory.

Suggested change
Title: request.GetString("title", ""),
title, err := request.RequireString("title")
if err != nil {
return nil, err
}
return &EnvironmentCreateToolRequest{
BaseRepositoryRequest: base,
Title: title,
}, nil

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants