Skip to content

Conversation

@mbillow
Copy link

@mbillow mbillow commented Nov 19, 2025

In order to allow third parties to build their own cluster providers, I'd like to propose a very small change to make the Manager initialization function newManager public. This allows people to easily extend the upstream package without having to fork it.

Currently, we can create our own implementation of Provider and a register a provider configuration, but the provider implementation itself needs to be able to initialize Managers for each cluster it wants to use, which is impossible since only the NewInClusterManager and NewKubeconfigManager functions are public.

A super simple example would look like:

pkg/custom_config.go

import (
	// ...others...
	"github.com/containers/kubernetes-mcp-server/pkg/config"
)

type Config struct {
	DemoConfig string `toml:"demo"`
}

func init() {
	// Register config parser with the upstream MCP server
	config.RegisterProviderConfig(ProviderStrategy, parseConfig)
}

func parseConfig(ctx context.Context, primitive toml.Primitive, md toml.MetaData) (config.ProviderConfig, error) {
	// ...impl specific config parsing...
}

pkg/custom_provider.go

import (
	// ...others...
	"github.com/containers/kubernetes-mcp-server/pkg/config"
	"github.com/containers/kubernetes-mcp-server/pkg/kubernetes"
)

const ProviderStrategy = "custom"

type Provider struct {
	clusters map[string]*ClusterInfo
	managers map[string]*kubernetes.Manager
}
var _ kubernetes.Provider = &Provider{}

func init() {
	// Register this provider with the upstream MCP server
	kubernetes.RegisterProvider(ProviderStrategy, NewProvider)
}

func NewProvider(cfg *config.StaticConfig) (kubernetes.Provider, error) {
	p := &Provider{}
	p.fetchClusters()
	return p, nil
}

func (p *Provider) fetchClusters() error {
	p.clusters = company.magicClusterDiscovery()
}

func (p *Provider) managerForCluster(shortname string) (*kubernetes.Manager, error) {
	if m, ok := p.managers[shortname]; ok && m != nil {
		return m, nil
	}
	cluster, ok := p.clusters[shortname]
	if !ok {
		return nil, fmt.Errorf("cluster %s not found", shortname)
	}

	// we'd build the necessary clientcmd configs, etc. here
	// then we can call our newly public function
	m, err := kubernetes.NewManager(...)
	p.managers[shortname] = m
	return m, nil
}

// rest of the provider implementation where functions like `VerifyToken` call `p.managerForCluster`...

main.go

import (
	// ...others...

	// import mcp server
	"github.com/containers/kubernetes-mcp-server/pkg/kubernetes-mcp-server/cmd"

	// import our custom provider - this triggers init() which registers the provider
	_ "github.com/foo/bar/pkg/custom_provider"
)

func main() {
	flags := pflag.NewFlagSet("kubernetes-mcp-server", pflag.ExitOnError)
	pflag.CommandLine = flags

	root := cmd.NewMCPServer(genericiooptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr})
	if err := root.Execute(); err != nil {
		os.Exit(1)
	}
}

config.toml

cluster_provider_strategy = "custom"

[cluster_provider_configs.custom]
demo = "hello, world"

@mbillow mbillow changed the title Allow for the Creation of External Kubernetes Cluster Providers feat(kubernetes): public new manager to enable external providers Nov 19, 2025
@Cali0707 Cali0707 requested a review from manusa November 19, 2025 17:44
@manusa
Copy link
Member

manusa commented Nov 20, 2025

Hi @mbillow
Thanks for sending this, your use case looks very interesting and aligned with our goal of making this MCP server a good base to build other toolsets on top.
Let me evaluate how does this intersect with the work I'm doing in #473 and what are other alternatives we might want to consider to add support for your use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants