subm-mcp-server

vthapar/subm-mcp-server

3.1

If you are the rightful owner of subm-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

A Model Context Protocol (MCP) server for managing multiple Kubernetes clusters.

Tools
5
Resources
0
Prompts
0

Kubernetes Multi-Cluster MCP Server

A Model Context Protocol (MCP) server for managing multiple Kubernetes clusters. This server provides generic operations for any Kubernetes resource type, plus specialized operations for ServiceExports across multiple configured clusters.

Features

  • Multi-cluster support with a single server instance
  • Generic Resource Operations: Get and List any Kubernetes resource (pods, deployments, services, CRDs, etc.)
    • Supports both namespaced and cluster-scoped resources
    • Works with any API version (v1, apps/v1, custom CRDs, etc.)
    • Label selector support for filtering
  • ServiceExports (multicluster.x-k8s.io/v1alpha1): Get, List, Create, Delete
    • Simplified creation with just name (manifest optional)
    • Full MCS API compatibility
  • Namespace Operations: List namespaces across clusters
  • Multiple transport modes:
    • Stdio: JSON-RPC 2.0 over stdin/stdout (default)
    • HTTP: RESTful HTTP server with JSON-RPC 2.0
  • Easy configuration via YAML file
  • CORS support for HTTP mode

Prerequisites

  • Go 1.21 or later
  • Access to one or more Kubernetes clusters
  • Valid kubeconfig files for each cluster

Installation

Build from source

git clone https://github.com/vthapar/subm-mcp-server.git
cd subm-mcp-server
make build

The binary will be created at bin/subm-mcp-server.

Install

make install

Configuration

Create a configuration file config.yaml:

clusters:
  - name: cluster1
    kubeconfig: /path/to/cluster1/kubeconfig
    context: cluster1-context  # optional

  - name: cluster2
    kubeconfig: /path/to/cluster2/kubeconfig
    context: cluster2-context  # optional

  - name: local
    kubeconfig: ~/.kube/config

# Server configuration (optional)
server:
  transport: stdio  # "stdio" or "http", defaults to "stdio"
  http:
    host: localhost  # defaults to "localhost"
    port: 8080       # defaults to 8080

See config.yaml.example for a complete example.

Usage

Running the server

Stdio Mode (Default)
# Using -config flag
./bin/subm-mcp-server -config config.yaml

# Using environment variable
export MCP_K8S_CONFIG=config.yaml
./bin/subm-mcp-server

# Override transport mode via command line
./bin/subm-mcp-server -config config.yaml -transport stdio

The server reads JSON-RPC 2.0 requests from stdin and writes responses to stdout.

HTTP Mode
# Using config file with HTTP transport
./bin/subm-mcp-server -config config.yaml

# Override via command line flags
./bin/subm-mcp-server -config config.yaml -transport http

# Custom host and port
./bin/subm-mcp-server -config config.yaml -transport http -http-host 0.0.0.0 -http-port 9000

The HTTP server exposes the following endpoints:

  • POST /mcp - MCP JSON-RPC 2.0 endpoint
  • GET /health - Health check endpoint

Available Tools

Cluster Management
  • list_clusters - List all configured clusters
  • list_namespaces - List all namespaces in a cluster
Generic Resource Operations
  • get_resource - Get any Kubernetes resource by API version and type
  • list_resources - List any Kubernetes resources by API version and type
ServiceExports (Specialized Operations)
  • get_serviceexport - Get a specific ServiceExport
  • list_serviceexports - List ServiceExports in a namespace
  • create_serviceexport - Create a new ServiceExport (simple name-based or full manifest)
  • delete_serviceexport - Delete a ServiceExport

Tool Details

Generic Resource Operations

The get_resource and list_resources tools work with any Kubernetes resource type:

Supported Resource Types:

  • Core resources: pods, services, configmaps, secrets, nodes, namespaces, etc. (use api_version: "v1")
  • Apps resources: deployments, statefulsets, daemonsets, replicasets (use api_version: "apps/v1")
  • Custom Resources: Any CRD installed in your cluster (e.g., api_version: "submariner.io/v1alpha1", resource: "submariners")

Parameters:

  • cluster (required): Name of the cluster from config
  • api_version (required): API version (e.g., "v1", "apps/v1", "submariner.io/v1alpha1")
  • resource (required): Resource type in plural form (e.g., "pods", "deployments", "submariners")
  • name (required for get_resource): Resource name
  • namespace (optional): Namespace (omit for cluster-scoped resources like nodes)
  • labels (optional for list_resources): Label selector for filtering

ServiceExport Operations

ServiceExports follow the Kubernetes Multi-Cluster Services API (MCS).

Simple Creation: Just provide a name - the server creates a minimal ServiceExport that declares the service should be exported.

Advanced Creation: Provide a full manifest to specify additional fields like exportedLabels or exportedAnnotations.

