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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ Command line arguments:
```sh
Usage of ./aks-mcp:
--access-level string Access level (readonly, readwrite, admin) (default "readonly")
--additional-tools string Comma-separated list of additional Kubernetes tools to support (kubectl is always enabled). Available: helm,cilium
--additional-tools string Comma-separated list of additional Kubernetes tools to support (kubectl is always enabled). Available: helm,cilium,hubble
--allow-namespaces string Comma-separated list of allowed Kubernetes namespaces (empty means all namespaces)
--host string Host to listen for the server (only used with transport sse or streamable-http) (default "127.0.0.1")
--otlp-endpoint string OTLP endpoint for OpenTelemetry traces (e.g. localhost:4317, default "")
Expand Down
2 changes: 1 addition & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (cfg *ConfigData) ParseFlags() {

// Kubernetes-specific settings
additionalTools := flag.String("additional-tools", "",
"Comma-separated list of additional Kubernetes tools to support (kubectl is always enabled). Available: helm,cilium")
"Comma-separated list of additional Kubernetes tools to support (kubectl is always enabled). Available: helm,cilium,hubble")
flag.StringVar(&cfg.AllowNamespaces, "allow-namespaces", "",
"Comma-separated list of allowed Kubernetes namespaces (empty means all namespaces)")

Expand Down
6 changes: 6 additions & 0 deletions internal/config/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ func (v *Validator) validateCli() bool {
valid = false
}

// hubble is optional - only validate if explicitly enabled
if v.config.AdditionalTools["hubble"] && !v.isCliInstalled("hubble") {
v.errors = append(v.errors, "hubble is not installed or not found in PATH (required when --additional-tools includes hubble)")
valid = false
}

return valid
}

Expand Down
4 changes: 2 additions & 2 deletions internal/k8s/adapter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func TestConvertConfig_MapsFields(t *testing.T) {
Host: "127.0.0.1",
Port: 8000,
AccessLevel: "readonly",
AdditionalTools: map[string]bool{"helm": true, "cilium": false},
AdditionalTools: map[string]bool{"helm": true, "cilium": false, "hubble": false},
AllowNamespaces: "default,platform",
OTLPEndpoint: "otel:4317",
}
Expand Down Expand Up @@ -220,7 +220,7 @@ func BenchmarkConvertConfig(b *testing.B) {
Host: "127.0.0.1",
Port: 8000,
AccessLevel: "readonly",
AdditionalTools: map[string]bool{"helm": true, "cilium": false},
AdditionalTools: map[string]bool{"helm": true, "cilium": false, "hubble": false},
AllowNamespaces: "default,platform",
OTLPEndpoint: "otel:4317",
}
Expand Down
16 changes: 15 additions & 1 deletion internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/Azure/aks-mcp/internal/version"
"github.com/Azure/mcp-kubernetes/pkg/cilium"
"github.com/Azure/mcp-kubernetes/pkg/helm"
"github.com/Azure/mcp-kubernetes/pkg/hubble"
"github.com/Azure/mcp-kubernetes/pkg/kubectl"
k8stools "github.com/Azure/mcp-kubernetes/pkg/tools"
"github.com/mark3labs/mcp-go/server"
Expand Down Expand Up @@ -335,8 +336,11 @@ func (s *Service) registerOptionalKubernetesComponents() {
// Register cilium if enabled
s.registerCiliumComponent()

// Register hubble if enabled
s.registerHubbleComponent()

// Log if no optional components are enabled
if !s.cfg.AdditionalTools["helm"] && !s.cfg.AdditionalTools["cilium"] {
if !s.cfg.AdditionalTools["helm"] && !s.cfg.AdditionalTools["cilium"] && !s.cfg.AdditionalTools["hubble"] {
log.Println("No optional Kubernetes components enabled")
}
}
Expand Down Expand Up @@ -443,3 +447,13 @@ func (s *Service) registerCiliumComponent() {
s.mcpServer.AddTool(ciliumTool, tools.CreateToolHandler(ciliumExecutor, s.cfg))
}
}

// registerHubbleComponent registers hubble tools if enabled
func (s *Service) registerHubbleComponent() {
if s.cfg.AdditionalTools["hubble"] {
log.Println("Registering Kubernetes tool: hubble")
hubbleTool := hubble.RegisterHubble()
hubbleExecutor := k8s.WrapK8sExecutor(hubble.NewExecutor())
s.mcpServer.AddTool(hubbleTool, tools.CreateToolHandler(hubbleExecutor, s.cfg))
}
}
9 changes: 7 additions & 2 deletions internal/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (m *MockToolCounter) AddTool(toolName string) {

// Categorize tools
azureToolPrefixes := []string{"az_", "azure_", "get_aks_", "list_detectors", "run_detector", "inspektor_gadget_observability"}
k8sToolPrefixes := []string{"kubectl_", "k8s_", "helm", "cilium"}
k8sToolPrefixes := []string{"kubectl_", "k8s_", "helm", "cilium", "hubble"}

isAzureTool := false
for _, prefix := range azureToolPrefixes {
Expand Down Expand Up @@ -119,6 +119,7 @@ func TestService(t *testing.T) {
additionalTools: map[string]bool{
"helm": true,
"cilium": true,
"hubble": true,
},
expectedAzureTools: 8, // Same as readonly (Inspektor Gadget now included automatically)
expectedK8sTools: 0, // Will be calculated + 2 optional tools
Expand Down Expand Up @@ -146,6 +147,9 @@ func TestService(t *testing.T) {
if tt.additionalTools["cilium"] {
optionalToolsCount++
}
if tt.additionalTools["hubble"] {
optionalToolsCount++
}

expectedTotalK8sTools := expectedKubectlCount + optionalToolsCount

Expand Down Expand Up @@ -242,6 +246,7 @@ func TestComponentToolCounts(t *testing.T) {
t.Logf("Optional Kubernetes Components:")
t.Logf(" - Helm: 1 tool (when enabled)")
t.Logf(" - Cilium: 1 tool (when enabled)")
t.Logf(" - Hubble: 1 tool (when enabled)")
t.Logf("Note: Inspektor Gadget is now automatically enabled as part of Azure Components")
})

Expand Down Expand Up @@ -344,7 +349,7 @@ func TestExpectedToolsByAccessLevel(t *testing.T) {

t.Logf("Kubernetes Tools:")
t.Logf(" - Kubectl Tools: %d", k8sToolsCount)
t.Logf(" - Optional Tools: 0-2 (helm, cilium)")
t.Logf(" - Optional Tools: 0-3 (helm, cilium, hubble)")

t.Logf("kubectl tools for %s:", level)
for i, tool := range kubectlTools {
Expand Down
4 changes: 3 additions & 1 deletion prompts/aks-mcp-tool-consolidation.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The current AKS-MCP server registers approximately 40+ individual tools, which c
- kubectl commands
- helm (optional)
- cilium (optional)
- hubble (optional)

5. **Advisor Tools** (1 tool)
- Advisor recommendations
Expand Down Expand Up @@ -160,11 +161,12 @@ The current AKS-MCP server registers approximately 40+ individual tools, which c
- kubectl commands
- helm operations (if enabled)
- cilium operations (if enabled)
- hubble commands (if enabled)

**Parameters:**
```json
{
"tool": "kubectl|helm|cilium",
"tool": "kubectl|helm|cilium|hubble",
"command": "specific command",
"args": "command arguments"
}
Expand Down
Loading