Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/mcp/tool_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func ConvertToCallToolResult(data interface{}) (*sdk.CallToolResult, error) {
// Returns the parsed arguments as a map, or an error if parsing fails.
func ParseToolArguments(req *sdk.CallToolRequest) (map[string]interface{}, error) {
var toolArgs map[string]interface{}
if req.Params.Arguments != nil {
if req.Params != nil && req.Params.Arguments != nil {
if err := json.Unmarshal(req.Params.Arguments, &toolArgs); err != nil {
return nil, fmt.Errorf("failed to parse arguments: %w", err)
}
Expand Down
42 changes: 33 additions & 9 deletions internal/mcp/tool_result_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func TestConvertToCallToolResult(t *testing.T) {

// TestParseToolArguments tests extraction and unmarshaling of tool arguments.
func TestParseToolArguments(t *testing.T) {
t.Run("nil arguments returns empty map", func(t *testing.T) {
t.Run("nil params returns empty map", func(t *testing.T) {
req := &sdk.CallToolRequest{}

args, err := ParseToolArguments(req)
Expand All @@ -151,6 +151,18 @@ func TestParseToolArguments(t *testing.T) {
assert.Empty(t, args)
})

t.Run("nil arguments returns empty map", func(t *testing.T) {
req := &sdk.CallToolRequest{
Params: &sdk.CallToolParamsRaw{},
}

args, err := ParseToolArguments(req)

require.NoError(t, err)
require.NotNil(t, args)
assert.Empty(t, args)
})

t.Run("valid json arguments are parsed correctly", func(t *testing.T) {
params := map[string]interface{}{
"query": "search term",
Expand All @@ -160,8 +172,11 @@ func TestParseToolArguments(t *testing.T) {
argsJSON, err := json.Marshal(params)
require.NoError(t, err)

req := &sdk.CallToolRequest{}
req.Params.Arguments = json.RawMessage(argsJSON)
req := &sdk.CallToolRequest{
Params: &sdk.CallToolParamsRaw{
Arguments: json.RawMessage(argsJSON),
},
}

args, err := ParseToolArguments(req)

Expand All @@ -175,8 +190,11 @@ func TestParseToolArguments(t *testing.T) {
t.Run("nested object arguments are parsed correctly", func(t *testing.T) {
argsJSON := `{"filter": {"type": "repo", "owner": "github"}, "page": 1}`

req := &sdk.CallToolRequest{}
req.Params.Arguments = json.RawMessage(argsJSON)
req := &sdk.CallToolRequest{
Params: &sdk.CallToolParamsRaw{
Arguments: json.RawMessage(argsJSON),
},
}

args, err := ParseToolArguments(req)

Expand All @@ -188,8 +206,11 @@ func TestParseToolArguments(t *testing.T) {
})

t.Run("invalid json returns error", func(t *testing.T) {
req := &sdk.CallToolRequest{}
req.Params.Arguments = json.RawMessage(`{not valid json}`)
req := &sdk.CallToolRequest{
Params: &sdk.CallToolParamsRaw{
Arguments: json.RawMessage(`{not valid json}`),
},
}

args, err := ParseToolArguments(req)

Expand All @@ -199,8 +220,11 @@ func TestParseToolArguments(t *testing.T) {
})

t.Run("empty json object returns empty map", func(t *testing.T) {
req := &sdk.CallToolRequest{}
req.Params.Arguments = json.RawMessage(`{}`)
req := &sdk.CallToolRequest{
Params: &sdk.CallToolParamsRaw{
Arguments: json.RawMessage(`{}`),
},
}

args, err := ParseToolArguments(req)

Expand Down
Loading