mcp-server-kubernetes 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/utils/kubernetes-manager.d.ts +37 -0
- package/dist/utils/kubernetes-manager.js +129 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
[](https://github.com/Flux159/mcp-server-kubernetes/commits/main)
|
|
12
12
|
[](https://smithery.ai/protocol/mcp-server-kubernetes)
|
|
13
13
|
|
|
14
|
-
MCP Server that can connect to a Kubernetes cluster and manage it.
|
|
14
|
+
MCP Server that can connect to a Kubernetes cluster and manage it. Supports loading kubeconfig from multiple sources in priority order.
|
|
15
15
|
|
|
16
16
|
https://github.com/user-attachments/assets/f25f8f4e-4d04-479b-9ae0-5dac452dd2ed
|
|
17
17
|
|
|
18
18
|
<a href="https://glama.ai/mcp/servers/w71ieamqrt"><img width="380" height="200" src="https://glama.ai/mcp/servers/w71ieamqrt/badge" /></a>
|
|
19
19
|
|
|
20
|
+
|
|
20
21
|
## Usage with Claude Desktop
|
|
21
22
|
|
|
22
23
|
```json
|
|
@@ -30,6 +31,8 @@ https://github.com/user-attachments/assets/f25f8f4e-4d04-479b-9ae0-5dac452dd2ed
|
|
|
30
31
|
}
|
|
31
32
|
```
|
|
32
33
|
|
|
34
|
+
By default, the server loads kubeconfig from `~/.kube/config`. For additional authentication options (environment variables, custom paths, etc.), see [ADVANCED_README.md](ADVANCED_README.md).
|
|
35
|
+
|
|
33
36
|
The server will automatically connect to your current kubectl context. Make sure you have:
|
|
34
37
|
|
|
35
38
|
1. kubectl installed and in your PATH
|
|
@@ -13,6 +13,38 @@ export declare class KubernetesManager {
|
|
|
13
13
|
* A very simple test to check if the application is running inside a Kubernetes cluster
|
|
14
14
|
*/
|
|
15
15
|
private isRunningInCluster;
|
|
16
|
+
/**
|
|
17
|
+
* Check if KUBECONFIG_YAML environment variable is available
|
|
18
|
+
*/
|
|
19
|
+
private hasEnvKubeconfigYaml;
|
|
20
|
+
/**
|
|
21
|
+
* Check if KUBECONFIG_JSON environment variable is available
|
|
22
|
+
*/
|
|
23
|
+
private hasEnvKubeconfigJson;
|
|
24
|
+
/**
|
|
25
|
+
* Check if minimal K8S_SERVER and K8S_TOKEN environment variables are available
|
|
26
|
+
*/
|
|
27
|
+
private hasEnvMinimalKubeconfig;
|
|
28
|
+
/**
|
|
29
|
+
* Load kubeconfig from KUBECONFIG_PATH environment variable (file path)
|
|
30
|
+
*/
|
|
31
|
+
private loadEnvKubeconfigPath;
|
|
32
|
+
/**
|
|
33
|
+
* Load kubeconfig from KUBECONFIG_YAML environment variable (YAML format)
|
|
34
|
+
*/
|
|
35
|
+
private loadEnvKubeconfigYaml;
|
|
36
|
+
/**
|
|
37
|
+
* Load kubeconfig from KUBECONFIG_JSON environment variable (JSON format)
|
|
38
|
+
*/
|
|
39
|
+
private loadEnvKubeconfigJson;
|
|
40
|
+
/**
|
|
41
|
+
* Load kubeconfig from minimal K8S_SERVER and K8S_TOKEN environment variables
|
|
42
|
+
*/
|
|
43
|
+
private loadEnvMinimalKubeconfig;
|
|
44
|
+
/**
|
|
45
|
+
* Check if KUBECONFIG_PATH environment variable is available
|
|
46
|
+
*/
|
|
47
|
+
private hasEnvKubeconfigPath;
|
|
16
48
|
/**
|
|
17
49
|
* Set the current context to the desired context name.
|
|
18
50
|
*
|
|
@@ -30,4 +62,9 @@ export declare class KubernetesManager {
|
|
|
30
62
|
getCoreApi(): k8s.CoreV1Api;
|
|
31
63
|
getAppsApi(): k8s.AppsV1Api;
|
|
32
64
|
getBatchApi(): k8s.BatchV1Api;
|
|
65
|
+
/**
|
|
66
|
+
* Get the default namespace for operations
|
|
67
|
+
* Uses K8S_NAMESPACE environment variable if set, otherwise defaults to "default"
|
|
68
|
+
*/
|
|
69
|
+
getDefaultNamespace(): string;
|
|
33
70
|
}
|
|
@@ -11,11 +11,59 @@ export class KubernetesManager {
|
|
|
11
11
|
constructor() {
|
|
12
12
|
this.kc = new k8s.KubeConfig();
|
|
13
13
|
if (this.isRunningInCluster()) {
|
|
14
|
+
// Priority 1: In-cluster configuration (existing)
|
|
14
15
|
this.kc.loadFromCluster();
|
|
15
16
|
}
|
|
17
|
+
else if (this.hasEnvKubeconfigYaml()) {
|
|
18
|
+
// Priority 2: Full kubeconfig as YAML string
|
|
19
|
+
try {
|
|
20
|
+
this.loadEnvKubeconfigYaml();
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
throw new Error(`Failed to parse KUBECONFIG_YAML: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else if (this.hasEnvKubeconfigJson()) {
|
|
27
|
+
// Priority 3: Full kubeconfig as JSON string
|
|
28
|
+
try {
|
|
29
|
+
this.loadEnvKubeconfigJson();
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
throw new Error(`Failed to parse KUBECONFIG_JSON: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else if (this.hasEnvMinimalKubeconfig()) {
|
|
36
|
+
// Priority 4: Minimal config with individual environment variables
|
|
37
|
+
try {
|
|
38
|
+
this.loadEnvMinimalKubeconfig();
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
throw new Error(`Failed to create kubeconfig from K8S_SERVER and K8S_TOKEN: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (this.hasEnvKubeconfigPath()) {
|
|
45
|
+
// Priority 5: Custom kubeconfig file path
|
|
46
|
+
try {
|
|
47
|
+
this.loadEnvKubeconfigPath();
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw new Error(`Failed to load kubeconfig from KUBECONFIG_PATH: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
16
53
|
else {
|
|
54
|
+
// Priority 6: Default file-based configuration (existing fallback)
|
|
17
55
|
this.kc.loadFromDefault();
|
|
18
56
|
}
|
|
57
|
+
// Apply context override if specified
|
|
58
|
+
if (process.env.K8S_CONTEXT) {
|
|
59
|
+
try {
|
|
60
|
+
this.setCurrentContext(process.env.K8S_CONTEXT);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.warn(`Warning: Could not set context to ${process.env.K8S_CONTEXT}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Initialize API clients
|
|
19
67
|
this.k8sApi = this.kc.makeApiClient(k8s.CoreV1Api);
|
|
20
68
|
this.k8sAppsApi = this.kc.makeApiClient(k8s.AppsV1Api);
|
|
21
69
|
this.k8sBatchApi = this.kc.makeApiClient(k8s.BatchV1Api);
|
|
@@ -32,6 +80,80 @@ export class KubernetesManager {
|
|
|
32
80
|
return false;
|
|
33
81
|
}
|
|
34
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Check if KUBECONFIG_YAML environment variable is available
|
|
85
|
+
*/
|
|
86
|
+
hasEnvKubeconfigYaml() {
|
|
87
|
+
return !!(process.env.KUBECONFIG_YAML && process.env.KUBECONFIG_YAML.trim());
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Check if KUBECONFIG_JSON environment variable is available
|
|
91
|
+
*/
|
|
92
|
+
hasEnvKubeconfigJson() {
|
|
93
|
+
return !!(process.env.KUBECONFIG_JSON && process.env.KUBECONFIG_JSON.trim());
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Check if minimal K8S_SERVER and K8S_TOKEN environment variables are available
|
|
97
|
+
*/
|
|
98
|
+
hasEnvMinimalKubeconfig() {
|
|
99
|
+
return !!(process.env.K8S_SERVER &&
|
|
100
|
+
process.env.K8S_SERVER.trim() &&
|
|
101
|
+
process.env.K8S_TOKEN &&
|
|
102
|
+
process.env.K8S_TOKEN.trim());
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Load kubeconfig from KUBECONFIG_PATH environment variable (file path)
|
|
106
|
+
*/
|
|
107
|
+
loadEnvKubeconfigPath() {
|
|
108
|
+
this.kc.loadFromFile(process.env.KUBECONFIG_PATH);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Load kubeconfig from KUBECONFIG_YAML environment variable (YAML format)
|
|
112
|
+
*/
|
|
113
|
+
loadEnvKubeconfigYaml() {
|
|
114
|
+
this.kc.loadFromString(process.env.KUBECONFIG_YAML);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Load kubeconfig from KUBECONFIG_JSON environment variable (JSON format)
|
|
118
|
+
*/
|
|
119
|
+
loadEnvKubeconfigJson() {
|
|
120
|
+
const configObj = JSON.parse(process.env.KUBECONFIG_JSON);
|
|
121
|
+
this.kc.loadFromOptions(configObj);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Load kubeconfig from minimal K8S_SERVER and K8S_TOKEN environment variables
|
|
125
|
+
*/
|
|
126
|
+
loadEnvMinimalKubeconfig() {
|
|
127
|
+
if (!process.env.K8S_SERVER || !process.env.K8S_TOKEN) {
|
|
128
|
+
throw new Error('K8S_SERVER and K8S_TOKEN environment variables are required');
|
|
129
|
+
}
|
|
130
|
+
const cluster = {
|
|
131
|
+
name: 'env-cluster',
|
|
132
|
+
server: process.env.K8S_SERVER,
|
|
133
|
+
skipTLSVerify: process.env.K8S_SKIP_TLS_VERIFY === 'true'
|
|
134
|
+
};
|
|
135
|
+
const user = {
|
|
136
|
+
name: 'env-user',
|
|
137
|
+
token: process.env.K8S_TOKEN
|
|
138
|
+
};
|
|
139
|
+
const context = {
|
|
140
|
+
name: 'env-context',
|
|
141
|
+
user: user.name,
|
|
142
|
+
cluster: cluster.name
|
|
143
|
+
};
|
|
144
|
+
this.kc.loadFromOptions({
|
|
145
|
+
clusters: [cluster],
|
|
146
|
+
users: [user],
|
|
147
|
+
contexts: [context],
|
|
148
|
+
currentContext: context.name
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Check if KUBECONFIG_PATH environment variable is available
|
|
153
|
+
*/
|
|
154
|
+
hasEnvKubeconfigPath() {
|
|
155
|
+
return !!(process.env.KUBECONFIG_PATH && process.env.KUBECONFIG_PATH.trim());
|
|
156
|
+
}
|
|
35
157
|
/**
|
|
36
158
|
* Set the current context to the desired context name.
|
|
37
159
|
*
|
|
@@ -110,4 +232,11 @@ export class KubernetesManager {
|
|
|
110
232
|
getBatchApi() {
|
|
111
233
|
return this.k8sBatchApi;
|
|
112
234
|
}
|
|
235
|
+
/**
|
|
236
|
+
* Get the default namespace for operations
|
|
237
|
+
* Uses K8S_NAMESPACE environment variable if set, otherwise defaults to "default"
|
|
238
|
+
*/
|
|
239
|
+
getDefaultNamespace() {
|
|
240
|
+
return process.env.K8S_NAMESPACE || 'default';
|
|
241
|
+
}
|
|
113
242
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-server-kubernetes",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "MCP server for interacting with Kubernetes clusters via kubectl",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"@types/express": "5.0.1",
|
|
47
47
|
"@types/js-yaml": "4.0.9",
|
|
48
48
|
"@types/node": "22.9.3",
|
|
49
|
+
"esbuild": "0.21.5",
|
|
49
50
|
"shx": "0.3.4",
|
|
50
51
|
"typescript": "5.6.2",
|
|
51
52
|
"vitest": "2.1.9"
|