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
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,15 @@ require explicit enablement via `--additional-tools`*
<details>
<summary>Real-time Observability</summary>

**Tool:** `inspektor_gadget` *(requires `--additional-tools inspektor-gadget`)*
**Tool:** `inspektor_gadget_observability`

Real-time observability tool for Azure Kubernetes Service (AKS) clusters using
eBPF.

**Available Actions:**

- `deploy`: Deploy Inspektor Gadget to cluster
- `undeploy`: Remove Inspektor Gadget from cluster
- `deploy`: Deploy Inspektor Gadget to cluster (requires `readwrite`/`admin` access)
- `undeploy`: Remove Inspektor Gadget from cluster (requires `readwrite`/`admin` access)
- `is_deployed`: Check deployment status
- `run`: Run one-shot gadgets
- `start`: Start continuous gadgets
Expand Down Expand Up @@ -407,7 +407,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,inspektor-gadget
--additional-tools string Comma-separated list of additional Kubernetes tools to support (kubectl is always enabled). Available: helm,cilium
--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")
--port int Port to listen for the server (only used with transport sse or streamable-http) (default 8000)
Expand Down
13 changes: 7 additions & 6 deletions docs/inspektor-gadget-usage.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Inspektor Gadget Tool Usage
# Inspektor Gadget Observability Tool Usage in AKS-MCP Server

This document gives an overview of `inspektor_gadget` tool in the AKS-MCP server.
This document gives an overview of `inspektor_gadget_observability` tool in the AKS-MCP server.

## Tool Overview

