Skip to main content
Glama
yanmxa

Multi-Cluster MCP Server

by yanmxa

connect_cluster

Generates and binds a KUBECONFIG file to a specified ClusterRole, enabling secure access to a target Kubernetes cluster via the Multi-Cluster MCP Server.

Instructions

Generates the 'KUBECONFIG' for the managed cluster and binds it to the specified ClusterRole (default: cluster-admin).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
clusterYesThe target cluster where the ServiceAccount will be created for the KUBECONFIG.
cluster_roleNoThe ClusterRole defining permissions to access the cluster.cluster-admin

Implementation Reference

  • Python MCP tool handler for 'connect_cluster': decorates the function and implements logic to create ManagedServiceAccount, RBAC via ManifestWork, retrieve token secret, and generate kubeconfig file.
    @mcp.tool(description="Generates the 'KUBECONFIG' for the managed cluster and binds it to the specified ClusterRole (default: cluster-admin).") def connect_cluster( cluster: Annotated[str, Field(description="The target cluster where the ServiceAccount will be created for the KUBECONFIG.")], cluster_role: Annotated[str, Field(description="The ClusterRole defining permissions to access the cluster.")] = "cluster-admin", ) -> Annotated[str, Field(description="A message indicating the kubeconfig file or failure of the operation.")]: return setup_cluster_access(cluster, cluster_role=cluster_role) def setup_cluster_access(cluster: str, cluster_role: str = "cluster-admin", mcp_server: str = server_name): logger.debug(f"Setting up ManagedServiceAccount and RBAC for cluster: {cluster}") msa_result = create_or_update_managed_service_account(cluster, mcp_server) if not msa_result: logger.error("Failed to set up ManagedServiceAccount. Skipping RBAC setup.") return None rbac_result = create_or_update_rbac(cluster, mcp_server, cluster_role) if not rbac_result: logger.error("RBAC (ManifestWork) setup failed.") return None server_url = get_managed_cluster_url(cluster_name=cluster) if not server_url: logger.error(f"API server URL not found for ManagedCluster '{cluster}'.") return None token_secret = get_secret_with_timeout(cluster, mcp_server) if not token_secret: logger.error(f"Failed to get the service account token for cluster: {cluster}") return None kubeconfig_path_or_error = generate_kubeconfig_file_from_secret(token_secret, server_url, mcp_server) if not kubeconfig_path_or_error.startswith("/tmp/"): logger.error(kubeconfig_path_or_error) return None logger.debug(f"Generate the kubeconfig file: {kubeconfig_path_or_error}") return kubeconfig_path_or_error
  • TypeScript MCP tool handler for 'connect_cluster': async function that applies ManagedServiceAccount, ManagedClusterAddOn, ClusterRoleBinding via ManifestWork, polls for token secret, and generates KUBECONFIG.
    export async function connectCluster({ cluster, clusterRole = "cluster-admin" }: { cluster: string, clusterRole?: string }): Promise<CallToolResult> { // https://open-cluster-management.io/docs/getting-started/integration/managed-serviceaccount/ const mcpServerName = "multicluster-mcp-server" const msa = { apiVersion: 'authentication.open-cluster-management.io/v1beta1', kind: 'ManagedServiceAccount', metadata: { name: mcpServerName, namespace: cluster, }, spec: { rotation: {}, }, } const mca = { apiVersion: 'addon.open-cluster-management.io/v1alpha1', kind: 'ManagedClusterAddOn', metadata: { name: "managed-serviceaccount", namespace: cluster, }, } let result = `Successfully connected to cluster ${cluster} using ServiceAccount ${mcpServerName}, with the ${clusterRole} ClusterRole assigned.`; let isErrored = false try { const [applyMsa, getMca, getClusters] = await Promise.all([ client.patch<k8s.KubernetesObject>( msa, undefined, undefined, mcpServerName, true, k8s.PatchStrategy.ServerSideApply ), client.read(mca), listClusters({}) ]); if (!applyMsa) { console.warn(`Patched ManagedServiceAccount ${msa.metadata.namespace}/${msa.metadata.name} with empty response`); } const saNamespace = (getMca as any)?.status?.namespace; if (!saNamespace) { throw new Error(`ManagedServiceAccount ${mca.metadata.namespace}/${mca.metadata.name} not found in the cluster`); } const clusterRoleBinding = { apiVersion: "rbac.authorization.k8s.io/v1", kind: "ClusterRoleBinding", metadata: { name: `${mcpServerName}-clusterrolebinding`, }, roleRef: { apiGroup: "rbac.authorization.k8s.io", kind: "ClusterRole", name: clusterRole, // default clusterRole name for kubernetes admin - "cluster-admin" }, subjects: [ { kind: "ServiceAccount", name: mcpServerName, namespace: saNamespace, }, ], }; // create manifestWork to binding the clusterRole into the serviceAccount const bindingPermissionManifestWork = { apiVersion: 'work.open-cluster-management.io/v1', kind: 'ManifestWork', metadata: { name: mcpServerName, namespace: cluster, }, spec: { workload: { manifests: [ clusterRoleBinding, ] } }, } const [tokenSecret, applyRBACManifest, appliedStatusErrMessage] = await Promise.all([ getSecretWithRetry(cluster, mcpServerName), // createKubeConfigFile(acmMCPServer, cluster), client.patch<k8s.KubernetesObject>( bindingPermissionManifestWork, undefined, undefined, mcpServerName, true, k8s.PatchStrategy.ServerSideApply), // get the status manifestWorkAppliedErrorMessage(client, mcpServerName, cluster) ]); // error token if (typeof tokenSecret == 'string') { throw new Error(tokenSecret) } // error status if (appliedStatusErrMessage != "") { throw new Error(appliedStatusErrMessage) } const kubeConfigErrMessage = generateKubeconfig(tokenSecret, clusterToServerAPIMap); if (kubeConfigErrMessage) { throw new Error(kubeConfigErrMessage) } } catch (err: any) { isErrored = true result = `Failed to generate KUBECONFIG for ${cluster}: ${err}` } // return manifestsResponse return { content: [{ type: "text", text: result }], isErrored: isErrored } }
  • src/index.ts:31-35 (registration)
    Explicit registration of the 'connect_cluster' tool in the MCP server using server.tool() with description, args schema, and handler.
    "connect_cluster", connectClusterDesc, connectClusterArgs, async (args, extra) => connectCluster(args) // ensure connectCluster matches (args, extra) => ... )
  • Zod schema definition for connect_cluster tool parameters (cluster and optional clusterRole) and tool description.
    export const connectClusterArgs = { cluster: z.string().describe("The target cluster where the ServiceAccount will be created for the KUBECONFIG."), clusterRole: z.string().default('cluster-admin').describe("The ClusterRole defining permissions to access the cluster") } export const connectClusterDesc = "Generates the KUBECONFIG for the managed cluster and binds it to the specified ClusterRole (default: cluster-admin)."
  • Import of connect_cluster tool in __main__.py, which triggers auto-registration via @mcp.tool decorator when mcp.run() is called.
    from multicluster_mcp_server.tools.connect import connect_cluster

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yanmxa/multicluster-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server