Example Requests

Stdio Mode Examples

These examples show raw JSON-RPC requests/responses for stdio mode:

Initialize
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
List Tools
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
List Clusters
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "list_clusters",
    "arguments": {}
  }
}
List Namespaces
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "list_namespaces",
    "arguments": {
      "cluster": "cluster1"
    }
  }
}
Get a Resource (Pod Example)
{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "get_resource",
    "arguments": {
      "cluster": "cluster1",
      "api_version": "v1",
      "resource": "pods",
      "namespace": "default",
      "name": "my-pod"
    }
  }
}
List Resources (Pods with Label Selector)
{
  "jsonrpc": "2.0",
  "id": 6,
  "method": "tools/call",
  "params": {
    "name": "list_resources",
    "arguments": {
      "cluster": "cluster1",
      "api_version": "v1",
      "resource": "pods",
      "namespace": "default",
      "labels": "app=myapp"
    }
  }
}
Get a Custom Resource (Submariner Example)
{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/call",
  "params": {
    "name": "get_resource",
    "arguments": {
      "cluster": "cluster1",
      "api_version": "submariner.io/v1alpha1",
      "resource": "submariners",
      "name": "submariner"
    }
  }
}
List Cluster-Scoped Resources (Nodes with Labels)
{
  "jsonrpc": "2.0",
  "id": 8,
  "method": "tools/call",
  "params": {
    "name": "list_resources",
    "arguments": {
      "cluster": "cluster1",
      "api_version": "v1",
      "resource": "nodes",
      "labels": "submariner.io/gateway=true"
    }
  }
}
Create a ServiceExport (Simple)
{
  "jsonrpc": "2.0",
  "id": 9,
  "method": "tools/call",
  "params": {
    "name": "create_serviceexport",
    "arguments": {
      "cluster": "cluster1",
      "namespace": "default",
      "name": "my-service"
    }
  }
}
Create a ServiceExport (With Manifest)
{
  "jsonrpc": "2.0",
  "id": 10,
  "method": "tools/call",
  "params": {
    "name": "create_serviceexport",
    "arguments": {
      "cluster": "cluster1",
      "namespace": "default",
      "name": "my-service",
      "manifest": "{\"apiVersion\":\"multicluster.x-k8s.io/v1alpha1\",\"kind\":\"ServiceExport\",\"metadata\":{\"name\":\"my-service\",\"namespace\":\"default\"},\"spec\":{\"exportedLabels\":{\"env\":\"prod\"}}}"
    }
  }
}

HTTP Mode Examples

These examples show how to make requests using curl when running in HTTP mode:

Health Check
curl http://localhost:8080/health

Response:

{
  "status": "healthy",
  "server": "kubernetes-mcp-server"
}
List Clusters
curl -s -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "list_clusters",
      "arguments": {}
    }
  }'
List Namespaces
curl -s -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "list_namespaces",
      "arguments": {
        "cluster": "cluster1"
      }
    }
  }'
Get a Resource (Pod)
curl -s -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "get_resource",
      "arguments": {
        "cluster": "cluster1",
        "api_version": "v1",
        "resource": "pods",
        "namespace": "default",
        "name": "my-pod"
      }
    }
  }'
List Resources (Submariner CRs)
curl -s -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 4,
    "method": "tools/call",
    "params": {
      "name": "list_resources",
      "arguments": {
        "cluster": "cluster1",
        "api_version": "submariner.io/v1alpha1",
        "resource": "submariners"
      }
    }
  }'
Create a ServiceExport
curl -s -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 5,
    "method": "tools/call",
    "params": {
      "name": "create_serviceexport",
      "arguments": {
        "cluster": "cluster1",
        "namespace": "default",
        "name": "my-service"
      }
    }
  }'

Project Structure

.
├── cmd/
│   └── server/
│       └── main.go                # Application entry point
├── config/
│   └── config.go                  # Configuration loading and validation
├── pkg/
│   ├── cluster/
│   │   └── manager.go             # Multi-cluster client manager
│   ├── handlers/
│   │   ├── resources.go           # Generic resource operations (Get, List, ListNamespaces)
│   │   ├── serviceexports.go      # ServiceExport CRUD operations
│   │   └── utils.go               # Shared utilities
│   ├── mcp/
│   │   ├── server.go              # MCP server implementation
│   │   ├── tools.go               # Tool definitions
│   │   └── types.go               # MCP protocol types
│   └── transport/
│       ├── http.go                # HTTP transport implementation
│       └── stdio.go               # Stdio transport implementation
├── .gitignore                     # Git ignore rules
├── Makefile                       # Build automation
├── README.md                      # This file
├── config.yaml.example            # Example configuration file
├── go.mod                         # Go module definition
└── go.sum                         # Go module checksums

Development

Build

make build

Format code

make fmt

Run tests

make test

Clean build artifacts

make clean

License

MIT License

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.