@prodisco/k8s-mcp 0.1.2 → 0.1.3
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 +63 -35
- package/dist/kube/client.d.ts +6 -0
- package/dist/kube/client.d.ts.map +1 -1
- package/dist/kube/client.js +11 -0
- package/dist/kube/client.js.map +1 -1
- package/dist/kube/client.test.d.ts +2 -0
- package/dist/kube/client.test.d.ts.map +1 -0
- package/dist/kube/client.test.js +59 -0
- package/dist/kube/client.test.js.map +1 -0
- package/dist/server.js +94 -50
- package/dist/server.js.map +1 -1
- package/dist/tools/api/apiTools.d.ts +6 -0
- package/dist/tools/api/apiTools.d.ts.map +1 -0
- package/dist/tools/api/apiTools.js +132 -0
- package/dist/tools/api/apiTools.js.map +1 -0
- package/dist/tools/kubernetes/metadata.d.ts +67 -27
- package/dist/tools/kubernetes/metadata.d.ts.map +1 -1
- package/dist/tools/kubernetes/metadata.js +2 -7
- package/dist/tools/kubernetes/metadata.js.map +1 -1
- package/dist/tools/kubernetes/searchTools.d.ts +180 -5
- package/dist/tools/kubernetes/searchTools.d.ts.map +1 -1
- package/dist/tools/kubernetes/searchTools.js +1365 -261
- package/dist/tools/kubernetes/searchTools.js.map +1 -1
- package/dist/util/apiClient.d.ts +20 -0
- package/dist/util/apiClient.d.ts.map +1 -0
- package/dist/util/apiClient.js +90 -0
- package/dist/util/apiClient.js.map +1 -0
- package/dist/util/k8sClient.d.ts +38 -0
- package/dist/util/k8sClient.d.ts.map +1 -0
- package/dist/util/k8sClient.js +85 -0
- package/dist/util/k8sClient.js.map +1 -0
- package/dist/util/logger.d.ts +26 -0
- package/dist/util/logger.d.ts.map +1 -0
- package/dist/util/logger.js +62 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/summary.d.ts +14 -14
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
# ProDisco (Progressive Disclosure
|
|
1
|
+
# ProDisco (Progressive Disclosure Kubernetes MCP Server)
|
|
2
2
|
|
|
3
|
-
ProDisco gives
|
|
3
|
+
ProDisco gives AI agents Kubernetes access that closely follows Anthropic’s [Progressive Disclosure](https://www.anthropic.com/engineering/code-execution-with-mcp) pattern: the MCP server exposes search tools which in turn surface TypeScript modules, agents discover them to write code, and only the final console output returns to the agent.
|
|
4
4
|
|
|
5
5
|
## Why Progressive Disclosure Matters
|
|
6
6
|
|
|
7
|
-
Anthropic’s latest guidance explains why MCP servers should progressively reveal capabilities instead of dumping every tool definition into the model context. When agents explore a filesystem of TypeScript modules,
|
|
7
|
+
Anthropic’s latest guidance explains why MCP servers should progressively reveal capabilities instead of dumping every tool definition into the model context. When agents explore a filesystem of TypeScript modules, they only load what they need and process data inside the execution environment, then return a concise result to the chat. This keeps token usage low, improves latency, and avoids copying large intermediate payloads through the model ([source](https://www.anthropic.com/engineering/code-execution-with-mcp)).
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- Agents only see a single advertised tool (`kubernetes.searchTools`); they call it with structured parameters (resourceType, action, scope) to discover the TypeScript modules (get pods, list nodes, fetch logs, etc.) that the server exposes, then write their own code to compose those modules without loading unused schemas.
|
|
11
|
-
- Letting the model issue one instruction instead of micromanaging dozens of sequential tool calls.
|
|
12
|
-
- Agents can mix and match multiple Kubernetes modules joining pod stats with node health, or correlating events with logs without shuttling raw outputs between tools in the chat loop, which dramatically cuts token usage.
|
|
9
|
+
ProDisco goes a step further: instead of exposing custom TypeScript modules, it provides a structured parameter search tool that returns the most suitable methods from the official Kubernetes client library, including the type definitions for their input and return values. This lets agents dynamically interact with the upstream Kubernetes library while avoiding any ongoing maintenance burden in this repository to mirror or wrap those APIs.
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Demo
|
|
15
|
+
|
|
16
|
+

|
|
15
17
|
|
|
16
18
|
---
|
|
17
19
|
|
|
@@ -56,27 +58,43 @@ ProDisco automatically creates a `~/.prodisco/scripts/cache/` directory in your
|
|
|
56
58
|
|
|
57
59
|
## Available Tools
|
|
58
60
|
|
|
59
|
-
ProDisco exposes
|
|
61
|
+
ProDisco exposes a single tool with three modes for agents to discover and interact with the Kubernetes API.
|
|
62
|
+
|
|
63
|
+
For comprehensive documentation including architecture details and example workflows, see [docs/search-tools.md](docs/search-tools.md).
|
|
60
64
|
|
|
61
|
-
###
|
|
65
|
+
### kubernetes.searchTools
|
|
62
66
|
|
|
63
|
-
Find Kubernetes API methods
|
|
67
|
+
Find Kubernetes API methods, get type definitions, or search cached scripts.
|
|
64
68
|
|
|
65
69
|
**Input:**
|
|
66
70
|
```typescript
|
|
67
71
|
{
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
// Mode selection
|
|
73
|
+
mode?: 'methods' | 'types' | 'scripts'; // default: 'methods'
|
|
74
|
+
|
|
75
|
+
// Methods mode parameters
|
|
76
|
+
resourceType?: string; // e.g., "Pod", "Deployment", "Service"
|
|
77
|
+
action?: string; // e.g., "list", "read", "create", "delete", "patch", "replace", "connect"
|
|
70
78
|
scope?: 'namespaced' | 'cluster' | 'all'; // default: 'all'
|
|
71
|
-
exclude?: {
|
|
72
|
-
actions?: string[];
|
|
73
|
-
apiClasses?: string[];
|
|
79
|
+
exclude?: { // Optional: filter out methods
|
|
80
|
+
actions?: string[]; // e.g., ["delete", "create"]
|
|
81
|
+
apiClasses?: string[]; // e.g., ["CoreV1Api"]
|
|
74
82
|
};
|
|
75
|
-
|
|
83
|
+
|
|
84
|
+
// Types mode parameters
|
|
85
|
+
types?: string[]; // Type names or property paths
|
|
86
|
+
depth?: number; // Nested type depth (default: 1, max: 2)
|
|
87
|
+
|
|
88
|
+
// Scripts mode parameters
|
|
89
|
+
searchTerm?: string; // Search term (omit to list all scripts)
|
|
90
|
+
|
|
91
|
+
// Shared parameters (all modes)
|
|
92
|
+
limit?: number; // Max results (default: 10, max: 50)
|
|
93
|
+
offset?: number; // Skip N results for pagination (default: 0)
|
|
76
94
|
}
|
|
77
95
|
```
|
|
78
96
|
|
|
79
|
-
**
|
|
97
|
+
**Methods Mode Examples:**
|
|
80
98
|
```typescript
|
|
81
99
|
// List all Pod-related methods
|
|
82
100
|
{ resourceType: "Pod" }
|
|
@@ -92,29 +110,39 @@ Find Kubernetes API methods by resource type and action.
|
|
|
92
110
|
|
|
93
111
|
// Pod methods excluding CoreV1Api (shows only PolicyV1Api, AutoscalingV1Api, etc.)
|
|
94
112
|
{ resourceType: "Pod", exclude: { apiClasses: ["CoreV1Api"] } }
|
|
95
|
-
|
|
96
|
-
// Pod methods excluding delete from CoreV1Api only (AND logic)
|
|
97
|
-
{ resourceType: "Pod", exclude: { actions: ["delete"], apiClasses: ["CoreV1Api"] } }
|
|
98
113
|
```
|
|
99
114
|
|
|
100
|
-
|
|
115
|
+
**Types Mode Examples:**
|
|
116
|
+
```typescript
|
|
117
|
+
// Get V1Pod type definition
|
|
118
|
+
{ mode: "types", types: ["V1Pod"] }
|
|
101
119
|
|
|
102
|
-
Get
|
|
120
|
+
// Get multiple types
|
|
121
|
+
{ mode: "types", types: ["V1Pod", "V1Deployment", "V1Service"] }
|
|
103
122
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
123
|
+
// Navigate to nested types using dot notation
|
|
124
|
+
{ mode: "types", types: ["V1Deployment.spec"] } // Returns V1DeploymentSpec
|
|
125
|
+
{ mode: "types", types: ["V1Pod.spec.containers"] } // Returns V1Container (array element)
|
|
126
|
+
{ mode: "types", types: ["V1Pod.status.conditions"] } // Returns V1PodCondition
|
|
127
|
+
|
|
128
|
+
// Include nested types at depth 2
|
|
129
|
+
{ mode: "types", types: ["V1Pod"], depth: 2 }
|
|
111
130
|
```
|
|
112
131
|
|
|
113
|
-
**
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
132
|
+
**Scripts Mode Examples:**
|
|
133
|
+
```typescript
|
|
134
|
+
// List all cached scripts
|
|
135
|
+
{ mode: "scripts" }
|
|
136
|
+
|
|
137
|
+
// Search for pod-related scripts
|
|
138
|
+
{ mode: "scripts", searchTerm: "pod" }
|
|
139
|
+
|
|
140
|
+
// Search for logging scripts
|
|
141
|
+
{ mode: "scripts", searchTerm: "logs" }
|
|
142
|
+
|
|
143
|
+
// Paginate through scripts
|
|
144
|
+
{ mode: "scripts", limit: 5, offset: 5 }
|
|
145
|
+
```
|
|
118
146
|
|
|
119
147
|
---
|
|
120
148
|
|
package/dist/kube/client.d.ts
CHANGED
|
@@ -9,6 +9,12 @@ interface KubernetesClientBundle {
|
|
|
9
9
|
}
|
|
10
10
|
export declare function getKubeClients(): KubernetesClientBundle;
|
|
11
11
|
export declare function resetKubeClients(): void;
|
|
12
|
+
/**
|
|
13
|
+
* Probes the Kubernetes cluster to verify connectivity.
|
|
14
|
+
* Makes a lightweight API call to check if the cluster is reachable.
|
|
15
|
+
* @throws Error if the cluster is not accessible
|
|
16
|
+
*/
|
|
17
|
+
export declare function probeClusterConnectivity(): Promise<void>;
|
|
12
18
|
export declare function splitApiVersion(apiVersion: string): {
|
|
13
19
|
group?: string;
|
|
14
20
|
version: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/kube/client.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EAChB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAKpF,UAAU,sBAAsB;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,aAAa,EAAE,gBAAgB,CAAC;IAChC,SAAS,EAAE,mBAAmB,CAAC;CAChC;AAkCD,wBAAgB,cAAc,IAAI,sBAAsB,CAMvD;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAWvF;AAED,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC,CAejD;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAevF;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;IAC3D,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,GACxC,OAAO,CAAC,gBAAgB,CAAC,CAgB3B;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAYlB;AAaD,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,kBAAkB,EAC9B,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,OAAO,CAAC,CAiClB;AAED,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAwBxF"}
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/kube/client.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EAChB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAKpF,UAAU,sBAAsB;IAC9B,UAAU,EAAE,UAAU,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,aAAa,EAAE,gBAAgB,CAAC;IAChC,SAAS,EAAE,mBAAmB,CAAC;CAChC;AAkCD,wBAAgB,cAAc,IAAI,sBAAsB,CAMvD;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAWvF;AAED,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,CAAC,CAejD;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAevF;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;IAC3D,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,gBAAgB,CAAC,gBAAgB,CAAC,GACxC,OAAO,CAAC,gBAAgB,CAAC,CAgB3B;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAYlB;AAaD,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,kBAAkB,EAC9B,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,OAAO,CAAC,CAiClB;AAED,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAwBxF"}
|
package/dist/kube/client.js
CHANGED
|
@@ -42,6 +42,17 @@ export function getKubeClients() {
|
|
|
42
42
|
export function resetKubeClients() {
|
|
43
43
|
cachedClients = null;
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Probes the Kubernetes cluster to verify connectivity.
|
|
47
|
+
* Makes a lightweight API call to check if the cluster is reachable.
|
|
48
|
+
* @throws Error if the cluster is not accessible
|
|
49
|
+
*/
|
|
50
|
+
export async function probeClusterConnectivity() {
|
|
51
|
+
const { core } = getKubeClients();
|
|
52
|
+
// Use a lightweight API call - getting API versions or listing namespaces with limit=1
|
|
53
|
+
// This verifies both network connectivity and authentication
|
|
54
|
+
await core.listNamespace({ limit: 1 });
|
|
55
|
+
}
|
|
45
56
|
export function splitApiVersion(apiVersion) {
|
|
46
57
|
if (!apiVersion.includes('/')) {
|
|
47
58
|
return { version: apiVersion };
|
package/dist/kube/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/kube/client.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/kube/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.test.d.ts","sourceRoot":"","sources":["../../src/kube/client.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
// Store the mock function at module level so we can control it
|
|
3
|
+
const mockListNamespace = vi.fn();
|
|
4
|
+
// Mock the @kubernetes/client-node module before importing client
|
|
5
|
+
vi.mock('@kubernetes/client-node', () => {
|
|
6
|
+
class MockKubeConfig {
|
|
7
|
+
loadFromDefault = vi.fn();
|
|
8
|
+
loadFromCluster = vi.fn();
|
|
9
|
+
makeApiClient = vi.fn().mockReturnValue({
|
|
10
|
+
listNamespace: mockListNamespace,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
class MockKubernetesObjectApi {
|
|
14
|
+
static makeApiClient = vi.fn().mockReturnValue({});
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
KubeConfig: MockKubeConfig,
|
|
18
|
+
CoreV1Api: class {
|
|
19
|
+
},
|
|
20
|
+
AppsV1Api: class {
|
|
21
|
+
},
|
|
22
|
+
CustomObjectsApi: class {
|
|
23
|
+
},
|
|
24
|
+
KubernetesObjectApi: MockKubernetesObjectApi,
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
// Import after mocking
|
|
28
|
+
import { probeClusterConnectivity, resetKubeClients } from './client.js';
|
|
29
|
+
describe('probeClusterConnectivity', () => {
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
// Reset the cached clients before each test
|
|
32
|
+
resetKubeClients();
|
|
33
|
+
vi.clearAllMocks();
|
|
34
|
+
});
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
resetKubeClients();
|
|
37
|
+
});
|
|
38
|
+
it('should succeed when cluster is reachable', async () => {
|
|
39
|
+
mockListNamespace.mockResolvedValueOnce({ items: [] });
|
|
40
|
+
await expect(probeClusterConnectivity()).resolves.toBeUndefined();
|
|
41
|
+
expect(mockListNamespace).toHaveBeenCalledWith({ limit: 1 });
|
|
42
|
+
});
|
|
43
|
+
it('should throw when cluster is not reachable', async () => {
|
|
44
|
+
const connectionError = new Error('connect ECONNREFUSED 127.0.0.1:6443');
|
|
45
|
+
mockListNamespace.mockRejectedValueOnce(connectionError);
|
|
46
|
+
await expect(probeClusterConnectivity()).rejects.toThrow('connect ECONNREFUSED 127.0.0.1:6443');
|
|
47
|
+
});
|
|
48
|
+
it('should throw when authentication fails', async () => {
|
|
49
|
+
const authError = new Error('Unauthorized');
|
|
50
|
+
mockListNamespace.mockRejectedValueOnce(authError);
|
|
51
|
+
await expect(probeClusterConnectivity()).rejects.toThrow('Unauthorized');
|
|
52
|
+
});
|
|
53
|
+
it('should throw when cluster returns forbidden', async () => {
|
|
54
|
+
const forbiddenError = new Error('Forbidden: User cannot list namespaces at the cluster scope');
|
|
55
|
+
mockListNamespace.mockRejectedValueOnce(forbiddenError);
|
|
56
|
+
await expect(probeClusterConnectivity()).rejects.toThrow('Forbidden');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=client.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../src/kube/client.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEzE,+DAA+D;AAC/D,MAAM,iBAAiB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AAElC,kEAAkE;AAClE,EAAE,CAAC,IAAI,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACtC,MAAM,cAAc;QAClB,eAAe,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,eAAe,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1B,aAAa,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC;YACtC,aAAa,EAAE,iBAAiB;SACjC,CAAC,CAAC;KACJ;IAED,MAAM,uBAAuB;QAC3B,MAAM,CAAC,aAAa,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;;IAGrD,OAAO;QACL,UAAU,EAAE,cAAc;QAC1B,SAAS,EAAE;SAAQ;QACnB,SAAS,EAAE;SAAQ;QACnB,gBAAgB,EAAE;SAAQ;QAC1B,mBAAmB,EAAE,uBAAuB;KAC7C,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,uBAAuB;AACvB,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEzE,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,UAAU,CAAC,GAAG,EAAE;QACd,4CAA4C;QAC5C,gBAAgB,EAAE,CAAC;QACnB,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,gBAAgB,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,iBAAiB,CAAC,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAEvD,MAAM,MAAM,CAAC,wBAAwB,EAAE,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC;QAClE,MAAM,CAAC,iBAAiB,CAAC,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,eAAe,GAAG,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzE,iBAAiB,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;QAEzD,MAAM,MAAM,CAAC,wBAAwB,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC;IAClG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;QAC5C,iBAAiB,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;QAEnD,MAAM,MAAM,CAAC,wBAAwB,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,cAAc,GAAG,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;QAChG,iBAAiB,CAAC,qBAAqB,CAAC,cAAc,CAAC,CAAC;QAExD,MAAM,MAAM,CAAC,wBAAwB,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -5,12 +5,13 @@ import { fileURLToPath } from 'node:url';
|
|
|
5
5
|
import * as fs from 'node:fs';
|
|
6
6
|
import * as os from 'node:os';
|
|
7
7
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
8
|
+
import { logger } from './util/logger.js';
|
|
8
9
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
9
10
|
const require = createRequire(import.meta.url);
|
|
10
11
|
const pkg = require('../package.json');
|
|
11
|
-
import { searchToolsTool } from './tools/kubernetes/searchTools.js';
|
|
12
|
-
import { getTypeDefinitionTool } from './tools/kubernetes/typeDefinitions.js';
|
|
12
|
+
import { searchToolsTool, warmupSearchIndex, shutdownSearchIndex } from './tools/kubernetes/searchTools.js';
|
|
13
13
|
import { PUBLIC_GENERATED_ROOT_PATH_WITH_SLASH, listGeneratedFiles, readGeneratedFile, } from './resources/filesystem.js';
|
|
14
|
+
import { probeClusterConnectivity } from './kube/client.js';
|
|
14
15
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
16
|
const __dirname = path.dirname(__filename);
|
|
16
17
|
const GENERATED_DIR = path.resolve(__dirname, 'tools/kubernetes');
|
|
@@ -19,12 +20,9 @@ const server = new McpServer({
|
|
|
19
20
|
version: typeof pkg.version === 'string' ? pkg.version : '0.0.0',
|
|
20
21
|
}, {
|
|
21
22
|
instructions: 'Kubernetes operations via Progressive Disclosure. Use the kubernetes.searchTools tool to discover available operations. ' +
|
|
22
|
-
'The tool returns available Kubernetes API methods and
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
'Write scripts to the scriptsDirectory path and import dependencies from packageDirectory/node_modules/@kubernetes/client-node. ' +
|
|
26
|
-
'Example: import * as k8s from \'/path/from/packageDirectory/node_modules/@kubernetes/client-node\'. ' +
|
|
27
|
-
'Always use absolute paths from the paths object to ensure scripts work from any directory.',
|
|
23
|
+
'The tool returns available Kubernetes API methods and a "paths.scriptsDirectory" for writing scripts. ' +
|
|
24
|
+
'Write scripts to scriptsDirectory and use bare imports: import * as k8s from \'@kubernetes/client-node\'. ' +
|
|
25
|
+
'The scriptsDirectory has a node_modules symlink that handles package resolution automatically.',
|
|
28
26
|
});
|
|
29
27
|
// Expose generated TypeScript files as MCP resources using ResourceTemplate
|
|
30
28
|
import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
@@ -66,62 +64,108 @@ server.registerResource('generated-typescript-files', resourceTemplate, {
|
|
|
66
64
|
],
|
|
67
65
|
};
|
|
68
66
|
});
|
|
69
|
-
|
|
67
|
+
logger.info(`Exposed ${GENERATED_DIR} as MCP resources`);
|
|
70
68
|
// Register kubernetes.searchTools helper as an exposed tool.
|
|
69
|
+
// This tool now supports both modes: 'methods' (API discovery) and 'types' (type definitions)
|
|
71
70
|
server.registerTool(searchToolsTool.name, {
|
|
72
|
-
title: 'Kubernetes
|
|
71
|
+
title: 'Kubernetes Search Tools',
|
|
73
72
|
description: searchToolsTool.description,
|
|
74
73
|
inputSchema: searchToolsTool.schema,
|
|
75
74
|
}, async (args) => {
|
|
76
75
|
const parsedArgs = await searchToolsTool.schema.parseAsync(args);
|
|
77
76
|
const result = await searchToolsTool.execute(parsedArgs);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
77
|
+
// Handle different result modes
|
|
78
|
+
if (result.mode === 'types') {
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{
|
|
82
|
+
type: 'text',
|
|
83
|
+
text: result.summary,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
type: 'text',
|
|
87
|
+
text: JSON.stringify(result.types, null, 2),
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
structuredContent: result,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
else if (result.mode === 'scripts') {
|
|
94
|
+
return {
|
|
95
|
+
content: [
|
|
96
|
+
{
|
|
97
|
+
type: 'text',
|
|
98
|
+
text: result.summary,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
type: 'text',
|
|
102
|
+
text: JSON.stringify(result.scripts, null, 2),
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
structuredContent: result,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// mode === 'methods'
|
|
110
|
+
return {
|
|
111
|
+
content: [
|
|
112
|
+
{
|
|
113
|
+
type: 'text',
|
|
114
|
+
text: result.summary,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
type: 'text',
|
|
118
|
+
text: JSON.stringify(result.tools, null, 2),
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
structuredContent: result,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
113
124
|
});
|
|
114
125
|
async function main() {
|
|
115
|
-
//
|
|
126
|
+
// Probe cluster connectivity before starting the server
|
|
127
|
+
// This ensures we fail fast if the cluster is not reachable
|
|
128
|
+
logger.info('Probing Kubernetes cluster connectivity...');
|
|
129
|
+
try {
|
|
130
|
+
await probeClusterConnectivity();
|
|
131
|
+
logger.info('Kubernetes cluster is reachable');
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
135
|
+
logger.error(`Failed to connect to Kubernetes cluster: ${message}`);
|
|
136
|
+
throw new Error(`Kubernetes cluster is not accessible: ${message}`);
|
|
137
|
+
}
|
|
138
|
+
// Ensure ~/.prodisco/scripts/cache/ directory exists (using async API for consistency)
|
|
116
139
|
const scriptsDir = path.join(os.homedir(), '.prodisco', 'scripts', 'cache');
|
|
117
|
-
fs.
|
|
118
|
-
|
|
140
|
+
await fs.promises.mkdir(scriptsDir, { recursive: true });
|
|
141
|
+
logger.info(`Scripts directory: ${scriptsDir}`);
|
|
142
|
+
// Pre-warm the Orama search index to avoid delay on first search
|
|
143
|
+
await warmupSearchIndex();
|
|
119
144
|
const transport = new StdioServerTransport();
|
|
120
145
|
await server.connect(transport);
|
|
121
|
-
|
|
146
|
+
logger.info('Kubernetes MCP server ready on stdio');
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Graceful shutdown handler.
|
|
150
|
+
* Stops the script watcher and cleans up resources.
|
|
151
|
+
*/
|
|
152
|
+
async function shutdown(signal) {
|
|
153
|
+
logger.info(`Received ${signal}, shutting down gracefully...`);
|
|
154
|
+
try {
|
|
155
|
+
await shutdownSearchIndex();
|
|
156
|
+
logger.info('Shutdown complete');
|
|
157
|
+
process.exit(0);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
logger.error('Error during shutdown', error);
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
122
163
|
}
|
|
164
|
+
// Register shutdown handlers
|
|
165
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
166
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
123
167
|
main().catch((error) => {
|
|
124
|
-
|
|
168
|
+
logger.error('Fatal error starting MCP server', error);
|
|
125
169
|
process.exit(1);
|
|
126
170
|
});
|
|
127
171
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAyB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiTools.d.ts","sourceRoot":"","sources":["../../../src/tools/api/apiTools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,QAuJjD"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal API Tools for openapi-fetch clients
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { getApiClientConfig, getPaths } from '../../util/apiClient.js';
|
|
6
|
+
export function registerApiTools(server) {
|
|
7
|
+
const config = getApiClientConfig();
|
|
8
|
+
if (!config) {
|
|
9
|
+
server.tool('api_setup', 'How to set up an API client', {}, async () => ({
|
|
10
|
+
content: [{
|
|
11
|
+
type: 'text',
|
|
12
|
+
text: `# API Client Setup
|
|
13
|
+
|
|
14
|
+
1. Generate a client:
|
|
15
|
+
\`\`\`bash
|
|
16
|
+
./scripts/generate-openapi-client.sh --url <openapi-spec-url> --name <name>
|
|
17
|
+
\`\`\`
|
|
18
|
+
|
|
19
|
+
2. Set env var:
|
|
20
|
+
\`\`\`bash
|
|
21
|
+
export PRODISCO_API_CLIENT="~/.prodisco/generated/<name>-client"
|
|
22
|
+
export <NAME>_TOKEN="your-token"
|
|
23
|
+
\`\`\`
|
|
24
|
+
|
|
25
|
+
3. Restart the MCP server
|
|
26
|
+
`,
|
|
27
|
+
}],
|
|
28
|
+
}));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
// api_info
|
|
32
|
+
server.tool('api_info', `Show info about the configured API client (${config.name})`, {}, async () => ({
|
|
33
|
+
content: [{
|
|
34
|
+
type: 'text',
|
|
35
|
+
text: `# API Client: ${config.name}
|
|
36
|
+
|
|
37
|
+
**Path:** ${config.clientPath}
|
|
38
|
+
**Base URL:** ${config.metadata.baseUrl || '(not set)'}
|
|
39
|
+
**Auth Env Var:** ${config.metadata.envVar || `${config.name.toUpperCase()}_TOKEN`}
|
|
40
|
+
`,
|
|
41
|
+
}],
|
|
42
|
+
}));
|
|
43
|
+
// api_discover
|
|
44
|
+
server.tool('api_discover', `Discover available API paths for ${config.name}. Use filter to narrow results.`, {
|
|
45
|
+
filter: z.string().optional().describe('Filter paths (case-insensitive)'),
|
|
46
|
+
limit: z.number().optional().default(50).describe('Max results'),
|
|
47
|
+
}, async ({ filter, limit }) => {
|
|
48
|
+
const paths = getPaths();
|
|
49
|
+
const filtered = paths
|
|
50
|
+
.filter((p) => !filter || p.path.toLowerCase().includes(filter.toLowerCase()))
|
|
51
|
+
.slice(0, limit || 50);
|
|
52
|
+
if (filtered.length === 0) {
|
|
53
|
+
return { content: [{ type: 'text', text: `No paths found${filter ? ` matching "${filter}"` : ''}.` }] };
|
|
54
|
+
}
|
|
55
|
+
const formatted = filtered.map((p) => `- **${p.methods.join(', ').toUpperCase()}** \`${p.path}\``).join('\n');
|
|
56
|
+
return {
|
|
57
|
+
content: [{
|
|
58
|
+
type: 'text',
|
|
59
|
+
text: `# API Paths${filter ? ` (matching "${filter}")` : ''}
|
|
60
|
+
|
|
61
|
+
${formatted}
|
|
62
|
+
|
|
63
|
+
Use \`api_call\` to call an endpoint:
|
|
64
|
+
\`\`\`
|
|
65
|
+
method: "GET"
|
|
66
|
+
path: "/repos/{owner}/{repo}"
|
|
67
|
+
params: { "path": { "owner": "kubernetes", "repo": "kubernetes" } }
|
|
68
|
+
\`\`\`
|
|
69
|
+
`,
|
|
70
|
+
}],
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
// api_call
|
|
74
|
+
server.tool('api_call', `Call an API endpoint on ${config.name}`, {
|
|
75
|
+
method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']).describe('HTTP method'),
|
|
76
|
+
path: z.string().describe('API path (e.g., "/repos/{owner}/{repo}")'),
|
|
77
|
+
params: z.record(z.any()).optional().describe('{ path: {...}, query: {...}, body: {...} }'),
|
|
78
|
+
}, async ({ method, path, params }) => {
|
|
79
|
+
try {
|
|
80
|
+
const clientPath = `file://${config.distPath}/index.js`;
|
|
81
|
+
const { client } = await import(clientPath);
|
|
82
|
+
const fn = client[method];
|
|
83
|
+
if (typeof fn !== 'function') {
|
|
84
|
+
return { content: [{ type: 'text', text: `Method ${method} not supported.` }] };
|
|
85
|
+
}
|
|
86
|
+
const { data, error, response } = await fn(path, params || {});
|
|
87
|
+
if (error) {
|
|
88
|
+
return {
|
|
89
|
+
content: [{
|
|
90
|
+
type: 'text',
|
|
91
|
+
text: `# Error: ${method} ${path}
|
|
92
|
+
|
|
93
|
+
**Status:** ${response?.status || 'unknown'}
|
|
94
|
+
\`\`\`json
|
|
95
|
+
${JSON.stringify(error, null, 2)}
|
|
96
|
+
\`\`\`
|
|
97
|
+
`,
|
|
98
|
+
}],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
let resultText = JSON.stringify(data, null, 2);
|
|
102
|
+
if (resultText.length > 50000) {
|
|
103
|
+
resultText = resultText.substring(0, 50000) + '\n... (truncated)';
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
content: [{
|
|
107
|
+
type: 'text',
|
|
108
|
+
text: `# ${method} ${path}
|
|
109
|
+
|
|
110
|
+
\`\`\`json
|
|
111
|
+
${resultText}
|
|
112
|
+
\`\`\`
|
|
113
|
+
`,
|
|
114
|
+
}],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
return {
|
|
119
|
+
content: [{
|
|
120
|
+
type: 'text',
|
|
121
|
+
text: `# Error: ${method} ${path}
|
|
122
|
+
|
|
123
|
+
${err.message}
|
|
124
|
+
|
|
125
|
+
**Hint:** Make sure ${config.metadata.envVar || `${config.name.toUpperCase()}_TOKEN`} is set.
|
|
126
|
+
`,
|
|
127
|
+
}],
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=apiTools.js.map
|