Skip to content
Open
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
134 changes: 67 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,10 @@ The following sets of tools are available (toolsets marked with ✓ in the Defau

| Toolset | Description | Default |
|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|
| kiali | Most common tools for managing Kiali, check the [Kiali documentation](https://github.com/containers/kubernetes-mcp-server/blob/main/docs/KIALI.md) for more details. | |
| config | View and manage the current local Kubernetes configuration (kubeconfig) | ✓ |
| core | Most common tools for Kubernetes management (Pods, Generic Resources, Events, etc.) | ✓ |
| kcp | Manage kcp workspaces and multi-tenancy features | |
| kiali | Most common tools for managing Kiali, check the [Kiali documentation](https://github.com/containers/kubernetes-mcp-server/blob/main/docs/KIALI.md) for more details. | |
| kubevirt | KubeVirt virtual machine management tools | |
| helm | Tools for managing Helm charts and releases | ✓ |

Expand All @@ -328,6 +328,72 @@ In case multi-cluster support is enabled (default) and you have access to multip

<details>

<summary>kiali</summary>

- **kiali_mesh_graph** - Returns the topology of a specific namespaces, health, status of the mesh and namespaces. Includes a mesh health summary overview with aggregated counts of healthy, degraded, and failing apps, workloads, and services. Use this for high-level overviews
- `graphType` (`string`) - Optional type of graph to return: 'versionedApp', 'app', 'service', 'workload', 'mesh'
- `namespace` (`string`) - Optional single namespace to include in the graph (alternative to namespaces)
- `namespaces` (`string`) - Optional comma-separated list of namespaces to include in the graph
- `rateInterval` (`string`) - Optional rate interval for fetching (e.g., '10m', '5m', '1h').

- **kiali_manage_istio_config_read** - Lists or gets Istio configuration objects (Gateways, VirtualServices, etc.)
- `action` (`string`) **(required)** - Action to perform: list or get
- `group` (`string`) - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io')
- `kind` (`string`) - Kind of the Istio object (e.g., 'DestinationRule', 'VirtualService', 'HTTPRoute', 'Gateway')
- `name` (`string`) - Name of the Istio object
- `namespace` (`string`) - Namespace containing the Istio object
- `version` (`string`) - API version of the Istio object (e.g., 'v1', 'v1beta1')

- **kiali_manage_istio_config** - Creates, patches, or deletes Istio configuration objects (Gateways, VirtualServices, etc.)
- `action` (`string`) **(required)** - Action to perform: create, patch, or delete
- `group` (`string`) - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io')
- `json_data` (`string`) - JSON data to apply or create the object
- `kind` (`string`) - Kind of the Istio object (e.g., 'DestinationRule', 'VirtualService', 'HTTPRoute', 'Gateway')
- `name` (`string`) - Name of the Istio object
- `namespace` (`string`) - Namespace containing the Istio object
- `version` (`string`) - API version of the Istio object (e.g., 'v1', 'v1beta1')

- **kiali_get_resource_details** - Gets lists or detailed info for Kubernetes resources (services, workloads) within the mesh
- `namespaces` (`string`) - Comma-separated list of namespaces to get services from (e.g. 'bookinfo' or 'bookinfo,default'). If not provided, will list services from all accessible namespaces
- `resource_name` (`string`) - Name of the resource to get details for (optional string - if provided, gets details; if empty, lists all).
- `resource_type` (`string`) - Type of resource to get details for (service, workload)

- **kiali_get_metrics** - Gets lists or detailed info for Kubernetes resources (services, workloads) within the mesh
- `byLabels` (`string`) - Comma-separated list of labels to group metrics by (e.g., 'source_workload,destination_service'). Optional
- `direction` (`string`) - Traffic direction: 'inbound' or 'outbound'. Optional, defaults to 'outbound'
- `duration` (`string`) - Time range to get metrics for (optional string - if provided, gets metrics (e.g., '1m', '5m', '1h'); if empty, get default 30m).
- `namespace` (`string`) **(required)** - Namespace to get resources from
- `quantiles` (`string`) - Comma-separated list of quantiles for histogram metrics (e.g., '0.5,0.95,0.99'). Optional
- `rateInterval` (`string`) - Rate interval for metrics (e.g., '1m', '5m'). Optional, defaults to '10m'
- `reporter` (`string`) - Metrics reporter: 'source', 'destination', or 'both'. Optional, defaults to 'source'
- `requestProtocol` (`string`) - Filter by request protocol (e.g., 'http', 'grpc', 'tcp'). Optional
- `resource_name` (`string`) **(required)** - Name of the resource to get details for (optional string - if provided, gets details; if empty, lists all).
- `resource_type` (`string`) **(required)** - Type of resource to get details for (service, workload)
- `step` (`string`) - Step between data points in seconds (e.g., '15'). Optional, defaults to 15 seconds

- **kiali_workload_logs** - Get logs for a specific workload's pods in a namespace. Only requires namespace and workload name - automatically discovers pods and containers. Optionally filter by container name, time range, and other parameters. Container is auto-detected if not specified.
- `container` (`string`) - Optional container name to filter logs. If not provided, automatically detects and uses the main application container (excludes istio-proxy and istio-init)
- `namespace` (`string`) **(required)** - Namespace containing the workload
- `since` (`string`) - Time duration to fetch logs from (e.g., '5m', '1h', '30s'). If not provided, returns recent logs
- `tail` (`integer`) - Number of lines to retrieve from the end of logs (default: 100)
- `workload` (`string`) **(required)** - Name of the workload to get logs for

- **kiali_get_traces** - Gets traces for a specific resource (app, service, workload) in a namespace, or gets detailed information for a specific trace by its ID. If traceId is provided, it returns detailed trace information and other parameters are not required.
- `clusterName` (`string`) - Cluster name for multi-cluster environments (optional, only used when traceId is not provided)
- `endMicros` (`string`) - End time for traces in microseconds since epoch (optional, defaults to 10 minutes after startMicros if not provided, only used when traceId is not provided)
- `limit` (`integer`) - Maximum number of traces to return (default: 100, only used when traceId is not provided)
- `minDuration` (`integer`) - Minimum trace duration in microseconds (optional, only used when traceId is not provided)
- `namespace` (`string`) - Namespace to get resources from. Required if traceId is not provided.
- `resource_name` (`string`) - Name of the resource to get traces for. Required if traceId is not provided.
- `resource_type` (`string`) - Type of resource to get traces for (app, service, workload). Required if traceId is not provided.
- `startMicros` (`string`) - Start time for traces in microseconds since epoch (optional, defaults to 10 minutes before current time if not provided, only used when traceId is not provided)
- `tags` (`string`) - JSON string of tags to filter traces (optional, only used when traceId is not provided)
- `traceId` (`string`) - Unique identifier of the trace to retrieve detailed information for. If provided, this will return detailed trace information and other parameters (resource_type, namespace, resource_name) are not required.

</details>

<details>

<summary>config</summary>

- **configuration_contexts_list** - List all available context names and associated server urls from the kubeconfig file
Expand Down Expand Up @@ -453,72 +519,6 @@ In case multi-cluster support is enabled (default) and you have access to multip

<details>

<summary>kiali</summary>

- **kiali_mesh_graph** - Returns the topology of a specific namespaces, health, status of the mesh and namespaces. Includes a mesh health summary overview with aggregated counts of healthy, degraded, and failing apps, workloads, and services. Use this for high-level overviews
- `graphType` (`string`) - Optional type of graph to return: 'versionedApp', 'app', 'service', 'workload', 'mesh'
- `namespace` (`string`) - Optional single namespace to include in the graph (alternative to namespaces)
- `namespaces` (`string`) - Optional comma-separated list of namespaces to include in the graph
- `rateInterval` (`string`) - Optional rate interval for fetching (e.g., '10m', '5m', '1h').

- **kiali_manage_istio_config_read** - Lists or gets Istio configuration objects (Gateways, VirtualServices, etc.)
- `action` (`string`) **(required)** - Action to perform: list or get
- `group` (`string`) - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io')
- `kind` (`string`) - Kind of the Istio object (e.g., 'DestinationRule', 'VirtualService', 'HTTPRoute', 'Gateway')
- `name` (`string`) - Name of the Istio object
- `namespace` (`string`) - Namespace containing the Istio object
- `version` (`string`) - API version of the Istio object (e.g., 'v1', 'v1beta1')

- **kiali_manage_istio_config** - Creates, patches, or deletes Istio configuration objects (Gateways, VirtualServices, etc.)
- `action` (`string`) **(required)** - Action to perform: create, patch, or delete
- `group` (`string`) - API group of the Istio object (e.g., 'networking.istio.io', 'gateway.networking.k8s.io')
- `json_data` (`string`) - JSON data to apply or create the object
- `kind` (`string`) - Kind of the Istio object (e.g., 'DestinationRule', 'VirtualService', 'HTTPRoute', 'Gateway')
- `name` (`string`) - Name of the Istio object
- `namespace` (`string`) - Namespace containing the Istio object
- `version` (`string`) - API version of the Istio object (e.g., 'v1', 'v1beta1')

- **kiali_get_resource_details** - Gets lists or detailed info for Kubernetes resources (services, workloads) within the mesh
- `namespaces` (`string`) - Comma-separated list of namespaces to get services from (e.g. 'bookinfo' or 'bookinfo,default'). If not provided, will list services from all accessible namespaces
- `resource_name` (`string`) - Name of the resource to get details for (optional string - if provided, gets details; if empty, lists all).
- `resource_type` (`string`) - Type of resource to get details for (service, workload)

- **kiali_get_metrics** - Gets lists or detailed info for Kubernetes resources (services, workloads) within the mesh
- `byLabels` (`string`) - Comma-separated list of labels to group metrics by (e.g., 'source_workload,destination_service'). Optional
- `direction` (`string`) - Traffic direction: 'inbound' or 'outbound'. Optional, defaults to 'outbound'
- `duration` (`string`) - Time range to get metrics for (optional string - if provided, gets metrics (e.g., '1m', '5m', '1h'); if empty, get default 30m).
- `namespace` (`string`) **(required)** - Namespace to get resources from
- `quantiles` (`string`) - Comma-separated list of quantiles for histogram metrics (e.g., '0.5,0.95,0.99'). Optional
- `rateInterval` (`string`) - Rate interval for metrics (e.g., '1m', '5m'). Optional, defaults to '10m'
- `reporter` (`string`) - Metrics reporter: 'source', 'destination', or 'both'. Optional, defaults to 'source'
- `requestProtocol` (`string`) - Filter by request protocol (e.g., 'http', 'grpc', 'tcp'). Optional
- `resource_name` (`string`) **(required)** - Name of the resource to get details for (optional string - if provided, gets details; if empty, lists all).
- `resource_type` (`string`) **(required)** - Type of resource to get details for (service, workload)
- `step` (`string`) - Step between data points in seconds (e.g., '15'). Optional, defaults to 15 seconds

- **kiali_workload_logs** - Get logs for a specific workload's pods in a namespace. Only requires namespace and workload name - automatically discovers pods and containers. Optionally filter by container name, time range, and other parameters. Container is auto-detected if not specified.
- `container` (`string`) - Optional container name to filter logs. If not provided, automatically detects and uses the main application container (excludes istio-proxy and istio-init)
- `namespace` (`string`) **(required)** - Namespace containing the workload
- `since` (`string`) - Time duration to fetch logs from (e.g., '5m', '1h', '30s'). If not provided, returns recent logs
- `tail` (`integer`) - Number of lines to retrieve from the end of logs (default: 100)
- `workload` (`string`) **(required)** - Name of the workload to get logs for

- **kiali_get_traces** - Gets traces for a specific resource (app, service, workload) in a namespace, or gets detailed information for a specific trace by its ID. If traceId is provided, it returns detailed trace information and other parameters are not required.
- `clusterName` (`string`) - Cluster name for multi-cluster environments (optional, only used when traceId is not provided)
- `endMicros` (`string`) - End time for traces in microseconds since epoch (optional, defaults to 10 minutes after startMicros if not provided, only used when traceId is not provided)
- `limit` (`integer`) - Maximum number of traces to return (default: 100, only used when traceId is not provided)
- `minDuration` (`integer`) - Minimum trace duration in microseconds (optional, only used when traceId is not provided)
- `namespace` (`string`) - Namespace to get resources from. Required if traceId is not provided.
- `resource_name` (`string`) - Name of the resource to get traces for. Required if traceId is not provided.
- `resource_type` (`string`) - Type of resource to get traces for (app, service, workload). Required if traceId is not provided.
- `startMicros` (`string`) - Start time for traces in microseconds since epoch (optional, defaults to 10 minutes before current time if not provided, only used when traceId is not provided)
- `tags` (`string`) - JSON string of tags to filter traces (optional, only used when traceId is not provided)
- `traceId` (`string`) - Unique identifier of the trace to retrieve detailed information for. If provided, this will return detailed trace information and other parameters (resource_type, namespace, resource_name) are not required.

</details>

<details>

<summary>kubevirt</summary>

- **vm_create** - Create a VirtualMachine in the cluster with the specified configuration, automatically resolving instance types, preferences, and container disk images. VM will be created in Halted state by default; use autostart parameter to start it immediately.
Expand Down
120 changes: 120 additions & 0 deletions docs/VALIDATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Pre-Execution Validation

The kubernetes-mcp-server includes a validation layer that catches errors before they reach the Kubernetes API. This prevents AI hallucinations (like typos in resource names) and permission issues from causing confusing failures.

## Why Validation?

When an AI assistant makes a Kubernetes API call with errors, the raw Kubernetes error messages can be cryptic:

```
the server doesn't have a resource type "Deploymnt"
```

With validation enabled, you get clearer feedback:

```
Resource apps/v1/Deploymnt does not exist in the cluster
```

The validation layer catches these types of issues:

1. **Resource Existence** - Catches typos like "Deploymnt" instead of "Deployment" (checked in access control)
2. **Schema Validation** - Catches invalid fields like "spec.replcias" instead of "spec.replicas"
3. **RBAC Validation** - Pre-checks permissions before attempting operations

## Configuration

Validation is **disabled by default**. Schema and RBAC validators run together when enabled. Resource existence is always checked as part of access control.

```toml
# Enable all validation (default: false)
validation_enabled = true
```

### Configuration Reference

| TOML Field | Default | Description |
|------------|---------|-------------|
| `validation_enabled` | `false` | Enable/disable all validators |

**Note:** The schema validator caches the OpenAPI schema for 15 minutes internally.

## How It Works

### Validation Flow

Validation happens at the HTTP RoundTripper level, intercepting all Kubernetes API calls:

```
MCP Tool Call → Kubernetes Client → HTTP RoundTripper → Kubernetes API
Access Control
- Check deny list
- Check resource exists
Schema Validator (if enabled)
"Are the fields valid?"
RBAC Validator (if enabled)
"Does the user have permission?"
Forward to K8s API
```

This HTTP-layer approach ensures **all** Kubernetes API calls are validated, including those from plugins (KubeVirt, Kiali, Helm, etc.) - not just the core tools.

If any validator fails, the request is rejected with a clear error message before reaching the Kubernetes API.

### 1. Resource Existence (Access Control)

The access control layer validates that the requested resource type exists in the cluster. This check runs regardless of whether validation is enabled.

**What it catches:**
- Typos in Kind names: "Deploymnt" → should be "Deployment"
- Wrong API versions: "apps/v2" → should be "apps/v1"
- Non-existent custom resources

**Example error:**
```
RESOURCE_NOT_FOUND: Resource deployments.apps does not exist in the cluster
```

### 2. Schema Validation

Validates resource manifests against the cluster's OpenAPI schema for create/update operations.

**What it catches:**
- Invalid field names: "spec.replcias" → should be "spec.replicas"
- Wrong field types: string where integer expected
- Missing required fields

**Example error:**
```
INVALID_FIELD: unknown field "spec.replcias"
```

**Note:** Schema validation uses kubectl's validation library and caches the OpenAPI schema for 15 minutes.

### 3. RBAC Validation

Pre-checks permissions using Kubernetes `SelfSubjectAccessReview` before attempting operations.

**What it catches:**
- Missing permissions: can't create Deployments in namespace X
- Cluster-scoped vs namespace-scoped mismatches
- Read-only access attempting writes

**Example error:**
```
PERMISSION_DENIED: Cannot create deployments.apps in namespace "production"
```

**Note:** RBAC validation uses the same credentials as the actual operation - either the server's service account or the user's token (when OAuth is enabled).

## Error Codes

| Code | Description |
|------|-------------|
| `RESOURCE_NOT_FOUND` | The requested resource type doesn't exist in the cluster |
| `INVALID_FIELD` | A field in the manifest doesn't exist or has the wrong type |
| `PERMISSION_DENIED` | RBAC denies the requested operation |
Loading