@prodisco/k8s-mcp 0.1.8 → 0.1.10
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 +342 -198
- package/dist/codegen/toolMapping.js +12 -12
- package/dist/codegen/toolMapping.js.map +1 -1
- package/dist/config/libraries.d.ts +28 -0
- package/dist/config/libraries.d.ts.map +1 -0
- package/dist/config/libraries.js +116 -0
- package/dist/config/libraries.js.map +1 -0
- package/dist/resources/filesystem.d.ts +1 -1
- package/dist/resources/filesystem.d.ts.map +1 -1
- package/dist/resources/filesystem.js +1 -1
- package/dist/resources/filesystem.js.map +1 -1
- package/dist/server.js +438 -217
- 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/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/kubernetes/metadata.d.ts +63 -3
- package/dist/tools/kubernetes/metadata.d.ts.map +1 -1
- package/dist/tools/kubernetes/searchTools-old.d.ts +35 -0
- package/dist/tools/kubernetes/searchTools-old.d.ts.map +1 -0
- package/dist/tools/kubernetes/searchTools-old.js +414 -0
- package/dist/tools/kubernetes/searchTools-old.js.map +1 -0
- package/dist/tools/kubernetes/searchTools-v2.d.ts +35 -0
- package/dist/tools/kubernetes/searchTools-v2.d.ts.map +1 -0
- package/dist/tools/kubernetes/searchTools-v2.js +269 -0
- package/dist/tools/kubernetes/searchTools-v2.js.map +1 -0
- package/dist/tools/kubernetes/searchTools.d.ts +68 -4
- package/dist/tools/kubernetes/searchTools.d.ts.map +1 -1
- package/dist/tools/kubernetes/searchTools.js +459 -2
- package/dist/tools/kubernetes/searchTools.js.map +1 -1
- package/dist/tools/kubernetes/typeDefinitions.d.ts +24 -0
- package/dist/tools/kubernetes/typeDefinitions.d.ts.map +1 -0
- package/dist/tools/kubernetes/typeDefinitions.js +518 -0
- package/dist/tools/kubernetes/typeDefinitions.js.map +1 -0
- package/dist/tools/prodisco/index.d.ts +5 -0
- package/dist/tools/prodisco/index.d.ts.map +1 -0
- package/dist/tools/prodisco/index.js +6 -0
- package/dist/tools/prodisco/index.js.map +1 -0
- package/dist/tools/prodisco/lspTools.d.ts +17 -0
- package/dist/tools/prodisco/lspTools.d.ts.map +1 -0
- package/dist/tools/prodisco/lspTools.js +312 -0
- package/dist/tools/prodisco/lspTools.js.map +1 -0
- package/dist/tools/prodisco/metadata.d.ts +337 -0
- package/dist/tools/prodisco/metadata.d.ts.map +1 -0
- package/dist/tools/prodisco/metadata.js +21 -0
- package/dist/tools/prodisco/metadata.js.map +1 -0
- package/dist/tools/prodisco/runSandbox.d.ts +249 -0
- package/dist/tools/prodisco/runSandbox.d.ts.map +1 -0
- package/dist/tools/prodisco/runSandbox.js +517 -0
- package/dist/tools/prodisco/runSandbox.js.map +1 -0
- package/dist/tools/prodisco/searchTools.d.ts +294 -0
- package/dist/tools/prodisco/searchTools.d.ts.map +1 -0
- package/dist/tools/prodisco/searchTools.js +411 -0
- package/dist/tools/prodisco/searchTools.js.map +1 -0
- 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/summary.d.ts +20 -20
- package/package.json +14 -3
package/README.md
CHANGED
|
@@ -1,26 +1,52 @@
|
|
|
1
|
-
# ProDisco (Progressive Disclosure
|
|
1
|
+
# ProDisco (Progressive Disclosure MCP Server)
|
|
2
2
|
|
|
3
|
-
ProDisco
|
|
3
|
+
ProDisco is a **progressive-disclosure MCP server framework**: you provide a list of TypeScript libraries, ProDisco indexes their APIs for discovery, and a sandbox executes code that uses only those libraries. It follows Anthropic's [Progressive Disclosure](https://www.anthropic.com/engineering/code-execution-with-mcp) pattern: the MCP server exposes search tools which surface library APIs, agents discover them to write code, execute it in a sandbox, and only the final console output returns to the agent.
|
|
4
4
|
|
|
5
|
-
**
|
|
6
|
-
- **kubernetes.searchTools** - Discover API methods, type definitions, cached scripts, and Prometheus methods
|
|
7
|
-
- **kubernetes.runSandbox** - Execute TypeScript code in a sandboxed VM environment
|
|
5
|
+
**Kubernetes/observability is just one example** configuration (see `examples/`). You can equally build an MCP server around AWS/GCP SDKs, Postgres clients, internal TypeScript SDKs, etc.
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
> Note: ProDisco prefers indexing APIs from TypeScript declaration files (`.d.ts`). If a library ships no `.d.ts`, ProDisco can fall back to indexing **ESM JavaScript** exports (best-effort; types default to `any`). CommonJS-only JavaScript packages without typings are not supported.
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
Demo use-cases (optional):
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
11
|
+
- **Kubernetes access** via `@kubernetes/client-node`
|
|
12
|
+
- **Prometheus metrics** via `@prodisco/prometheus-client`
|
|
13
|
+
- **Loki logs** via `@prodisco/loki-client`
|
|
14
|
+
- **Analytics** via `simple-statistics`
|
|
17
15
|
|
|
16
|
+
[](https://www.youtube.com/watch?v=W-DyrsGRJeQ)
|
|
18
17
|
|
|
19
18
|
---
|
|
20
19
|
|
|
21
|
-
##
|
|
20
|
+
## Table of Contents
|
|
21
|
+
|
|
22
|
+
- [Why Progressive Disclosure?](#why-progressive-disclosure)
|
|
23
|
+
- [Quick Start](#quick-start)
|
|
24
|
+
- [Add to Claude Code](#add-to-claude-code)
|
|
25
|
+
- [Environment Variables](#environment-variables)
|
|
26
|
+
- [Development Setup](#development-setup)
|
|
27
|
+
- [HTTP Transport](#http-transport)
|
|
28
|
+
- [Available Tools](#available-tools)
|
|
29
|
+
- [prodisco.searchTools](#prodiscosearchtools)
|
|
30
|
+
- [prodisco.runSandbox](#prodiscorunsandbox)
|
|
31
|
+
- [Advanced Analytics](#advanced-analytics)
|
|
32
|
+
- [Advanced Deployment](#advanced-deployment)
|
|
33
|
+
- [Container Isolation](#container-isolation)
|
|
34
|
+
- [Transport Security (TLS/mTLS)](#transport-security-tlsmtls)
|
|
35
|
+
- [Testing](#testing)
|
|
36
|
+
- [Additional Documentation](#additional-documentation)
|
|
37
|
+
- [License](#license)
|
|
22
38
|
|
|
23
|
-
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Why Progressive Disclosure?
|
|
42
|
+
|
|
43
|
+
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)).
|
|
44
|
+
|
|
45
|
+
ProDisco goes a step further: instead of exposing custom TypeScript modules, it provides a structured parameter search tool that dynamically extracts methods from upstream libraries using TypeScript AST parsing. This means:
|
|
46
|
+
|
|
47
|
+
- **Zero maintenance** - Methods are extracted directly from library `.d.ts` files
|
|
48
|
+
- **Always current** - Upgrading a dependency automatically exposes new methods
|
|
49
|
+
- **Type-safe** - Full parameter types and return types included
|
|
24
50
|
|
|
25
51
|
---
|
|
26
52
|
|
|
@@ -28,34 +54,30 @@ ProDisco goes a step further: instead of exposing custom TypeScript modules, it
|
|
|
28
54
|
|
|
29
55
|
### Add to Claude Code
|
|
30
56
|
|
|
31
|
-
Add ProDisco to Claude Code:
|
|
32
|
-
|
|
33
57
|
```bash
|
|
34
|
-
|
|
35
|
-
|
|
58
|
+
npm install
|
|
59
|
+
npm run build --workspaces
|
|
60
|
+
npm run build
|
|
36
61
|
|
|
62
|
+
# Example configs live in ./examples (see examples/README.md)
|
|
37
63
|
# Then add the MCP server
|
|
38
|
-
claude mcp add
|
|
64
|
+
claude mcp add --transport stdio prodisco -- node dist/server.js --config examples/prodisco.postgres.yaml
|
|
39
65
|
```
|
|
40
66
|
|
|
41
|
-
**
|
|
42
|
-
```bash
|
|
43
|
-
export KUBECONFIG="${HOME}/.kube/config"
|
|
44
|
-
export PROMETHEUS_URL="http://localhost:9090"
|
|
45
|
-
claude mcp add ProDisco -- npx -y @prodisco/k8s-mcp
|
|
46
|
-
```
|
|
67
|
+
**Remove if needed:**
|
|
47
68
|
|
|
48
|
-
Remove if needed:
|
|
49
69
|
```bash
|
|
50
|
-
claude mcp remove
|
|
70
|
+
claude mcp remove prodisco
|
|
51
71
|
```
|
|
52
72
|
|
|
53
|
-
|
|
73
|
+
### Environment Variables
|
|
74
|
+
|
|
54
75
|
| Variable | Required | Description |
|
|
55
76
|
|----------|----------|-------------|
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
58
|
-
| `PROMETHEUS_URL` | No | Prometheus server URL
|
|
77
|
+
| `PRODISCO_CONFIG_PATH` | No | Path to the libraries config file (same as `--config`) |
|
|
78
|
+
| `KUBECONFIG` | No | (If using `@kubernetes/client-node`) Path to kubeconfig (defaults to `~/.kube/config`) |
|
|
79
|
+
| `PROMETHEUS_URL` | No | (If using `@prodisco/prometheus-client`) Prometheus server URL |
|
|
80
|
+
| `LOKI_URL` | No | (If using `@prodisco/loki-client`) Loki server URL |
|
|
59
81
|
|
|
60
82
|
> **Important:** Export environment variables before running `claude mcp add`. The `--env` flag may not reliably pass variables to the MCP server process.
|
|
61
83
|
|
|
@@ -65,41 +87,6 @@ claude mcp remove ProDisco
|
|
|
65
87
|
> ```
|
|
66
88
|
> Then set `PROMETHEUS_URL="http://localhost:9090"`
|
|
67
89
|
|
|
68
|
-
### Container Isolation (Advanced)
|
|
69
|
-
|
|
70
|
-
For stronger isolation, you can run the sandbox server in a Kubernetes cluster and connect to it via TCP instead of using the local subprocess.
|
|
71
|
-
|
|
72
|
-
**1. Deploy the sandbox server to your cluster:**
|
|
73
|
-
```bash
|
|
74
|
-
# Build and load the image (for kind clusters)
|
|
75
|
-
docker build -f packages/sandbox-server/Dockerfile -t prodisco/sandbox-server:latest .
|
|
76
|
-
kind load docker-image prodisco/sandbox-server:latest
|
|
77
|
-
|
|
78
|
-
# Deploy
|
|
79
|
-
kubectl apply -f packages/sandbox-server/k8s/deployment.yaml
|
|
80
|
-
|
|
81
|
-
# Port-forward to access locally
|
|
82
|
-
kubectl -n prodisco port-forward service/sandbox-server 50051:50051
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
**2. Configure the MCP server to use TCP transport:**
|
|
86
|
-
```bash
|
|
87
|
-
export KUBECONFIG="${HOME}/.kube/config"
|
|
88
|
-
export SANDBOX_USE_TCP=true
|
|
89
|
-
export SANDBOX_TCP_HOST=localhost
|
|
90
|
-
export SANDBOX_TCP_PORT=50051
|
|
91
|
-
claude mcp add ProDisco -- npx -y @prodisco/k8s-mcp
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**Sandbox transport environment variables:**
|
|
95
|
-
| Variable | Default | Description |
|
|
96
|
-
|----------|---------|-------------|
|
|
97
|
-
| `SANDBOX_USE_TCP` | `false` | Use TCP instead of local subprocess |
|
|
98
|
-
| `SANDBOX_TCP_HOST` | `localhost` | Sandbox server host |
|
|
99
|
-
| `SANDBOX_TCP_PORT` | `50051` | Sandbox server port |
|
|
100
|
-
|
|
101
|
-
See [docs/grpc-sandbox-architecture.md](docs/grpc-sandbox-architecture.md) for full architecture details.
|
|
102
|
-
|
|
103
90
|
### Development Setup
|
|
104
91
|
|
|
105
92
|
For local development:
|
|
@@ -113,76 +100,211 @@ claude mcp add --transport stdio prodisco -- node dist/server.js
|
|
|
113
100
|
claude mcp remove prodisco # remove when you're done
|
|
114
101
|
```
|
|
115
102
|
|
|
116
|
-
|
|
103
|
+
**Startup Options:**
|
|
117
104
|
|
|
118
105
|
| Flag | Description |
|
|
119
106
|
|------|-------------|
|
|
120
107
|
| `--clear-cache` | Clear the scripts cache before starting |
|
|
108
|
+
| `--config <path>` | Path to YAML/JSON config listing libraries to index/allow |
|
|
109
|
+
| `--transport <mode>` | Transport mode: `stdio` (default) or `http` |
|
|
110
|
+
| `--host <host>` | HTTP host to bind to (default: `127.0.0.1`) |
|
|
111
|
+
| `--port <port>` | HTTP port (default: `3000`, implies `--transport http`) |
|
|
121
112
|
|
|
122
|
-
Example:
|
|
123
113
|
```bash
|
|
124
114
|
node dist/server.js --clear-cache
|
|
125
115
|
```
|
|
126
116
|
|
|
117
|
+
### Dynamic Libraries Configuration
|
|
118
|
+
|
|
119
|
+
ProDisco can be started with a config file that determines which npm packages are:
|
|
120
|
+
|
|
121
|
+
- **Indexed** by `prodisco.searchTools`
|
|
122
|
+
- **Allowed** in the sandbox via `require()` (kept in lockstep with indexing)
|
|
123
|
+
|
|
124
|
+
Example `prodisco.config.yaml`:
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
libraries:
|
|
128
|
+
- name: "@kubernetes/client-node"
|
|
129
|
+
description: "Kubernetes API client"
|
|
130
|
+
- name: "@prodisco/prometheus-client"
|
|
131
|
+
description: "Prometheus queries + metric discovery"
|
|
132
|
+
- name: "@prodisco/loki-client"
|
|
133
|
+
description: "Loki LogQL querying"
|
|
134
|
+
- name: "simple-statistics"
|
|
135
|
+
description: "Statistics helpers"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Start with a config file:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
node dist/server.js --config prodisco.config.yaml
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Missing packages are automatically installed into `.cache/deps` on startup.
|
|
145
|
+
|
|
146
|
+
Environment variables:
|
|
147
|
+
|
|
148
|
+
| Variable | Description |
|
|
149
|
+
|----------|-------------|
|
|
150
|
+
| `PRODISCO_CONFIG_PATH` | Path to YAML/JSON config listing libraries |
|
|
151
|
+
|
|
152
|
+
### Build Docker Images From Config
|
|
153
|
+
|
|
154
|
+
If you want images that already contain the configured libraries (for deploying MCP and sandbox separately), you can build them directly from the same config file:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
npm run docker:build:config -- --config prodisco.config.yaml
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
This builds:
|
|
161
|
+
- `prodisco/mcp-server:<configSha8>` using the root `Dockerfile`
|
|
162
|
+
- `prodisco/sandbox-server:<configSha8>` using `packages/sandbox-server/Dockerfile`
|
|
163
|
+
|
|
164
|
+
You can override image names/tags:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
npm run docker:build:config -- --config prodisco.config.yaml --tag dev --mcp-image myorg/prodisco-mcp --sandbox-image myorg/prodisco-sandbox
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### HTTP Transport
|
|
171
|
+
|
|
172
|
+
ProDisco supports HTTP transport for network-based MCP connections, enabling remote access and containerized deployments.
|
|
173
|
+
|
|
174
|
+
**Start in HTTP mode:**
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# HTTP mode on default port (3000)
|
|
178
|
+
node dist/server.js --transport http
|
|
179
|
+
|
|
180
|
+
# HTTP mode on custom port
|
|
181
|
+
node dist/server.js --port 8080
|
|
182
|
+
|
|
183
|
+
# HTTP mode on all interfaces (for network access)
|
|
184
|
+
node dist/server.js --host 0.0.0.0 --port 3000
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Environment Variables:**
|
|
188
|
+
|
|
189
|
+
| Variable | Default | Description |
|
|
190
|
+
|----------|---------|-------------|
|
|
191
|
+
| `MCP_TRANSPORT` | `stdio` | Transport mode (`stdio` or `http`) |
|
|
192
|
+
| `MCP_HOST` | `127.0.0.1` | HTTP host to bind to |
|
|
193
|
+
| `MCP_PORT` | `3000` | HTTP port to listen on |
|
|
194
|
+
|
|
195
|
+
**HTTP Endpoints:**
|
|
196
|
+
|
|
197
|
+
| Endpoint | Method | Description |
|
|
198
|
+
|----------|--------|-------------|
|
|
199
|
+
| `/health` | GET | Health check, returns `{"status":"ok"}` |
|
|
200
|
+
| `/mcp` | POST | MCP JSON-RPC endpoint (Streamable HTTP) |
|
|
201
|
+
|
|
202
|
+
**Example: Connect with curl**
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# Health check
|
|
206
|
+
curl http://localhost:3000/health
|
|
207
|
+
|
|
208
|
+
# Initialize MCP session
|
|
209
|
+
curl -X POST http://localhost:3000/mcp \
|
|
210
|
+
-H "Content-Type: application/json" \
|
|
211
|
+
-H "Accept: application/json, text/event-stream" \
|
|
212
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}'
|
|
213
|
+
|
|
214
|
+
# Use session ID from response header for subsequent requests
|
|
215
|
+
curl -X POST http://localhost:3000/mcp \
|
|
216
|
+
-H "Content-Type: application/json" \
|
|
217
|
+
-H "mcp-session-id: <session-id-from-init>" \
|
|
218
|
+
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
The HTTP transport uses the MCP SDK's `StreamableHTTPServerTransport`, which supports session management via `mcp-session-id` headers and Server-Sent Events (SSE) for streaming responses.
|
|
222
|
+
|
|
127
223
|
---
|
|
128
224
|
|
|
129
225
|
## Available Tools
|
|
130
226
|
|
|
131
227
|
ProDisco exposes two tools:
|
|
132
228
|
|
|
133
|
-
###
|
|
229
|
+
### prodisco.searchTools
|
|
230
|
+
|
|
231
|
+
Search and browse extracted API documentation for your **startup-configured TypeScript libraries** (from `.d.ts`). Use it to discover the correct method/type/function signatures **before** calling `prodisco.runSandbox`.
|
|
232
|
+
|
|
233
|
+
**Document Types:**
|
|
234
|
+
|
|
235
|
+
| Type | Description |
|
|
236
|
+
|------|-------------|
|
|
237
|
+
| `method` | Class methods / instance APIs extracted from configured libraries |
|
|
238
|
+
| `type` | TypeScript types (interfaces/classes/enums/type aliases) |
|
|
239
|
+
| `function` | Standalone exported functions |
|
|
240
|
+
| `script` | Cached sandbox scripts |
|
|
241
|
+
| `all` | Search everything above (default) |
|
|
242
|
+
|
|
243
|
+
**Examples:**
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
// Search broadly by name (methods/types/functions/scripts)
|
|
247
|
+
// Replace the placeholders with terms relevant to your configured libraries.
|
|
248
|
+
{ methodName: "<search-term>" }
|
|
249
|
+
|
|
250
|
+
// Filter by document type (methods/types/functions/scripts)
|
|
251
|
+
{ methodName: "<search-term>", documentType: "method" }
|
|
252
|
+
|
|
253
|
+
// Find Loki query methods
|
|
254
|
+
{ documentType: "method", library: "@prodisco/loki-client", category: "query" }
|
|
255
|
+
|
|
256
|
+
// Find Prometheus methods
|
|
257
|
+
{ methodName: "executeRange", library: "@prodisco/prometheus-client" }
|
|
258
|
+
|
|
259
|
+
// Find analytics functions
|
|
260
|
+
{ documentType: "function", library: "simple-statistics" }
|
|
261
|
+
|
|
262
|
+
// Search cached scripts
|
|
263
|
+
{ documentType: "script", methodName: "deployment" }
|
|
134
264
|
|
|
135
|
-
|
|
265
|
+
// Get TypeScript type definitions (classes/interfaces/enums/type aliases)
|
|
266
|
+
{ methodName: "<type-or-class-name>", documentType: "type" }
|
|
267
|
+
|
|
268
|
+
// Exclude certain categories/libraries
|
|
269
|
+
{ methodName: "query", exclude: { categories: ["delete"], libraries: ["some-library"] } }
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
For comprehensive documentation, see [docs/search-tools.md](docs/search-tools.md).
|
|
273
|
+
|
|
274
|
+
### prodisco.runSandbox
|
|
275
|
+
|
|
276
|
+
Execute TypeScript code in a sandboxed environment using the same **configured library allowlist** as `prodisco.searchTools`.
|
|
136
277
|
|
|
137
278
|
**Execution Modes:**
|
|
138
279
|
|
|
139
280
|
| Mode | Purpose | Key Parameters |
|
|
140
281
|
|------|---------|----------------|
|
|
141
|
-
| `execute` (default) | Blocking execution
|
|
282
|
+
| `execute` (default) | Blocking execution | `code` or `cached`, `timeout` |
|
|
142
283
|
| `stream` | Real-time output streaming | `code` or `cached`, `timeout` |
|
|
143
|
-
| `async` |
|
|
144
|
-
| `status` |
|
|
145
|
-
| `cancel` | Cancel
|
|
146
|
-
| `list` | List active
|
|
147
|
-
|
|
148
|
-
**Input:**
|
|
149
|
-
```typescript
|
|
150
|
-
{
|
|
151
|
-
// Mode selection (default: 'execute')
|
|
152
|
-
mode?: 'execute' | 'stream' | 'async' | 'status' | 'cancel' | 'list';
|
|
153
|
-
|
|
154
|
-
// Execute/Stream/Async mode parameters
|
|
155
|
-
code?: string; // TypeScript code to execute directly
|
|
156
|
-
cached?: string; // Name of a cached script to run (from searchTools results)
|
|
157
|
-
timeout?: number; // Execution timeout in ms (default: 30000, max: 120000)
|
|
158
|
-
|
|
159
|
-
// Status/Cancel mode parameters
|
|
160
|
-
executionId?: string; // ID from async mode response
|
|
161
|
-
wait?: boolean; // Long-poll until completion (status mode)
|
|
162
|
-
outputOffset?: number; // Offset for incremental reads (status mode)
|
|
163
|
-
|
|
164
|
-
// List mode parameters
|
|
165
|
-
states?: ('pending' | 'running' | 'completed' | 'failed' | 'cancelled' | 'timeout')[];
|
|
166
|
-
limit?: number; // Max results (default: 10)
|
|
167
|
-
includeCompletedWithinMs?: number; // Include recent completions
|
|
168
|
-
}
|
|
169
|
-
```
|
|
284
|
+
| `async` | Background execution | `code` or `cached`, `timeout` |
|
|
285
|
+
| `status` | Check async execution | `executionId`, `wait`, `outputOffset` |
|
|
286
|
+
| `cancel` | Cancel running execution | `executionId` |
|
|
287
|
+
| `list` | List active executions | `states`, `limit` |
|
|
170
288
|
|
|
171
289
|
**Sandbox Environment:**
|
|
172
|
-
|
|
173
|
-
- `kc` - Pre-configured KubeConfig instance
|
|
290
|
+
|
|
174
291
|
- `console` - Captured output (log, error, warn, info)
|
|
175
|
-
- `require()` -
|
|
176
|
-
- `process.env` - Environment variables
|
|
292
|
+
- `require()` - Restricted to configured npm packages (and their subpaths)
|
|
293
|
+
- `process.env` - Environment variables
|
|
177
294
|
|
|
178
295
|
**Examples:**
|
|
296
|
+
|
|
179
297
|
```typescript
|
|
180
|
-
// Execute
|
|
298
|
+
// Execute code (default mode)
|
|
181
299
|
{
|
|
182
300
|
code: `
|
|
301
|
+
const k8s = require("@kubernetes/client-node");
|
|
302
|
+
const kc = new k8s.KubeConfig();
|
|
303
|
+
kc.loadFromDefault();
|
|
304
|
+
|
|
183
305
|
const api = kc.makeApiClient(k8s.CoreV1Api);
|
|
184
|
-
const pods = await api.listNamespacedPod(
|
|
185
|
-
console.log(\`Found \${pods.items.length} pods\`);
|
|
306
|
+
const pods = await api.listNamespacedPod("default");
|
|
307
|
+
console.log(\`Found \${pods.body.items.length} pods\`);
|
|
186
308
|
`
|
|
187
309
|
}
|
|
188
310
|
|
|
@@ -194,147 +316,169 @@ Execute TypeScript code in a sandboxed environment for Kubernetes and Prometheus
|
|
|
194
316
|
|
|
195
317
|
// Async mode - start long-running task
|
|
196
318
|
{ mode: "async", code: "longRunningTask()" }
|
|
197
|
-
// Returns: { executionId: "abc-123", state: "running", ... }
|
|
198
319
|
|
|
199
|
-
//
|
|
320
|
+
// Check async execution status
|
|
200
321
|
{ mode: "status", executionId: "abc-123", wait: true }
|
|
201
322
|
|
|
202
|
-
// Cancel
|
|
323
|
+
// Cancel a running execution
|
|
203
324
|
{ mode: "cancel", executionId: "abc-123" }
|
|
204
325
|
|
|
205
|
-
//
|
|
206
|
-
{
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
326
|
+
// Query Prometheus metrics
|
|
327
|
+
{
|
|
328
|
+
code: `
|
|
329
|
+
const { PrometheusClient, MetricSearchEngine } = require('@prodisco/prometheus-client');
|
|
330
|
+
const client = new PrometheusClient({ endpoint: process.env.PROMETHEUS_URL });
|
|
331
|
+
|
|
332
|
+
// Discover metrics semantically
|
|
333
|
+
const search = new MetricSearchEngine(client);
|
|
334
|
+
const metrics = await search.search("memory usage");
|
|
335
|
+
console.log('Found metrics:', metrics.map(m => m.name));
|
|
336
|
+
|
|
337
|
+
// Execute PromQL query
|
|
338
|
+
const end = new Date();
|
|
339
|
+
const start = new Date(end.getTime() - 60 * 60 * 1000);
|
|
340
|
+
const result = await client.executeRange('node_memory_MemAvailable_bytes', { start, end, step: '1m' });
|
|
341
|
+
console.log(\`Got \${result.data.length} time series\`);
|
|
342
|
+
`
|
|
343
|
+
}
|
|
210
344
|
|
|
211
|
-
|
|
345
|
+
// Query Loki logs
|
|
346
|
+
{
|
|
347
|
+
code: `
|
|
348
|
+
const { LokiClient } = require('@prodisco/loki-client');
|
|
349
|
+
const client = new LokiClient({ baseUrl: process.env.LOKI_URL });
|
|
350
|
+
const result = await client.queryRange('{namespace="default"}', { since: '1h', limit: 100 });
|
|
351
|
+
result.logs.forEach(log => console.log(\`[\${log.timestamp.toISOString()}] \${log.line}\`));
|
|
352
|
+
`
|
|
353
|
+
}
|
|
354
|
+
```
|
|
212
355
|
|
|
213
|
-
|
|
214
|
-
|------|---------|---------|
|
|
215
|
-
| `methods` | Find Kubernetes API methods | `{ resourceType: "Pod", action: "list" }` |
|
|
216
|
-
| `types` | Get TypeScript type definitions | `{ mode: "types", types: ["V1Pod.spec"] }` |
|
|
217
|
-
| `scripts` | Search cached scripts | `{ mode: "scripts", searchTerm: "logs" }` |
|
|
218
|
-
| `prometheus` | Find Prometheus API methods | `{ mode: "prometheus", category: "query" }` |
|
|
356
|
+
For architecture details, see [docs/grpc-sandbox-architecture.md](docs/grpc-sandbox-architecture.md).
|
|
219
357
|
|
|
220
|
-
|
|
358
|
+
---
|
|
221
359
|
|
|
222
|
-
|
|
223
|
-
```typescript
|
|
224
|
-
{
|
|
225
|
-
// Mode selection
|
|
226
|
-
mode?: 'methods' | 'types' | 'scripts' | 'prometheus'; // default: 'methods'
|
|
360
|
+
## Advanced Analytics
|
|
227
361
|
|
|
228
|
-
|
|
229
|
-
resourceType?: string; // e.g., "Pod", "Deployment", "Service"
|
|
230
|
-
action?: string; // e.g., "list", "read", "create", "delete", "patch"
|
|
231
|
-
scope?: 'namespaced' | 'cluster' | 'all';
|
|
232
|
-
exclude?: { actions?: string[]; apiClasses?: string[] };
|
|
362
|
+
ProDisco goes beyond simple resource fetching - it provides **statistical analysis, machine learning, and signal processing** capabilities for deep cluster observability.
|
|
233
363
|
|
|
234
|
-
|
|
235
|
-
types?: string[]; // e.g., ["V1Pod", "V1Deployment.spec"]
|
|
236
|
-
depth?: number; // Nested type depth (1-2)
|
|
364
|
+
**Available Libraries:**
|
|
237
365
|
|
|
238
|
-
|
|
239
|
-
|
|
366
|
+
| Library | Purpose |
|
|
367
|
+
|---------|---------|
|
|
368
|
+
| `simple-statistics` | Mean, median, std dev, z-scores, percentiles, linear regression, correlation |
|
|
369
|
+
| `ml-regression` | Polynomial, exponential, and power regression for trend forecasting |
|
|
370
|
+
| `mathjs` | Matrix operations, linear algebra, symbolic math |
|
|
371
|
+
| `fft-js` | Fast Fourier Transform for detecting periodic patterns |
|
|
240
372
|
|
|
241
|
-
|
|
242
|
-
category?: 'query' | 'metadata' | 'alerts' | 'metrics' | 'all';
|
|
243
|
-
methodPattern?: string; // e.g., "query", "labels", "pod", "gpu"
|
|
373
|
+
**Example Prompts:**
|
|
244
374
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
375
|
+
| Use Case | Prompt |
|
|
376
|
+
|----------|--------|
|
|
377
|
+
| **Log Analysis** | "Query Loki for error logs from the nginx app in the last hour. Show me the most common error patterns." |
|
|
378
|
+
| **Cluster Health** | "Analyze CPU and memory usage across all pods. Calculate mean, median, standard deviation, and identify outliers using z-scores. Show pods above the 95th percentile." |
|
|
379
|
+
| **Memory Leaks** | "Check for memory leaks. Fetch memory usage over 2 hours and use linear regression to identify pods with increasing memory." |
|
|
380
|
+
| **Anomaly Detection** | "Analyze network traffic and detect anomalies. Find receive/transmit rates more than 2 standard deviations from normal." |
|
|
381
|
+
| **Correlation** | "Find correlations between CPU and memory usage. Tell me if high CPU correlates with high memory." |
|
|
382
|
+
| **Periodic Patterns** | "Use FFT analysis on node CPU to detect periodic patterns. Are there dominant frequencies suggesting scheduled jobs?" |
|
|
383
|
+
| **Capacity Planning** | "Analyze resource trends and use polynomial regression to forecast when we might hit resource limits." |
|
|
250
384
|
|
|
251
|
-
|
|
252
|
-
```typescript
|
|
253
|
-
// List all Pod-related methods
|
|
254
|
-
{ resourceType: "Pod" }
|
|
385
|
+
For detailed examples with code and output, see [docs/analytics.md](docs/analytics.md).
|
|
255
386
|
|
|
256
|
-
|
|
257
|
-
{ resourceType: "Pod", action: "list", scope: "namespaced" }
|
|
387
|
+
---
|
|
258
388
|
|
|
259
|
-
|
|
260
|
-
{ resourceType: "Deployment", action: "create" }
|
|
389
|
+
## Advanced Deployment
|
|
261
390
|
|
|
262
|
-
|
|
263
|
-
{ resourceType: "Pod", exclude: { actions: ["delete"] } }
|
|
391
|
+
### Container Isolation
|
|
264
392
|
|
|
265
|
-
|
|
266
|
-
{ resourceType: "Pod", exclude: { apiClasses: ["CoreV1Api"] } }
|
|
267
|
-
```
|
|
393
|
+
For stronger isolation, run the sandbox server in a Kubernetes cluster and connect via TCP.
|
|
268
394
|
|
|
269
|
-
**
|
|
270
|
-
```typescript
|
|
271
|
-
// Get V1Pod type definition
|
|
272
|
-
{ mode: "types", types: ["V1Pod"] }
|
|
395
|
+
**1. Deploy the sandbox server:**
|
|
273
396
|
|
|
274
|
-
|
|
275
|
-
|
|
397
|
+
```bash
|
|
398
|
+
# Build and load the image (for kind clusters)
|
|
399
|
+
docker build -f packages/sandbox-server/Dockerfile -t prodisco/sandbox-server:latest .
|
|
400
|
+
kind load docker-image prodisco/sandbox-server:latest
|
|
276
401
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
{ mode: "types", types: ["V1Pod.spec.containers"] } // Returns V1Container (array element)
|
|
280
|
-
{ mode: "types", types: ["V1Pod.status.conditions"] } // Returns V1PodCondition
|
|
402
|
+
# Deploy
|
|
403
|
+
kubectl apply -f packages/sandbox-server/k8s/deployment.yaml
|
|
281
404
|
|
|
282
|
-
|
|
283
|
-
|
|
405
|
+
# Port-forward to access locally
|
|
406
|
+
kubectl -n prodisco port-forward service/sandbox-server 50051:50051
|
|
284
407
|
```
|
|
285
408
|
|
|
286
|
-
**
|
|
287
|
-
```typescript
|
|
288
|
-
// List all cached scripts
|
|
289
|
-
{ mode: "scripts" }
|
|
409
|
+
**2. Configure the MCP server to use TCP:**
|
|
290
410
|
|
|
291
|
-
|
|
292
|
-
|
|
411
|
+
```bash
|
|
412
|
+
export KUBECONFIG="${HOME}/.kube/config"
|
|
413
|
+
export SANDBOX_USE_TCP=true
|
|
414
|
+
export SANDBOX_TCP_HOST=localhost
|
|
415
|
+
export SANDBOX_TCP_PORT=50051
|
|
416
|
+
claude mcp add --transport stdio prodisco -- node dist/server.js --config examples/prodisco.kubernetes.yaml
|
|
293
417
|
```
|
|
294
418
|
|
|
295
|
-
**
|
|
296
|
-
```typescript
|
|
297
|
-
// List all available methods
|
|
298
|
-
{ mode: "prometheus" }
|
|
419
|
+
**Transport Environment Variables:**
|
|
299
420
|
|
|
300
|
-
|
|
301
|
-
|
|
421
|
+
| Variable | Default | Description |
|
|
422
|
+
|----------|---------|-------------|
|
|
423
|
+
| `SANDBOX_USE_TCP` | `false` | Use TCP instead of local subprocess |
|
|
424
|
+
| `SANDBOX_TCP_HOST` | `localhost` | Sandbox server host |
|
|
425
|
+
| `SANDBOX_TCP_PORT` | `50051` | Sandbox server port |
|
|
302
426
|
|
|
303
|
-
|
|
304
|
-
{ mode: "prometheus", category: "metadata" }
|
|
427
|
+
### Transport Security (TLS/mTLS)
|
|
305
428
|
|
|
306
|
-
|
|
307
|
-
{ mode: "prometheus", methodPattern: "query" }
|
|
429
|
+
For production deployments, the sandbox server supports TLS and mutual TLS (mTLS):
|
|
308
430
|
|
|
309
|
-
|
|
310
|
-
|
|
431
|
+
| Mode | Description |
|
|
432
|
+
|------|-------------|
|
|
433
|
+
| `insecure` | No encryption (default, for local development) |
|
|
434
|
+
| `tls` | Server-side TLS (client verifies server identity) |
|
|
435
|
+
| `mtls` | Mutual TLS (both client and server authenticate) |
|
|
436
|
+
|
|
437
|
+
**Configuration:**
|
|
311
438
|
|
|
312
|
-
|
|
313
|
-
|
|
439
|
+
```bash
|
|
440
|
+
# Server-side TLS
|
|
441
|
+
export SANDBOX_TRANSPORT_MODE=tls
|
|
442
|
+
export SANDBOX_TLS_CERT_PATH=/path/to/server.crt
|
|
443
|
+
export SANDBOX_TLS_KEY_PATH=/path/to/server.key
|
|
444
|
+
|
|
445
|
+
# Client-side (MCP server)
|
|
446
|
+
export SANDBOX_TRANSPORT_MODE=tls
|
|
447
|
+
export SANDBOX_TLS_CA_PATH=/path/to/ca.crt
|
|
314
448
|
```
|
|
315
449
|
|
|
316
|
-
|
|
450
|
+
For Kubernetes deployments, use cert-manager to automate certificate management. See the [k8s/cert-manager](packages/sandbox-server/k8s/cert-manager) directory for ready-to-use manifests.
|
|
317
451
|
|
|
318
|
-
|
|
319
|
-
|----------|---------|----------|
|
|
320
|
-
| `query` | `instantQuery`, `rangeQuery` | Execute PromQL queries |
|
|
321
|
-
| `metadata` | `series`, `labelNames`, `labelValues`, `targets` | Explore metrics metadata |
|
|
322
|
-
| `alerts` | `rules`, `alerts`, `alertmanagers` | Access alerting information |
|
|
323
|
-
| `metrics` | (dynamic from cluster) | Discover actual metrics with descriptions |
|
|
452
|
+
For full architecture and security details, see [docs/grpc-sandbox-architecture.md](docs/grpc-sandbox-architecture.md).
|
|
324
453
|
|
|
325
454
|
---
|
|
326
455
|
|
|
327
|
-
##
|
|
456
|
+
## Testing
|
|
328
457
|
|
|
329
|
-
|
|
458
|
+
### Integration Tests
|
|
459
|
+
|
|
460
|
+
End-to-end testing with KIND cluster + Claude Agent SDK:
|
|
330
461
|
|
|
331
462
|
```bash
|
|
332
463
|
npm run test:integration
|
|
333
464
|
```
|
|
334
465
|
|
|
466
|
+
For detailed testing instructions, see [docs/integration-testing.md](docs/integration-testing.md).
|
|
467
|
+
|
|
468
|
+
---
|
|
469
|
+
|
|
470
|
+
## Additional Documentation
|
|
471
|
+
|
|
472
|
+
| Document | Description |
|
|
473
|
+
|----------|-------------|
|
|
474
|
+
| [docs/analytics.md](docs/analytics.md) | **Advanced analytics guide** - anomaly detection, forecasting, correlation, FFT analysis |
|
|
475
|
+
| [docs/search-tools.md](docs/search-tools.md) | Complete searchTools reference with examples and technical architecture |
|
|
476
|
+
| [examples/README.md](examples/README.md) | Practical examples + runnable library config files (`examples/*.yaml`) |
|
|
477
|
+
| [docs/grpc-sandbox-architecture.md](docs/grpc-sandbox-architecture.md) | Sandbox architecture, gRPC protocol, and security configuration |
|
|
478
|
+
| [docs/integration-testing.md](docs/integration-testing.md) | Integration test workflow and container tests |
|
|
479
|
+
|
|
335
480
|
---
|
|
336
481
|
|
|
337
482
|
## License
|
|
338
483
|
|
|
339
484
|
MIT
|
|
340
|
-
|