The [Inspektor Gadget](https://go.microsoft.com/fwlink/?linkid=2260072) tool allows users to run various diagnostics and inspections on Kubernetes clusters.
It uses gadgets to collect real-time data with Kubernetes enrichment. `inspektor_gadget` MCP tool essentially allows managing the gadgets, enabling users to
It uses gadgets to collect real-time data with Kubernetes enrichment. `inspektor_gadget_observability` MCP tool essentially allows managing the gadgets, enabling users to
run diagnostics, collect data, and analyze workloads in a Kubernetes environment. It currently supports the following actions:

- **start**: Start a gadget to collect data continuously
Expand Down Expand Up @@ -35,7 +35,7 @@ to get the most relevant data for your workload.

## Sample Prompts

Following are some sample prompts that can be used with to quickly try `inspektor_gadget` tool in the AKS-MCP server:
Following are some sample prompts that can be used with to quickly try `inspektor_gadget_observability` tool in the AKS-MCP server:

```
Can you check if any DNS queries are failing in AKS cluster?
Expand Down Expand Up @@ -68,12 +68,13 @@ Can you observe system calls for the pod my-pod in the default namespace for few
## Prerequisites

- A kubeconfig file that has access to the AKS cluster. You will need to restart the MCP server if you change the kubeconfig file.
- Ensure the AKS MCP server is running with the `--additional-tools=inspektor-gadget`.
- The tool requires Inspektor Gadget to be installed in the cluster. If you are running with `--additional-tools=inspektor-gadget` and `--access-level=readwrite` or more, the MCP server will automatically
- The tool requires Inspektor Gadget to be installed in the cluster. If you are running with `--access-level=readwrite` or more, the MCP server will automatically
install Inspektor Gadget (action `deploy` ) in the cluster otherwise you can follow the steps to install it manually: [Inspektor Gadget Installation](https://learn.microsoft.com/en-us/troubleshoot/azure/azure-kubernetes/logs/capture-system-insights-from-aks#how-to-install-inspektor-gadget-in-an-aks-cluster) or
use the official Helm chart: [Inspektor Gadget Helm Chart](https://inspektor-gadget.io/docs/latest/reference/install-kubernetes#installation-with-the-helm-chart):

```bash
IG_VERSION=$(curl -s https://api.github.com/repos/inspektor-gadget/inspektor-gadget/releases/latest | jq -r '.tag_name' | sed 's/^v//')
helm install gadget --namespace=gadget --create-namespace oci://ghcr.io/inspektor-gadget/inspektor-gadget/charts/gadget --version=$IG_VERSION
```

Once Inspektor Gadget is deployed (or you installed it manually), you only need `readonly` (default) access to use the `inspektor_gadget_observability` tool.
11 changes: 10 additions & 1 deletion internal/components/inspektorgadget/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ import (
// Inspektor Gadget Handler
// =============================================================================

var ErrNotDeployed = fmt.Errorf("inspektor gadget is not deployed, please deploy it first e.g. using 'inspektor_gadget' (action: deploy) tool (requires 'readwrite' or 'admin' access level)")
var (
defaultHelmCmd = fmt.Sprintf("helm install %s --namespace=%s --create-namespace %s --version=%s", inspektorGadgetChartRelease, inspektorGadgetChartNamespace, inspektorGadgetChartURL, getChartVersion())
defaultKubectlCmd = fmt.Sprintf("kubectl apply -f https://github.com/inspektor-gadget/inspektor-gadget/releases/download/v%s/inspektor-gadget-v%s.yaml", getChartVersion(), getChartVersion())
)

var ErrNotDeployed = fmt.Errorf("inspektor gadget is not deployed, please deploy it first using: 'inspektor_gadget_observability' tool (action: deploy) (requires 'readwrite' or 'admin' access level)\n"+
"or running either of the command manually:\n%s\nor\n%s", defaultHelmCmd, defaultKubectlCmd)

// InspektorGadgetHandler returns a handler to manage gadgets
func InspektorGadgetHandler(mgr GadgetManager, cfg *config.ConfigData) tools.ResourceHandler {
Expand Down Expand Up @@ -219,6 +225,9 @@ func handleLifecycleAction(deployed bool, action string, actionParams map[string
return "", fmt.Errorf("namespace %s is not allowed by security policy", inspektorGadgetChartNamespace)
}
if (cfg.AccessLevel != "readwrite" && cfg.AccessLevel != "admin") && (!slices.Contains(getReadonlyLifecycleActions(), action)) {
if action == deployAction {
return "", fmt.Errorf("action %q requires 'readwrite' or 'admin' access level, current access level is '%s'. %s", action, cfg.AccessLevel, ErrNotDeployed.Error())
}
return "", fmt.Errorf("action %q requires 'readwrite' or 'admin' access level, current access level is '%s'", action, cfg.AccessLevel)
}

Expand Down
4 changes: 2 additions & 2 deletions internal/components/inspektorgadget/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import "github.com/mark3labs/mcp-go/mcp"
// RegisterInspektorGadgetTool registers the inspektor-gadget tool to manage gadgets
func RegisterInspektorGadgetTool() mcp.Tool {
return mcp.NewTool(
"inspektor_gadget",
"inspektor_gadget_observability",
mcp.WithDescription("Real-time observability tool for Azure Kubernetes Service (AKS) clusters, allowing users to manage gadgets for monitoring and debugging"),
mcp.WithString("action",
mcp.Required(),
Expand Down Expand Up @@ -56,7 +56,7 @@ func RegisterInspektorGadgetTool() mcp.Tool {
map[string]any{
"namespace": map[string]any{
"type": "string",
"description": "Kubernetes namespace",
"description": "Kubernetes namespace, leave empty to use all namespaces",
},
"pod": map[string]any{
"type": "string",
Expand Down
4 changes: 2 additions & 2 deletions internal/components/inspektorgadget/registry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import "testing"

func TestRegisterInspektorGadgetTool(t *testing.T) {
tool := RegisterInspektorGadgetTool()
if tool.Name != "inspektor_gadget" {
t.Errorf("Expected tool name 'inspektor_gadget', got '%s'", tool.Name)
if tool.Name != "inspektor_gadget_observability" {
t.Errorf("Expected tool name 'inspektor_gadget_observability', got '%s'", tool.Name)
}

if tool.Description == "" {
Expand Down
4 changes: 2 additions & 2 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type ConfigData struct {
AccessLevel string

// Kubernetes-specific options
// Map of additional tools enabled (helm, cilium, inspektor-gadget)
// Map of additional tools enabled (helm, cilium)
AdditionalTools map[string]bool
// Comma-separated list of allowed Kubernetes namespaces
AllowNamespaces string
Expand Down Expand Up @@ -56,7 +56,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,inspektor-gadget")
"Comma-separated list of additional Kubernetes tools to support (kubectl is always enabled). Available: helm,cilium")
flag.StringVar(&cfg.AllowNamespaces, "allow-namespaces", "",
"Comma-separated list of allowed Kubernetes namespaces (empty means all namespaces)")

Expand Down
10 changes: 4 additions & 6 deletions internal/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ func (s *Service) Initialize() error {
// Register Kubernetes tools
s.registerKubernetesTools()

// Register Inspektor Gadget tools for observability
s.registerInspektorGadgetTools()

return nil
}

Expand Down Expand Up @@ -234,12 +237,6 @@ func (s *Service) registerKubernetesTools() {
ciliumExecutor := k8s.WrapK8sExecutor(cilium.NewExecutor())
s.mcpServer.AddTool(ciliumTool, tools.CreateToolHandler(ciliumExecutor, s.cfg))
}

// Register Inspektor Gadget tools for observability
if s.cfg.AdditionalTools["inspektor-gadget"] {
log.Println("Registering Kubernetes tool: inspektor-gadget")
s.registerInspektorGadgetTools()
}
}

// registerKubectlCommands registers kubectl commands based on access level
Expand Down Expand Up @@ -271,6 +268,7 @@ func (s *Service) registerInspektorGadgetTools() {
}

// Register Inspektor Gadget tool
log.Println("Registering Inspektor Gadget Observability tool: inspektor_gadget_observability")
inspektorGadget := inspektorgadget.RegisterInspektorGadgetTool()
s.mcpServer.AddTool(inspektorGadget, tools.CreateResourceHandler(inspektorgadget.InspektorGadgetHandler(gadgetMgr, s.cfg), s.cfg))
}
Loading