MKP is a Model Context Protocol (MCP) server for Kubernetes that allows LLM-powered applications to interact with Kubernetes clusters. It provides tools for listing and applying Kubernetes resources through the MCP protocol. - List resources supported by the Kubernetes API server - List clustered resources - List namespaced resources - Get resources and their subresources (including status, scale,
Add this skill
npx mdskills install StacklokLabs/mkpComprehensive MCP server for Kubernetes with excellent tool coverage and detailed documentation
1# MKP - Model Kontext Protocol Server for Kubernetes23<p align="center">4 <img src="docs/assets/mkp-logo.png" width="400" alt="MKP Logo">5</p>67MKP is a Model Context Protocol (MCP) server for Kubernetes that allows8LLM-powered applications to interact with Kubernetes clusters. It provides tools9for listing and applying Kubernetes resources through the MCP protocol.1011## Features1213- List resources supported by the Kubernetes API server14- List clustered resources15- List namespaced resources16- Get resources and their subresources (including status, scale, logs, etc.)17- Apply (create or update) clustered resources18- Apply (create or update) namespaced resources19- Execute commands in pods with timeout control20- Generic and pluggable implementation using API Machinery's unstructured client21- Built-in rate limiting for protection against excessive API calls2223## Why MKP?2425MKP offers several key advantages as a Model Context Protocol server for26Kubernetes:2728### Native Go Implementation2930- Built with the same language as Kubernetes itself31- Excellent performance characteristics for server applications32- Strong type safety and concurrency support33- Seamless integration with Kubernetes libraries3435### Direct API Integration3637- Uses Kubernetes API machinery directly without external dependencies38- No reliance on kubectl, helm, or other CLI tools39- Communicates directly with the Kubernetes API server40- Reduced overhead and improved reliability4142### Universal Resource Support4344- Works with any Kubernetes resource type through the unstructured client45- No hardcoded resource schemas or specialized handlers needed46- Automatically supports Custom Resource Definitions (CRDs)47- Future-proof for new Kubernetes resources4849### Minimalist Design5051- Focused on core Kubernetes resource operations52- Clean, maintainable codebase with clear separation of concerns53- Lightweight with minimal dependencies54- Easy to understand, extend, and contribute to5556### Production-Ready Architecture5758- Designed for reliability and performance in production environments59- Proper error handling and resource management60- Built-in rate limiting to protect against excessive API calls61- Testable design with comprehensive unit tests62- Follows Kubernetes development best practices6364## Prerequisites6566- Go 1.24 or later67- Kubernetes cluster and kubeconfig68- [Task](https://taskfile.dev/) for running tasks6970## Installation71721. Clone the repository:7374 ```bash75 git clone https://github.com/StacklokLabs/mkp.git76 cd mkp77 ```78792. Install dependencies:8081 ```bash82 task install83 ```84853. Build the server:8687 ```bash88 task build89 ```9091## Usage9293### Running the server9495To run the server with the default kubeconfig:9697```bash98task run99```100101To run the server with a specific kubeconfig:102103```bash104KUBECONFIG=/path/to/kubeconfig task run-with-kubeconfig105```106107To run the server on a specific port:108109```bash110MCP_PORT=9091 task run111```112113## Running with ToolHive114115MKP can be run as a Model Context Protocol (MCP) server using116[ToolHive](https://github.com/stacklok/toolhive), which simplifies the117deployment and management of MCP servers.118119See the120[ToolHive documentation](https://docs.stacklok.com/toolhive/guides-mcp/k8s) for121detailed instructions on how to set up MKP with the ToolHive UI, CLI, or122Kubernetes operator.123124### MCP Tools125126The MKP server provides the following MCP tools:127128#### get_resource129130Get a Kubernetes resource or its subresource.131132Parameters:133134- `resource_type` (required): Type of resource to get (clustered or namespaced)135- `group`: API group (e.g., apps, networking.k8s.io)136- `version` (required): API version (e.g., v1, v1beta1)137- `resource` (required): Resource name (e.g., deployments, services)138- `namespace`: Namespace (required for namespaced resources)139- `name` (required): Name of the resource to get140- `subresource`: Subresource to get (e.g., status, scale, logs)141- `parameters`: Optional parameters for the request (see examples below)142143Example:144145```json146{147 "name": "get_resource",148 "arguments": {149 "resource_type": "namespaced",150 "group": "apps",151 "version": "v1",152 "resource": "deployments",153 "namespace": "default",154 "name": "nginx-deployment",155 "subresource": "status"156 }157}158```159160Example of getting logs from a specific container with parameters:161162```json163{164 "name": "get_resource",165 "arguments": {166 "resource_type": "namespaced",167 "group": "",168 "version": "v1",169 "resource": "pods",170 "namespace": "default",171 "name": "my-pod",172 "subresource": "logs",173 "parameters": {174 "container": "my-container",175 "sinceSeconds": "3600",176 "timestamps": "true",177 "limitBytes": "102400"178 }179 }180}181```182183Available parameters for pod logs:184185- `container`: Specify which container to get logs from186- `previous`: Get logs from previous container instance (true/false)187- `sinceSeconds`: Only return logs newer than a relative duration in seconds188- `sinceTime`: Only return logs after a specific time (RFC3339 format)189- `timestamps`: Include timestamps on each line (true/false)190- `limitBytes`: Maximum number of bytes to return191- `tailLines`: Number of lines to return from the end of the logs192193By default, pod logs are limited to the last 100 lines and 32KB to avoid194overwhelming the LLM's context window. These defaults can be overridden using195the parameters above.196197Available parameters for regular resources:198199- `resourceVersion`: When specified, shows the resource at that particular200 version201202#### list_resources203204Lists Kubernetes resources of a specific type.205206Parameters:207208- `resource_type` (required): Type of resource to list (clustered or namespaced)209- `group`: API group (e.g., apps, networking.k8s.io)210- `version` (required): API version (e.g., v1, v1beta1)211- `resource` (required): Resource name (e.g., deployments, services)212- `namespace`: Namespace (required for namespaced resources)213- `label_selector`: Kubernetes label selector for filtering resources (optional)214- `include_annotations`: Whether to include annotations in the output (default:215 true)216- `exclude_annotation_keys`: List of annotation keys to exclude from output217 (supports wildcards with \*)218- `include_annotation_keys`: List of annotation keys to include in output (if219 specified, only these are included)220221##### Annotation Filtering222223The `list_resources` tool provides powerful annotation filtering capabilities to224control metadata output size and prevent truncation issues with large225annotations (such as GPU node annotations).226227**Basic Usage:**228229```json230{231 "name": "list_resources",232 "arguments": {233 "resource_type": "namespaced",234 "group": "apps",235 "version": "v1",236 "resource": "deployments",237 "namespace": "default"238 }239}240```241242**Exclude specific annotations (useful for GPU nodes):**243244```json245{246 "name": "list_resources",247 "arguments": {248 "resource_type": "clustered",249 "group": "",250 "version": "v1",251 "resource": "nodes",252 "exclude_annotation_keys": [253 "nvidia.com/*",254 "kubectl.kubernetes.io/last-applied-configuration"255 ]256 }257}258```259260**Include only specific annotations:**261262```json263{264 "name": "list_resources",265 "arguments": {266 "resource_type": "namespaced",267 "group": "",268 "version": "v1",269 "resource": "pods",270 "namespace": "default",271 "include_annotation_keys": ["app", "version", "prometheus.io/scrape"]272 }273}274```275276**Disable annotations completely for maximum performance:**277278```json279{280 "name": "list_resources",281 "arguments": {282 "resource_type": "namespaced",283 "group": "",284 "version": "v1",285 "resource": "pods",286 "namespace": "default",287 "include_annotations": false288 }289}290```291292**Annotation Filtering Rules:**293294- By default, `kubectl.kubernetes.io/last-applied-configuration` is excluded to295 prevent large configuration data296- `exclude_annotation_keys` supports wildcard patterns using `*` (e.g.,297 `nvidia.com/*` excludes all NVIDIA annotations)298- When `include_annotation_keys` is specified, it takes precedence and only299 those annotations are included300- Setting `include_annotations: false` completely removes all annotations from301 the output302- Wildcard patterns only support `*` at the end of the key (e.g.,303 `nvidia.com/*`)304305#### apply_resource306307Applies (creates or updates) a Kubernetes resource.308309Parameters:310311- `resource_type` (required): Type of resource to apply (clustered or312 namespaced)313- `group`: API group (e.g., apps, networking.k8s.io)314- `version` (required): API version (e.g., v1, v1beta1)315- `resource` (required): Resource name (e.g., deployments, services)316- `namespace`: Namespace (required for namespaced resources)317- `manifest` (required): Resource manifest318319Example:320321```json322{323 "name": "apply_resource",324 "arguments": {325 "resource_type": "namespaced",326 "group": "apps",327 "version": "v1",328 "resource": "deployments",329 "namespace": "default",330 "manifest": {331 "apiVersion": "apps/v1",332 "kind": "Deployment",333 "metadata": {334 "name": "nginx-deployment",335 "namespace": "default"336 },337 "spec": {338 "replicas": 3,339 "selector": {340 "matchLabels": {341 "app": "nginx"342 }343 },344 "template": {345 "metadata": {346 "labels": {347 "app": "nginx"348 }349 },350 "spec": {351 "containers": [352 {353 "name": "nginx",354 "image": "nginx:latest",355 "ports": [356 {357 "containerPort": 80358 }359 ]360 }361 ]362 }363 }364 }365 }366 }367}368```369370#### post_resource371372Posts to a Kubernetes resource or its subresource, particularly useful for373executing commands in pods.374375Parameters:376377- `resource_type` (required): Type of resource to post to (clustered or378 namespaced)379- `group`: API group (e.g., apps, networking.k8s.io)380- `version` (required): API version (e.g., v1, v1beta1)381- `resource` (required): Resource name (e.g., deployments, services)382- `namespace`: Namespace (required for namespaced resources)383- `name` (required): Name of the resource to post to384- `subresource`: Subresource to post to (e.g., exec)385- `body` (required): Body to post to the resource386- `parameters`: Optional parameters for the request387388Example of executing a command in a pod:389390```json391{392 "name": "post_resource",393 "arguments": {394 "resource_type": "namespaced",395 "group": "",396 "version": "v1",397 "resource": "pods",398 "namespace": "default",399 "name": "my-pod",400 "subresource": "exec",401 "body": {402 "command": ["ls", "-la", "/"],403 "container": "my-container",404 "timeout": 30405 }406 }407}408```409410The `body` for pod exec supports the following fields:411412- `command` (required): Command to execute, either as a string or an array of413 strings414- `container` (optional): Container name to execute the command in (defaults to415 the first container)416- `timeout` (optional): Timeout in seconds (defaults to 15 seconds, maximum 60417 seconds)418419Note on timeouts:420421- Default timeout: 15 seconds if not specified422- Maximum timeout: 60 seconds (any larger value will be capped)423- Commands that exceed the timeout will be terminated and return a timeout error424425The response includes stdout, stderr, and any error message:426427```json428{429 "apiVersion": "v1",430 "kind": "Pod",431 "metadata": {432 "name": "my-pod",433 "namespace": "default"434 },435 "spec": {436 "command": ["ls", "-la", "/"]437 },438 "status": {439 "stdout": "total 48\ndrwxr-xr-x 1 root root 4096 May 5 14:30 .\ndrwxr-xr-x 1 root root 4096 May 5 14:30 ..\n...",440 "stderr": "",441 "error": ""442 }443}444```445446### MCP Resources447448The MKP server provides access to Kubernetes resources through MCP resources.449The resource URIs follow these formats:450451- Clustered resources: `k8s://clustered/{group}/{version}/{resource}/{name}`452- Namespaced resources:453 `k8s://namespaced/{namespace}/{group}/{version}/{resource}/{name}`454455### Configuration456457#### Transport Protocol458459MKP supports two transport protocols for the MCP server:460461- **Streamable HTTP**: The default transport protocol, suitable for most use cases462- **SSE (Server-Sent Events)**: Legacy transport protocol, primarily for compatibility with older clients463464You can configure the transport protocol using either a CLI flag or an465environment variable:466467```bash468# Using CLI flag469./build/mkp-server --transport=sse470471# Using environment variable472MCP_TRANSPORT=sse ./build/mkp-server473474# Default (Streamable HTTP)475./build/mkp-server476```477478The `MCP_TRANSPORT` environment variable is automatically set by ToolHive when479running MKP in that environment.480481#### Controlling Resource Discovery482483By default, MKP serves all Kubernetes resources as MCP resources, which provides484useful context for LLMs. However, in large clusters with many resources, this485can consume significant context space in the LLM.486487You can disable this behavior by using the `--serve-resources` flag:488489```bash490# Run without serving cluster resources491./build/mkp-server --serve-resources=false492493# Run with a specific kubeconfig without serving cluster resources494./build/mkp-server --kubeconfig=/path/to/kubeconfig --serve-resources=false495```496497Even with resource discovery disabled, the MCP tools (`get_resource`,498`list_resources`, `apply_resource`, `delete_resource`, and `post_resource`)499remain fully functional, allowing you to interact with your Kubernetes cluster.500501#### Enabling Write Operations502503By default, MKP operates in read-only mode, meaning it does not allow write504operations on the cluster, i.e. the `apply_resource`, `delete_resource`, and505`post_resource` tools will not be available. You can enable write operations by506using the `--read-write` flag:507508```bash509# Run with write operations enabled510./build/mkp-server --read-write=true511512# Run with a specific kubeconfig and write operations enabled513./build/mkp-server --kubeconfig=/path/to/kubeconfig --read-write=true514```515516### Rate Limiting517518MKP includes a built-in rate limiting mechanism to protect the server from519excessive API calls, which is particularly important when used with AI agents.520The rate limiter uses a token bucket algorithm and applies different limits521based on the operation type:522523- Read operations (list_resources, get_resource): 120 requests per minute524- Write operations (apply_resource, delete_resource): 30 requests per minute525- Default for other operations: 60 requests per minute526527Rate limits are applied per client session, ensuring fair resource allocation528across multiple clients. The rate limiting feature can be enabled or disabled529via the command line flag:530531```bash532# Run with rate limiting enabled (default)533./build/mkp-server534535# Run with rate limiting disabled536./build/mkp-server --enable-rate-limiting=false537```538539Rate limits can be customized via environment variables:540541- `MKP_RATE_LIMIT_DEFAULT`: Default rate limit (default: 60)542- `MKP_RATE_LIMIT_READ`: Read operations rate limit (default: 120)543- `MKP_RATE_LIMIT_WRITE`: Write operations rate limit (default: 30)544545```bash546# Run with custom rate limits547MKP_RATE_LIMIT_READ=200 MKP_RATE_LIMIT_WRITE=50 ./build/mkp-server548```549550## Development551552### Running tests553554```bash555task test556```557558### Formatting code559560```bash561task fmt562```563564### Linting code565566```bash567task lint568```569570### Updating dependencies571572```bash573task deps574```575576## Contributing577578We welcome contributions to this MCP server! If you'd like to contribute, please579review the [CONTRIBUTING guide](./CONTRIBUTING.md) for details on how to get580started.581582If you run into a bug or have a feature request, please583[open an issue](https://github.com/StacklokLabs/mkp/issues) in the repository or584join us in the `#mcp-servers` channel on our585[community Discord server](https://discord.gg/stacklok).586587## License588589This project is licensed under the Apache v2 License - see the LICENSE file for590details.591
Full transparency — inspect the skill content before installing.