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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ bin/
*.html
/helm/kagent-tools/Chart.yaml
/reports/tools-cve.csv
.dagger/
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ DOCKER_BUILD_ARGS ?= --pull --load --platform linux/$(LOCALARCH) --builder $(BUI
# tools image build args
TOOLS_ISTIO_VERSION ?= 1.26.2
TOOLS_ARGO_ROLLOUTS_VERSION ?= 1.8.3
TOOLS_KUBECTL_VERSION ?= 1.33.2
TOOLS_KUBECTL_VERSION ?= 1.33.3
TOOLS_HELM_VERSION ?= 3.18.4
TOOLS_CILIUM_VERSION ?= 0.18.5

Expand Down
6 changes: 3 additions & 3 deletions internal/commands/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ func GetPods(namespace string, labels map[string]string) *CommandBuilder {
builder = builder.WithLabels(labels)
}

return builder.WithCache(true).WithOutput("json")
return builder.WithCache(true)
}

// GetServices creates a command to get services
Expand All @@ -460,7 +460,7 @@ func GetServices(namespace string, labels map[string]string) *CommandBuilder {
builder = builder.WithLabels(labels)
}

return builder.WithCache(true).WithOutput("json")
return builder.WithCache(true)
}

// GetDeployments creates a command to get deployments
Expand All @@ -475,7 +475,7 @@ func GetDeployments(namespace string, labels map[string]string) *CommandBuilder
builder = builder.WithLabels(labels)
}

return builder.WithCache(true).WithOutput("json")
return builder.WithCache(true)
}

// DescribeResource creates a command to describe a resource
Expand Down
6 changes: 3 additions & 3 deletions internal/commands/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ func TestGetPods(t *testing.T) {
assert.Equal(t, namespace, cb.namespace)
assert.Equal(t, labels, cb.labels)
assert.True(t, cb.cached)
assert.Equal(t, "json", cb.output)
assert.Empty(t, cb.output) // No default output format
}

func TestGetServices(t *testing.T) {
Expand All @@ -268,7 +268,7 @@ func TestGetServices(t *testing.T) {
assert.Equal(t, namespace, cb.namespace)
assert.Equal(t, labels, cb.labels)
assert.True(t, cb.cached)
assert.Equal(t, "json", cb.output)
assert.Empty(t, cb.output) // No default output format
}

func TestGetDeployments(t *testing.T) {
Expand All @@ -283,7 +283,7 @@ func TestGetDeployments(t *testing.T) {
assert.Equal(t, namespace, cb.namespace)
assert.Equal(t, labels, cb.labels)
assert.True(t, cb.cached)
assert.Equal(t, "json", cb.output)
assert.Empty(t, cb.output) // No default output format
}

func TestDescribeResource(t *testing.T) {
Expand Down
6 changes: 3 additions & 3 deletions pkg/k8s/k8s.go
Comment thread
dimetron marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (k *K8sTool) handleKubectlGetEnhanced(ctx context.Context, request mcp.Call
resourceName := mcp.ParseString(request, "resource_name", "")
namespace := mcp.ParseString(request, "namespace", "")
allNamespaces := mcp.ParseString(request, "all_namespaces", "") == "true"
output := mcp.ParseString(request, "output", "json")
output := mcp.ParseString(request, "output", "wide")

if resourceType == "" {
return mcp.NewToolResultError("resource_type parameter is required"), nil
Expand Down Expand Up @@ -292,7 +292,7 @@ func (k *K8sTool) handleExecCommand(ctx context.Context, request mcp.CallToolReq

// Get available API resources
func (k *K8sTool) handleGetAvailableAPIResources(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
return k.runKubectlCommand(ctx, "api-resources", "-o", "json")
return k.runKubectlCommand(ctx, "api-resources")
}

// Kubectl describe tool
Expand Down Expand Up @@ -567,7 +567,7 @@ func RegisterTools(s *server.MCPServer, llm llms.Model, kubeconfig string) {
mcp.WithString("resource_name", mcp.Description("Name of specific resource (optional)")),
mcp.WithString("namespace", mcp.Description("Namespace to query (optional)")),
mcp.WithString("all_namespaces", mcp.Description("Query all namespaces (true/false)")),
mcp.WithString("output", mcp.Description("Output format (json, yaml, wide, etc.)")),
mcp.WithString("output", mcp.Description("Output format (json, yaml, wide)"), mcp.DefaultString("wide")),
), telemetry.AdaptToolHandler(telemetry.WithTracing("k8s_get_resources", k8sTool.handleKubectlGetEnhanced)))

s.AddTool(mcp.NewTool("k8s_get_pod_logs",
Expand Down
12 changes: 7 additions & 5 deletions pkg/k8s/k8s_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ func TestHandleGetAvailableAPIResources(t *testing.T) {

t.Run("success", func(t *testing.T) {
mock := cmd.NewMockShellExecutor()
expectedOutput := `[{"name": "pods", "singularName": "pod", "namespaced": true, "kind": "Pod"}]`
mock.AddCommandString("kubectl", []string{"api-resources", "-o", "json"}, expectedOutput, nil)
expectedOutput := `NAME SHORTNAMES APIVERSION NAMESPACED KIND
pods po v1 true Pod
services svc v1 true Service`
mock.AddCommandString("kubectl", []string{"api-resources"}, expectedOutput, nil)
ctx := cmd.WithShellExecutor(ctx, mock)

k8sTool := newTestK8sTool()
Expand All @@ -56,7 +58,7 @@ func TestHandleGetAvailableAPIResources(t *testing.T) {

t.Run("kubectl command failure", func(t *testing.T) {
mock := cmd.NewMockShellExecutor()
mock.AddCommandString("kubectl", []string{"api-resources", "-o", "json"}, "", assert.AnError)
mock.AddCommandString("kubectl", []string{"api-resources"}, "", assert.AnError)
ctx := cmd.WithShellExecutor(ctx, mock)

k8sTool := newTestK8sTool()
Expand Down Expand Up @@ -408,8 +410,8 @@ func TestHandleKubectlGetEnhanced(t *testing.T) {

t.Run("valid resource_type", func(t *testing.T) {
mock := cmd.NewMockShellExecutor()
expectedOutput := `{"items": [{"metadata": {"name": "pod1"}}]}`
mock.AddCommandString("kubectl", []string{"get", "pods", "-o", "json"}, expectedOutput, nil)
expectedOutput := `NAME READY STATUS RESTARTS AGE`
mock.AddCommandString("kubectl", []string{"get", "pods", "-o", "wide"}, expectedOutput, nil)
ctx := cmd.WithShellExecutor(ctx, mock)

k8sTool := newTestK8sTool()
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ var _ = Describe("KAgent Tools E2E Tests", func() {
config := TestServerConfig{
Port: 8085,
Stdio: false,
Timeout: 30 * time.Second,
Timeout: 60 * time.Second,
}

server := NewTestServer(config)
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,8 @@ func InstallKAgentTools(namespace string, releaseName string) {

// GetMCPClient creates a new MCP client configured for the e2e test environment using the official mcp-go client
func GetMCPClient() (*MCPClient, error) {
// Create HTTP transport for the MCP server
httpTransport, err := transport.NewStreamableHTTP("http://127.0.0.1:30885/mcp", transport.WithHTTPTimeout(15*time.Second))
// Create HTTP transport for the MCP server with timeout long enough for operations like Istio installation
httpTransport, err := transport.NewStreamableHTTP("http://127.0.0.1:30885/mcp", transport.WithHTTPTimeout(180*time.Second))
if err != nil {
return nil, fmt.Errorf("failed to create HTTP transport: %w", err)
}
Expand Down