# How MCP Server Kubernetes Implements Tool Filtering for Non-Destructive and Read-Only Modes

> Discover how MCP Server Kubernetes implements tool filtering for read-only and non-destructive modes using environment variables to secure operations and control access.

- Repository: [Suyog Sonwalkar/mcp-server-kubernetes](https://github.com/flux159/mcp-server-kubernetes)
- Tags: internals
- Published: 2026-03-02

---

**The MCP server filters available tools at runtime by checking three environment variables—`ALLOW_ONLY_READONLY_TOOLS`, `ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS`, and `ALLOWED_TOOLS`—to restrict the tool catalog to safe, read-only operations or specific whitelisted commands.**

The `flux159/mcp-server-kubernetes` repository implements a declarative security model that controls which Kubernetes management tools are exposed to clients. By evaluating environment-driven flags during the `ListTools` request handling, the server dynamically builds the available tool catalog to prevent accidental cluster modifications or to comply with strict operational policies.

## Environment Variables That Control Tool Access

The filtering mechanism relies on three mutually exclusive configuration options parsed in [`src/index.ts`](https://github.com/flux159/mcp-server-kubernetes/blob/main/src/index.ts) (lines 79–94). When multiple variables are set, the whitelist takes precedence, followed by the read-only flag, then the non-destructive flag.

### ALLOW_ONLY_READONLY_TOOLS

Setting `ALLOW_ONLY_READONLY_TOOLS="true"` restricts the server to **observability operations only**. The `readonlyTools` array (lines 85–94) includes schemas for `kubectl get`, `kubectl describe`, `kubectl logs`, `kubectl context`, `explainResource`, `listApiResources`, and `ping`. No mutating commands are exposed to the client.

### ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS

Setting `ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS="true"` enables a broader set of operations while explicitly **excluding destructive capabilities**. The server filters the full `allTools` catalog by removing any tool present in the `destructiveTools` array defined at lines 96–104. This removes `kubectlDeleteSchema`, `uninstallHelmChartSchema`, `cleanupSchema`, `kubectlGenericSchema`, and `nodeManagementSchema`, preventing resource deletion, Helm uninstalls, node drains, and generic destructive kubectl commands.

### ALLOWED_TOOLS Whitelist

The `ALLOWED_TOOLS` variable accepts a comma-separated list of tool names (e.g., `kubectlGet,kubectlDescribe`). When present, the server bypasses all other logic and returns **only** the schemas matching the specified names (lines 79–83). This provides explicit, granular control over the exposed surface area.

## Implementation Details in src/index.ts

The filtering logic executes during the `ListTools` request handler, constructing the response array based on the active environment configuration.

### The Filtering Logic Flow

At lines 106–147, the server first assembles the complete `allTools` array containing every available tool schema. It then applies the decision tree:

1. **Whitelist check**: If `ALLOWED_TOOLS` is defined, parse the comma-separated values and return only matching schemas.
2. **Read-only check**: If `ALLOW_ONLY_READONLY_TOOLS` equals `"true"`, return the predefined `readonlyTools` array.
3. **Non-destructive check**: If `ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS` equals `"true"`, filter `allTools` to exclude any tool present in `destructiveTools`.
4. **Default**: Return the unfiltered `allTools` array.

### Defining Destructive and Read-Only Tool Sets

The classification of tools is hardcoded in [`src/index.ts`](https://github.com/flux159/mcp-server-kubernetes/blob/main/src/index.ts) based on operational impact:

- **Read-only tools** (lines 85–94): Query operations that cannot modify cluster state.
- **Destructive tools** (lines 96–104): Operations that delete resources, uninstall Helm releases, drain nodes, or execute arbitrary destructive commands.

The test suite in [`tests/non_destructive_tools.test.ts`](https://github.com/flux159/mcp-server-kubernetes/blob/main/tests/non_destructive_tools.test.ts) (lines 11–70) validates this behavior, confirming that enabling `ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS` removes the destructive schemas from the response and that disabling it restores the full catalog.

## Practical Code Examples

### Enabling Read-Only Mode

To restrict the server to observability commands only, set the environment variable before starting the server:

```bash
export ALLOW_ONLY_READONLY_TOOLS="true"
npx mcp-server-kubernetes

```

When a client sends a `ListTools` request, the server returns only the `readonlyTools` subset:

```typescript
// Returned schemas include:
// - kubectlGetSchema
// - kubectlDescribeSchema  
// - kubectlLogsSchema
// - kubectlContextSchema
// - explainResourceSchema
// - listApiResourcesSchema
// - pingSchema

```

### Enabling Non-Destructive Mode

To allow resource creation and updates while blocking deletion operations:

```bash
export ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS="true"
npx mcp-server-kubernetes

```

The server filters the `allTools` array by excluding the `destructiveTools` set defined at lines 96–104 of [`src/index.ts`](https://github.com/flux159/mcp-server-kubernetes/blob/main/src/index.ts). This removes tools such as `kubectlDeleteSchema`, `uninstallHelmChartSchema`, and `nodeManagementSchema` from the available catalog.

### Using Tool Whitelisting

For granular control, specify exact tool names via the whitelist variable:

```bash
export ALLOWED_TOOLS="kubectlGet,kubectlDescribe,kubectlLogs"
npx mcp-server-kubernetes

```

This configuration bypasses both the read-only and non-destructive flags, returning only the three specified tool schemas regardless of their operational classification.

## Summary

- **Environment-driven filtering**: The server evaluates `ALLOW_ONLY_READONLY_TOOLS`, `ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS`, and `ALLOWED_TOOLS` at runtime to determine the exposed tool catalog.
- **Hierarchical precedence**: The whitelist (`ALLOWED_TOOLS`) overrides all other flags, followed by read-only mode, then non-destructive filtering.
- **Explicit classification**: Destructive tools are explicitly enumerated in [`src/index.ts`](https://github.com/flux159/mcp-server-kubernetes/blob/main/src/index.ts) (lines 96–104) and include deletion, Helm uninstall, node drain, and generic destructive kubectl operations.
- **Validation**: The test suite [`tests/non_destructive_tools.test.ts`](https://github.com/flux159/mcp-server-kubernetes/blob/main/tests/non_destructive_tools.test.ts) confirms that filtering correctly removes dangerous operations while preserving safe, observational commands.

## Frequently Asked Questions

### What is the difference between read-only and non-destructive modes?

**Read-only mode** (`ALLOW_ONLY_READONLY_TOOLS="true"`) exposes only observability tools such as `kubectl get`, `describe`, `logs`, and `context` that cannot modify cluster state. **Non-destructive mode** (`ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS="true"`) allows a broader range of operations including resource creation and updates, but explicitly filters out tools that delete resources, uninstall Helm charts, drain nodes, or execute arbitrary destructive commands.

### Can I combine multiple filtering flags?

While you can set multiple environment variables simultaneously, the server applies a strict precedence order: `ALLOWED_TOOLS` takes priority over all other settings, followed by `ALLOW_ONLY_READONLY_TOOLS`, and finally `ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS`. If you set both read-only and non-destructive flags without a whitelist, the read-only restriction will apply because it is evaluated first in the decision tree at lines 79–94 of [`src/index.ts`](https://github.com/flux159/mcp-server-kubernetes/blob/main/src/index.ts).

### How do I verify which tools are available after filtering?

Send a `ListTools` request to the server via your MCP client or inspect the response programmatically. The server returns only the JSON schemas for tools that pass the active filters. You can also check the server logs at startup to confirm which environment variables are active, or review the test file [`tests/non_destructive_tools.test.ts`](https://github.com/flux159/mcp-server-kubernetes/blob/main/tests/non_destructive_tools.test.ts) to see the expected tool sets for each configuration.

### Where are the destructive tools defined in the source code?

The destructive tool set is explicitly enumerated in [`src/index.ts`](https://github.com/flux159/mcp-server-kubernetes/blob/main/src/index.ts) at lines 96–104. This array includes `kubectlDeleteSchema`, `uninstallHelmChartSchema`, `cleanupSchema`, `kubectlGenericSchema`, and `nodeManagementSchema`. These schemas represent operations that remove resources, uninstall Helm releases, perform node maintenance, or execute arbitrary kubectl commands that could damage cluster state.