diff --git a/pkg/agent/mcp.go b/pkg/agent/mcp.go index be5aef13f..520532150 100644 --- a/pkg/agent/mcp.go +++ b/pkg/agent/mcp.go @@ -167,7 +167,7 @@ func (t *mcpTool) Execute(ctx context.Context, arguments string) (ToolResult, er } func extractMCPContent(result *mcp.CallToolResult) string { - if result == nil || len(result.Content) == 0 { + if result == nil { return "" } @@ -178,5 +178,16 @@ func extractMCPContent(result *mcp.CallToolResult) string { } } - return strings.Join(parts, "\n") + if len(parts) > 0 { + return strings.Join(parts, "\n") + } + + if result.StructuredContent != nil { + data, err := json.Marshal(result.StructuredContent) + if err == nil { + return string(data) + } + } + + return "" } diff --git a/pkg/agent/mcp_test.go b/pkg/agent/mcp_test.go index 86df974c6..dd231976e 100644 --- a/pkg/agent/mcp_test.go +++ b/pkg/agent/mcp_test.go @@ -379,4 +379,48 @@ func TestExtractMCPContent(t *testing.T) { assert.Equal(t, "", extractMCPContent(result)) }, ) + + t.Run( + "falls back to structured content when no text content", + func(t *testing.T) { + t.Parallel() + result := &mcp.CallToolResult{ + StructuredContent: map[string]any{ + "status": "ok", + "count": float64(42), + }, + } + got := extractMCPContent(result) + assert.Contains(t, got, `"status":"ok"`) + assert.Contains(t, got, `"count":42`) + }, + ) + + t.Run( + "text content takes precedence over structured content", + func(t *testing.T) { + t.Parallel() + result := &mcp.CallToolResult{ + Content: []mcp.Content{ + &mcp.TextContent{Text: "text wins"}, + }, + StructuredContent: map[string]any{"key": "value"}, + } + assert.Equal(t, "text wins", extractMCPContent(result)) + }, + ) + + t.Run( + "structured content used when content has only non-text", + func(t *testing.T) { + t.Parallel() + result := &mcp.CallToolResult{ + Content: []mcp.Content{ + &mcp.ImageContent{Data: []byte("img"), MIMEType: "image/png"}, + }, + StructuredContent: map[string]any{"fallback": true}, + } + assert.Equal(t, `{"fallback":true}`, extractMCPContent(result)) + }, + ) }