@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.
Files changed (37) hide show
  1. package/README.md +63 -35
  2. package/dist/kube/client.d.ts +6 -0
  3. package/dist/kube/client.d.ts.map +1 -1
  4. package/dist/kube/client.js +11 -0
  5. package/dist/kube/client.js.map +1 -1
  6. package/dist/kube/client.test.d.ts +2 -0
  7. package/dist/kube/client.test.d.ts.map +1 -0
  8. package/dist/kube/client.test.js +59 -0
  9. package/dist/kube/client.test.js.map +1 -0
  10. package/dist/server.js +94 -50
  11. package/dist/server.js.map +1 -1
  12. package/dist/tools/api/apiTools.d.ts +6 -0
  13. package/dist/tools/api/apiTools.d.ts.map +1 -0
  14. package/dist/tools/api/apiTools.js +132 -0
  15. package/dist/tools/api/apiTools.js.map +1 -0
  16. package/dist/tools/kubernetes/metadata.d.ts +67 -27
  17. package/dist/tools/kubernetes/metadata.d.ts.map +1 -1
  18. package/dist/tools/kubernetes/metadata.js +2 -7
  19. package/dist/tools/kubernetes/metadata.js.map +1 -1
  20. package/dist/tools/kubernetes/searchTools.d.ts +180 -5
  21. package/dist/tools/kubernetes/searchTools.d.ts.map +1 -1
  22. package/dist/tools/kubernetes/searchTools.js +1365 -261
  23. package/dist/tools/kubernetes/searchTools.js.map +1 -1
  24. package/dist/util/apiClient.d.ts +20 -0
  25. package/dist/util/apiClient.d.ts.map +1 -0
  26. package/dist/util/apiClient.js +90 -0
  27. package/dist/util/apiClient.js.map +1 -0
  28. package/dist/util/k8sClient.d.ts +38 -0
  29. package/dist/util/k8sClient.d.ts.map +1 -0
  30. package/dist/util/k8sClient.js +85 -0
  31. package/dist/util/k8sClient.js.map +1 -0
  32. package/dist/util/logger.d.ts +26 -0
  33. package/dist/util/logger.d.ts.map +1 -0
  34. package/dist/util/logger.js +62 -0
  35. package/dist/util/logger.js.map +1 -0
  36. package/dist/util/summary.d.ts +14 -14
  37. package/package.json +3 -1
package/README.md CHANGED
@@ -1,17 +1,19 @@
1
- # ProDisco (Progressive Disclosure Kuberentes MCP Server)
1
+ # ProDisco (Progressive Disclosure Kubernetes MCP Server)
2
2
 
3
- ProDisco gives MCP agents Kubernetes access that exactly follows Anthropic’s [Progressive Disclosure](https://www.anthropic.com/engineering/code-execution-with-mcp) pattern: the server exposes TypeScript modules, agents discover them through the filesystem, write code, and only the final console output returns to the chat.
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, as they do with ProDisco, 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)).
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
- In practice that means:
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
- ProDisco ships with this layout out of the box, so any Claude Code or MCP-enabled agent can immediately adopt the progressive-disclosure workflow.
11
+
12
+ ---
13
+
14
+ ## Demo
15
+
16
+ ![Demo](docs/demo.gif)
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 two main tools for agents to discover and interact with the Kubernetes API:
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
- ### 1. kubernetes.searchTools
65
+ ### kubernetes.searchTools
62
66
 
63
- Find Kubernetes API methods by resource type and action.
67
+ Find Kubernetes API methods, get type definitions, or search cached scripts.
64
68
 
65
69
  **Input:**
66
70
  ```typescript
67
71
  {
68
- resourceType: string; // e.g., "Pod", "Deployment", "Service"
69
- action?: string; // e.g., "list", "read", "create", "delete", "patch", "replace", "connect"
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?: { // Optional: filter out methods
72
- actions?: string[]; // e.g., ["delete", "create"]
73
- apiClasses?: string[]; // e.g., ["CoreV1Api"]
79
+ exclude?: { // Optional: filter out methods
80
+ actions?: string[]; // e.g., ["delete", "create"]
81
+ apiClasses?: string[]; // e.g., ["CoreV1Api"]
74
82
  };
75
- limit?: number; // Max results (default: 10, max: 50)
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
- **Example Queries:**
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
- ### 2. kubernetes.getTypeDefinition
115
+ **Types Mode Examples:**
116
+ ```typescript
117
+ // Get V1Pod type definition
118
+ { mode: "types", types: ["V1Pod"] }
101
119
 
102
- Get detailed TypeScript type definitions for Kubernetes types.
120
+ // Get multiple types
121
+ { mode: "types", types: ["V1Pod", "V1Deployment", "V1Service"] }
103
122
 
104
- **Input:**
105
- ```typescript
106
- {
107
- types: string[]; // Type names or property paths
108
- // Examples: ["V1Pod", "V1Deployment.spec", "V1Pod.spec.containers"]
109
- depth?: number; // Nested type depth (default: 1, max: 2)
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
- **Dot Notation Support:**
114
- Navigate directly to nested types:
115
- - `V1Deployment.spec` Returns `V1DeploymentSpec` type
116
- - `V1Pod.spec.containers` Returns `V1Container` type (array element)
117
- - `V1Pod.status.conditions` → Returns `V1PodCondition` type
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
 
@@ -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"}
@@ -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 };
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=client.test.d.ts.map
@@ -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 includes a "paths" object with: ' +
23
- '(1) scriptsDirectory: where to write helper scripts (e.g., ~/.prodisco/scripts/cache/), ' +
24
- '(2) packageDirectory: where dependencies are installed (use for imports). ' +
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
- console.error(`📁 Exposed ${GENERATED_DIR} as MCP resources`);
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 Tool Search',
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
- return {
79
- content: [
80
- {
81
- type: 'text',
82
- text: result.summary,
83
- },
84
- {
85
- type: 'text',
86
- text: JSON.stringify(result.tools, null, 2),
87
- },
88
- ],
89
- structuredContent: result,
90
- };
91
- });
92
- // Register kubernetes.getTypeDefinition helper as an exposed tool.
93
- server.registerTool(getTypeDefinitionTool.name, {
94
- title: 'Kubernetes Type Definition',
95
- description: getTypeDefinitionTool.description,
96
- inputSchema: getTypeDefinitionTool.schema,
97
- }, async (args) => {
98
- const parsedArgs = await getTypeDefinitionTool.schema.parseAsync(args);
99
- const result = await getTypeDefinitionTool.execute(parsedArgs);
100
- return {
101
- content: [
102
- {
103
- type: 'text',
104
- text: result.summary,
105
- },
106
- {
107
- type: 'text',
108
- text: JSON.stringify(result.types, null, 2),
109
- },
110
- ],
111
- structuredContent: result,
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
- // Ensure ~/.prodisco/scripts/cache/ directory exists
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.mkdirSync(scriptsDir, { recursive: true });
118
- console.error(`📝 Scripts directory: ${scriptsDir}`);
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
- console.error('Kubernetes MCP server ready on stdio');
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
- console.error('Fatal error starting MCP server', error);
168
+ logger.error('Fatal error starting MCP server', error);
125
169
  process.exit(1);
126
170
  });
127
171
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Universal API Tools for openapi-fetch clients
3
+ */
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ export declare function registerApiTools(server: McpServer): void;
6
+ //# sourceMappingURL=apiTools.d.ts.map
@@ -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