@calltelemetry/ct-lab-mcp 0.8.68 → 0.8.70

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 (65) hide show
  1. package/README.md +5 -1
  2. package/dist/src/appliance/executor.d.ts.map +1 -1
  3. package/dist/src/appliance/executor.js +3 -172
  4. package/dist/src/appliance/executor.js.map +1 -1
  5. package/dist/src/hypervisors/esxi/client.d.ts.map +1 -1
  6. package/dist/src/hypervisors/esxi/client.js +5 -0
  7. package/dist/src/hypervisors/esxi/client.js.map +1 -1
  8. package/dist/src/hypervisors/manager.d.ts +1 -0
  9. package/dist/src/hypervisors/manager.d.ts.map +1 -1
  10. package/dist/src/hypervisors/manager.js +5 -2
  11. package/dist/src/hypervisors/manager.js.map +1 -1
  12. package/dist/src/proxmox/client.d.ts.map +1 -1
  13. package/dist/src/proxmox/client.js +17 -0
  14. package/dist/src/proxmox/client.js.map +1 -1
  15. package/dist/src/slot/manager.d.ts +12 -2
  16. package/dist/src/slot/manager.d.ts.map +1 -1
  17. package/dist/src/slot/manager.js +37 -4
  18. package/dist/src/slot/manager.js.map +1 -1
  19. package/dist/src/slot/purge-controller.d.ts +1 -0
  20. package/dist/src/slot/purge-controller.d.ts.map +1 -1
  21. package/dist/src/slot/purge-controller.js +4 -33
  22. package/dist/src/slot/purge-controller.js.map +1 -1
  23. package/dist/src/tools/appliance-claim-tools.d.ts +11 -7
  24. package/dist/src/tools/appliance-claim-tools.d.ts.map +1 -1
  25. package/dist/src/tools/appliance-claim-tools.js +28 -81
  26. package/dist/src/tools/appliance-claim-tools.js.map +1 -1
  27. package/dist/src/tools/appliance-exec.d.ts +4 -4
  28. package/dist/src/tools/claim-creation-projection.d.ts +7 -0
  29. package/dist/src/tools/claim-creation-projection.d.ts.map +1 -0
  30. package/dist/src/tools/claim-creation-projection.js +112 -0
  31. package/dist/src/tools/claim-creation-projection.js.map +1 -0
  32. package/dist/src/tools/claim-first.d.ts.map +1 -1
  33. package/dist/src/tools/claim-first.js +19 -15
  34. package/dist/src/tools/claim-first.js.map +1 -1
  35. package/dist/src/tools/claimed-import-qcow.d.ts +2 -2
  36. package/dist/src/tools/find-slot.d.ts +1 -1
  37. package/dist/src/tools/import-qcow.d.ts +6 -6
  38. package/dist/src/tools/index.d.ts.map +1 -1
  39. package/dist/src/tools/index.js +5 -1
  40. package/dist/src/tools/index.js.map +1 -1
  41. package/dist/src/tools/legacy-guest-guard.d.ts +4 -0
  42. package/dist/src/tools/legacy-guest-guard.d.ts.map +1 -0
  43. package/dist/src/tools/legacy-guest-guard.js +26 -0
  44. package/dist/src/tools/legacy-guest-guard.js.map +1 -0
  45. package/dist/src/tools/license-tools.d.ts +2 -2
  46. package/dist/src/tools/list-hosts.d.ts.map +1 -1
  47. package/dist/src/tools/list-hosts.js +17 -9
  48. package/dist/src/tools/list-hosts.js.map +1 -1
  49. package/dist/src/tools/physical-slot-claim-spec-schema.v1.json +1 -0
  50. package/dist/src/tools/physical-slot.d.ts +205 -0
  51. package/dist/src/tools/physical-slot.d.ts.map +1 -0
  52. package/dist/src/tools/physical-slot.js +295 -0
  53. package/dist/src/tools/physical-slot.js.map +1 -0
  54. package/dist/src/tools/provision-tools.d.ts +18 -18
  55. package/dist/src/tools/sandbox-tools.d.ts +2 -2
  56. package/dist/src/tools/slot-kubernetes.d.ts +13 -0
  57. package/dist/src/tools/slot-kubernetes.d.ts.map +1 -0
  58. package/dist/src/tools/slot-kubernetes.js +108 -0
  59. package/dist/src/tools/slot-kubernetes.js.map +1 -0
  60. package/dist/src/tools/slot-tools.d.ts +8 -8
  61. package/dist/src/tools/vm-action.d.ts +4 -4
  62. package/dist/src/transports/sse.d.ts.map +1 -1
  63. package/dist/src/transports/sse.js +61 -30
  64. package/dist/src/transports/sse.js.map +1 -1
  65. package/package.json +2 -2
@@ -137,8 +137,8 @@ export declare const ProvisionVmInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObje
137
137
  }, "strip", z.ZodTypeAny, {
138
138
  hypervisorType: "proxmox" | "esxi" | "any";
139
139
  format: "table" | "json";
140
- apply: boolean;
141
140
  source: "template" | "alma97-cloud" | "alma97-iso";
141
+ apply: boolean;
142
142
  recoverIncomplete: boolean;
143
143
  finalizeInstalled: boolean;
144
144
  startOnDeploy: boolean;
@@ -165,8 +165,8 @@ export declare const ProvisionVmInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObje
165
165
  requester?: string | undefined;
166
166
  purpose?: string | undefined;
167
167
  ttlHours?: number | undefined;
168
- assetId?: string | undefined;
169
168
  hostAssetId?: string | undefined;
169
+ assetId?: string | undefined;
170
170
  operationId?: string | undefined;
171
171
  networkBridge?: string | undefined;
172
172
  templateAssetId?: string | undefined;
@@ -220,8 +220,9 @@ export declare const ProvisionVmInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObje
220
220
  requester?: string | undefined;
221
221
  purpose?: string | undefined;
222
222
  ttlHours?: number | undefined;
223
- assetId?: string | undefined;
224
223
  hostAssetId?: string | undefined;
224
+ source?: "template" | "alma97-cloud" | "alma97-iso" | undefined;
225
+ assetId?: string | undefined;
225
226
  operationId?: string | undefined;
226
227
  networkBridge?: string | undefined;
227
228
  templateAssetId?: string | undefined;
@@ -232,7 +233,6 @@ export declare const ProvisionVmInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObje
232
233
  confirmAssetId?: string | undefined;
233
234
  targetHost?: string | undefined;
234
235
  outputFile?: string | undefined;
235
- source?: "template" | "alma97-cloud" | "alma97-iso" | undefined;
236
236
  webImage?: string | undefined;
237
237
  baseVersion?: string | undefined;
238
238
  nativeCliDir?: string | undefined;
@@ -263,8 +263,8 @@ export declare const ProvisionVmInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObje
263
263
  }>, {
264
264
  hypervisorType: "proxmox" | "esxi" | "any";
265
265
  format: "table" | "json";
266
- apply: boolean;
267
266
  source: "template" | "alma97-cloud" | "alma97-iso";
267
+ apply: boolean;
268
268
  recoverIncomplete: boolean;
269
269
  finalizeInstalled: boolean;
270
270
  startOnDeploy: boolean;
@@ -291,8 +291,8 @@ export declare const ProvisionVmInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObje
291
291
  requester?: string | undefined;
292
292
  purpose?: string | undefined;
293
293
  ttlHours?: number | undefined;
294
- assetId?: string | undefined;
295
294
  hostAssetId?: string | undefined;
295
+ assetId?: string | undefined;
296
296
  operationId?: string | undefined;
297
297
  networkBridge?: string | undefined;
298
298
  templateAssetId?: string | undefined;
@@ -346,8 +346,9 @@ export declare const ProvisionVmInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObje
346
346
  requester?: string | undefined;
347
347
  purpose?: string | undefined;
348
348
  ttlHours?: number | undefined;
349
- assetId?: string | undefined;
350
349
  hostAssetId?: string | undefined;
350
+ source?: "template" | "alma97-cloud" | "alma97-iso" | undefined;
351
+ assetId?: string | undefined;
351
352
  operationId?: string | undefined;
352
353
  networkBridge?: string | undefined;
353
354
  templateAssetId?: string | undefined;
@@ -358,7 +359,6 @@ export declare const ProvisionVmInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObje
358
359
  confirmAssetId?: string | undefined;
359
360
  targetHost?: string | undefined;
360
361
  outputFile?: string | undefined;
361
- source?: "template" | "alma97-cloud" | "alma97-iso" | undefined;
362
362
  webImage?: string | undefined;
363
363
  baseVersion?: string | undefined;
364
364
  nativeCliDir?: string | undefined;
@@ -389,8 +389,8 @@ export declare const ProvisionVmInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObje
389
389
  }>, {
390
390
  hypervisorType: "proxmox" | "esxi" | "any";
391
391
  format: "table" | "json";
392
- apply: boolean;
393
392
  source: "template" | "alma97-cloud" | "alma97-iso";
393
+ apply: boolean;
394
394
  recoverIncomplete: boolean;
395
395
  finalizeInstalled: boolean;
396
396
  startOnDeploy: boolean;
@@ -417,8 +417,8 @@ export declare const ProvisionVmInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObje
417
417
  requester?: string | undefined;
418
418
  purpose?: string | undefined;
419
419
  ttlHours?: number | undefined;
420
- assetId?: string | undefined;
421
420
  hostAssetId?: string | undefined;
421
+ assetId?: string | undefined;
422
422
  operationId?: string | undefined;
423
423
  networkBridge?: string | undefined;
424
424
  templateAssetId?: string | undefined;
@@ -472,8 +472,9 @@ export declare const ProvisionVmInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObje
472
472
  requester?: string | undefined;
473
473
  purpose?: string | undefined;
474
474
  ttlHours?: number | undefined;
475
- assetId?: string | undefined;
476
475
  hostAssetId?: string | undefined;
476
+ source?: "template" | "alma97-cloud" | "alma97-iso" | undefined;
477
+ assetId?: string | undefined;
477
478
  operationId?: string | undefined;
478
479
  networkBridge?: string | undefined;
479
480
  templateAssetId?: string | undefined;
@@ -484,7 +485,6 @@ export declare const ProvisionVmInputSchema: z.ZodEffects<z.ZodEffects<z.ZodObje
484
485
  confirmAssetId?: string | undefined;
485
486
  targetHost?: string | undefined;
486
487
  outputFile?: string | undefined;
487
- source?: "template" | "alma97-cloud" | "alma97-iso" | undefined;
488
488
  webImage?: string | undefined;
489
489
  baseVersion?: string | undefined;
490
490
  nativeCliDir?: string | undefined;
@@ -653,9 +653,9 @@ export declare const AutoProvisionVmInputSchema: z.ZodObject<{
653
653
  hypervisorType: "proxmox" | "esxi" | "any";
654
654
  ttlMinutes: number;
655
655
  format: "table" | "json";
656
+ source: "template" | "alma97-cloud" | "alma97-iso";
656
657
  apply: boolean;
657
658
  purgeIfFull: boolean;
658
- source: "template" | "alma97-cloud" | "alma97-iso";
659
659
  recoverIncomplete: boolean;
660
660
  finalizeInstalled: boolean;
661
661
  fullClone: boolean;
@@ -682,18 +682,18 @@ export declare const AutoProvisionVmInputSchema: z.ZodObject<{
682
682
  requester?: string | undefined;
683
683
  purpose?: string | undefined;
684
684
  ttlHours?: number | undefined;
685
- assetId?: string | undefined;
686
685
  hostAssetId?: string | undefined;
686
+ assetId?: string | undefined;
687
687
  operationId?: string | undefined;
688
688
  networkBridge?: string | undefined;
689
689
  templateAssetId?: string | undefined;
690
690
  workspaceRoot?: string | undefined;
691
691
  importStorage?: string | undefined;
692
+ allowEsxiSlots?: boolean | undefined;
692
693
  receiptFile?: string | undefined;
693
694
  confirmAssetId?: string | undefined;
694
695
  placementSeed?: string | undefined;
695
696
  targetHost?: string | undefined;
696
- allowEsxiSlots?: boolean | undefined;
697
697
  outputFile?: string | undefined;
698
698
  webImage?: string | undefined;
699
699
  baseVersion?: string | undefined;
@@ -740,22 +740,22 @@ export declare const AutoProvisionVmInputSchema: z.ZodObject<{
740
740
  requester?: string | undefined;
741
741
  purpose?: string | undefined;
742
742
  ttlHours?: number | undefined;
743
- assetId?: string | undefined;
744
743
  hostAssetId?: string | undefined;
744
+ source?: "template" | "alma97-cloud" | "alma97-iso" | undefined;
745
+ assetId?: string | undefined;
745
746
  operationId?: string | undefined;
746
747
  networkBridge?: string | undefined;
747
748
  templateAssetId?: string | undefined;
748
749
  workspaceRoot?: string | undefined;
749
750
  importStorage?: string | undefined;
751
+ allowEsxiSlots?: boolean | undefined;
750
752
  apply?: boolean | undefined;
751
753
  receiptFile?: string | undefined;
752
754
  confirmAssetId?: string | undefined;
753
755
  placementSeed?: string | undefined;
754
756
  targetHost?: string | undefined;
755
757
  purgeIfFull?: boolean | undefined;
756
- allowEsxiSlots?: boolean | undefined;
757
758
  outputFile?: string | undefined;
758
- source?: "template" | "alma97-cloud" | "alma97-iso" | undefined;
759
759
  webImage?: string | undefined;
760
760
  baseVersion?: string | undefined;
761
761
  nativeCliDir?: string | undefined;
@@ -162,8 +162,8 @@ export declare const SandboxResetInputSchema: z.ZodEffects<z.ZodObject<{
162
162
  receiptFile: z.ZodOptional<z.ZodString>;
163
163
  }, "strip", z.ZodTypeAny, {
164
164
  linearIssue: string;
165
- assetId: string;
166
165
  hostAssetId: "proxmox-lab" | "proxmox-mini" | "proxmox-minis-lab";
166
+ assetId: string;
167
167
  operationId: string;
168
168
  apply: boolean;
169
169
  snapshotName: string;
@@ -186,8 +186,8 @@ export declare const SandboxResetInputSchema: z.ZodEffects<z.ZodObject<{
186
186
  waitAgent?: boolean | undefined;
187
187
  }>, {
188
188
  linearIssue: string;
189
- assetId: string;
190
189
  hostAssetId: "proxmox-lab" | "proxmox-mini" | "proxmox-minis-lab";
190
+ assetId: string;
191
191
  operationId: string;
192
192
  apply: boolean;
193
193
  snapshotName: string;
@@ -0,0 +1,13 @@
1
+ export type SlotMethod = "GET" | "POST" | "PUT" | "DELETE";
2
+ export interface SlotApi {
3
+ request(path: string, method: SlotMethod, body?: unknown): Promise<any | null>;
4
+ }
5
+ export declare class SlotApiError extends Error {
6
+ readonly status: number | null;
7
+ constructor(status: number | null, message: string);
8
+ }
9
+ export declare const SLOT_CONTEXT = "do-nyc1-cluster-ny1";
10
+ export declare const SLOT_SERVER = "https://28a6e4a4-fbff-4b51-a9bd-6073ffd8cdb2.k8s.ondigitalocean.com";
11
+ export declare function assertSlotPath(path: string, method: SlotMethod): void;
12
+ export declare function createSlotApi(): SlotApi;
13
+ //# sourceMappingURL=slot-kubernetes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slot-kubernetes.d.ts","sourceRoot":"","sources":["../../../src/tools/slot-kubernetes.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;AAC3D,MAAM,WAAW,OAAO;IAAG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;CAAE;AAC5G,qBAAa,YAAa,SAAQ,KAAK;aACT,MAAM,EAAE,MAAM,GAAG,IAAI;gBAArB,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM;CACnE;AAGD,eAAO,MAAM,YAAY,wBAAwB,CAAC;AAClD,eAAO,MAAM,WAAW,wEAAwE,CAAC;AAGjG,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAUrE;AAmBD,wBAAgB,aAAa,IAAI,OAAO,CAgCvC"}
@@ -0,0 +1,108 @@
1
+ /** Fixed namespace transport for physical-slot custody. Never retry an unknown write. */
2
+ import { execFile } from "node:child_process";
3
+ import * as fs from "node:fs";
4
+ import { userInfo } from "node:os";
5
+ import { join } from "node:path";
6
+ import { fetch, Agent } from "undici";
7
+ export class SlotApiError extends Error {
8
+ status;
9
+ constructor(status, message) {
10
+ super(message);
11
+ this.status = status;
12
+ }
13
+ }
14
+ const TOKEN = "/var/run/secrets/kubernetes.io/serviceaccount/token";
15
+ const CA = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt";
16
+ export const SLOT_CONTEXT = "do-nyc1-cluster-ny1";
17
+ export const SLOT_SERVER = "https://28a6e4a4-fbff-4b51-a9bd-6073ffd8cdb2.k8s.ondigitalocean.com";
18
+ const MAX_BYTES = 1_048_576;
19
+ const COLLECTIONS = ["/apis/coordination.k8s.io/v1/namespaces/ct-lab/leases", "/apis/calltelemetry.com/v1alpha1/namespaces/ct-lab/applianceclaims"];
20
+ export function assertSlotPath(path, method) {
21
+ const cleanPath = path.split("?")[0];
22
+ if (path !== cleanPath && !/^\?limit=500(?:&continue=[A-Za-z0-9%._~-]+)?$/.test(path.slice(cleanPath.length)))
23
+ throw new Error("physical slot query refused");
24
+ const collection = COLLECTIONS.find(p => cleanPath === p || cleanPath.startsWith(p + "/"));
25
+ if (!collection)
26
+ throw new Error("physical slot API path refused");
27
+ const name = cleanPath.slice(collection.length + 1);
28
+ if (cleanPath !== collection && (name.length > 253 || !name.split(".").every(label => /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(label))))
29
+ throw new Error("physical slot object name refused");
30
+ if (method === "POST" && cleanPath !== collection || method !== "POST" && cleanPath === collection && !(method === "GET" && collection === COLLECTIONS[1]))
31
+ throw new Error("physical slot method refused");
32
+ if (collection === COLLECTIONS[0] && method === "DELETE")
33
+ throw new Error("MCP cannot release a durable physical reservation");
34
+ if (collection === COLLECTIONS[1] && method === "PUT")
35
+ throw new Error("physical slot adapter cannot replace a claim");
36
+ }
37
+ function parse(text) {
38
+ if (Buffer.byteLength(text) > MAX_BYTES)
39
+ throw new Error("physical slot response exceeds bound");
40
+ const value = JSON.parse(text);
41
+ if (!value || typeof value !== "object" || Array.isArray(value))
42
+ throw new Error("physical slot response is not an object");
43
+ return value;
44
+ }
45
+ function kubectl(args, body, env) {
46
+ return new Promise((resolve, reject) => {
47
+ const child = execFile("kubectl", args, { env, timeout: 10_000, maxBuffer: MAX_BYTES }, (err, stdout, stderr) => {
48
+ if (err) {
49
+ // kubectl has no machine-readable HTTP code. Only exact NotFound is absence.
50
+ const status = /\(NotFound\)/.test(stderr) ? 404 : /\(AlreadyExists\)|\(Conflict\)/.test(stderr) ? 409 : null;
51
+ reject(new SlotApiError(status, `physical slot Kubernetes request failed (${status ?? "unknown"}); retain custody`));
52
+ }
53
+ else
54
+ resolve(stdout);
55
+ });
56
+ if (body !== undefined)
57
+ child.stdin?.end(JSON.stringify(body));
58
+ });
59
+ }
60
+ export function createSlotApi() {
61
+ // The selected transport cannot change after a timeout or failed mutation.
62
+ const inCluster = fs.existsSync(TOKEN);
63
+ let localReady;
64
+ const env = { ...process.env };
65
+ for (const key of ["KUBECONFIG", "KUBERNETES_MASTER", "KUBECTL_KUBERC", "HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "http_proxy", "https_proxy", "all_proxy"])
66
+ delete env[key];
67
+ env.KUBECTL_KUBERC = "false";
68
+ const base = ["--kubeconfig", join(userInfo().homedir, ".kube", "config"), "--context", SLOT_CONTEXT, "--server", SLOT_SERVER, "--insecure-skip-tls-verify=false", "--request-timeout=10s"];
69
+ return { async request(path, method, body) {
70
+ assertSlotPath(path, method);
71
+ if (inCluster) {
72
+ if (!fs.existsSync(CA))
73
+ throw new Error("physical slot Kubernetes CA unavailable");
74
+ const host = process.env.KUBERNETES_SERVICE_HOST || "kubernetes.default.svc";
75
+ const port = process.env.KUBERNETES_SERVICE_PORT || "443";
76
+ if (!/^[a-zA-Z0-9.-]+$/.test(host) || !/^\d{1,5}$/.test(port))
77
+ throw new Error("physical slot Kubernetes service identity refused");
78
+ const agent = new Agent({ connect: { ca: fs.readFileSync(CA), rejectUnauthorized: true } });
79
+ try {
80
+ const response = await fetch(`https://${host}:${port}${path}`, { method, headers: { Authorization: `Bearer ${fs.readFileSync(TOKEN, "utf8").trim()}`, "Content-Type": "application/json" }, body: body === undefined ? undefined : JSON.stringify(body), dispatcher: agent, signal: AbortSignal.timeout(10_000) });
81
+ if (response.status === 404 && method === "GET")
82
+ return null;
83
+ if (!response.ok)
84
+ throw new SlotApiError(response.status, `physical slot Kubernetes request failed (${response.status}); retain custody`);
85
+ return parse(await response.text());
86
+ }
87
+ finally {
88
+ await agent.close();
89
+ }
90
+ }
91
+ localReady ??= (async () => {
92
+ const cluster = parse(await kubectl([...base, "config", "view", "--minify", "--raw", "-o", "jsonpath={.clusters[0].cluster}"], undefined, env));
93
+ if (cluster.server !== SLOT_SERVER || cluster["insecure-skip-tls-verify"] === true || !(cluster["certificate-authority-data"] || cluster["certificate-authority"]) || cluster["proxy-url"] || cluster["tls-server-name"] && cluster["tls-server-name"] !== new URL(SLOT_SERVER).hostname)
94
+ throw new Error("physical slot fixed cluster TLS binding refused");
95
+ })();
96
+ await localReady;
97
+ const command = method === "GET" ? "get" : method === "POST" ? "create" : method === "PUT" ? "replace" : "delete";
98
+ try {
99
+ return parse(await kubectl([...base, command, "--raw", path, ...(body === undefined ? [] : ["-f", "-"])], body, env));
100
+ }
101
+ catch (err) {
102
+ if (method === "GET" && err instanceof SlotApiError && err.status === 404)
103
+ return null;
104
+ throw err;
105
+ }
106
+ } };
107
+ }
108
+ //# sourceMappingURL=slot-kubernetes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slot-kubernetes.js","sourceRoot":"","sources":["../../../src/tools/slot-kubernetes.ts"],"names":[],"mappings":"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"}
@@ -99,11 +99,12 @@ export declare const ClaimSlotInputSchema: z.ZodEffects<z.ZodObject<{
99
99
  diskGb?: number | undefined;
100
100
  customTags?: string | string[] | undefined;
101
101
  requester?: string | undefined;
102
- purpose?: string | undefined;
103
102
  sessionId?: string | undefined;
103
+ purpose?: string | undefined;
104
104
  ttlHours?: number | undefined;
105
105
  assetId?: string | undefined;
106
106
  operationId?: string | undefined;
107
+ allowEsxiSlots?: boolean | undefined;
107
108
  receiptFile?: string | undefined;
108
109
  confirmAssetId?: string | undefined;
109
110
  claimNode?: "proxmox" | "esxi" | "minis" | undefined;
@@ -111,7 +112,6 @@ export declare const ClaimSlotInputSchema: z.ZodEffects<z.ZodObject<{
111
112
  claimVmName?: string | undefined;
112
113
  placementSeed?: string | undefined;
113
114
  targetHost?: string | undefined;
114
- allowEsxiSlots?: boolean | undefined;
115
115
  }, {
116
116
  tags?: string | string[] | undefined;
117
117
  hypervisorType?: "proxmox" | "esxi" | "any" | undefined;
@@ -130,11 +130,12 @@ export declare const ClaimSlotInputSchema: z.ZodEffects<z.ZodObject<{
130
130
  diskGb?: number | undefined;
131
131
  customTags?: string | string[] | undefined;
132
132
  requester?: string | undefined;
133
- purpose?: string | undefined;
134
133
  sessionId?: string | undefined;
134
+ purpose?: string | undefined;
135
135
  ttlHours?: number | undefined;
136
136
  assetId?: string | undefined;
137
137
  operationId?: string | undefined;
138
+ allowEsxiSlots?: boolean | undefined;
138
139
  apply?: boolean | undefined;
139
140
  receiptFile?: string | undefined;
140
141
  confirmAssetId?: string | undefined;
@@ -145,7 +146,6 @@ export declare const ClaimSlotInputSchema: z.ZodEffects<z.ZodObject<{
145
146
  placementSeed?: string | undefined;
146
147
  targetHost?: string | undefined;
147
148
  purgeIfFull?: boolean | undefined;
148
- allowEsxiSlots?: boolean | undefined;
149
149
  }>, {
150
150
  hypervisorType: "proxmox" | "esxi" | "any";
151
151
  durationMinutes: number;
@@ -167,11 +167,12 @@ export declare const ClaimSlotInputSchema: z.ZodEffects<z.ZodObject<{
167
167
  diskGb?: number | undefined;
168
168
  customTags?: string | string[] | undefined;
169
169
  requester?: string | undefined;
170
- purpose?: string | undefined;
171
170
  sessionId?: string | undefined;
171
+ purpose?: string | undefined;
172
172
  ttlHours?: number | undefined;
173
173
  assetId?: string | undefined;
174
174
  operationId?: string | undefined;
175
+ allowEsxiSlots?: boolean | undefined;
175
176
  receiptFile?: string | undefined;
176
177
  confirmAssetId?: string | undefined;
177
178
  claimNode?: "proxmox" | "esxi" | "minis" | undefined;
@@ -179,7 +180,6 @@ export declare const ClaimSlotInputSchema: z.ZodEffects<z.ZodObject<{
179
180
  claimVmName?: string | undefined;
180
181
  placementSeed?: string | undefined;
181
182
  targetHost?: string | undefined;
182
- allowEsxiSlots?: boolean | undefined;
183
183
  }, {
184
184
  tags?: string | string[] | undefined;
185
185
  hypervisorType?: "proxmox" | "esxi" | "any" | undefined;
@@ -198,11 +198,12 @@ export declare const ClaimSlotInputSchema: z.ZodEffects<z.ZodObject<{
198
198
  diskGb?: number | undefined;
199
199
  customTags?: string | string[] | undefined;
200
200
  requester?: string | undefined;
201
- purpose?: string | undefined;
202
201
  sessionId?: string | undefined;
202
+ purpose?: string | undefined;
203
203
  ttlHours?: number | undefined;
204
204
  assetId?: string | undefined;
205
205
  operationId?: string | undefined;
206
+ allowEsxiSlots?: boolean | undefined;
206
207
  apply?: boolean | undefined;
207
208
  receiptFile?: string | undefined;
208
209
  confirmAssetId?: string | undefined;
@@ -213,7 +214,6 @@ export declare const ClaimSlotInputSchema: z.ZodEffects<z.ZodObject<{
213
214
  placementSeed?: string | undefined;
214
215
  targetHost?: string | undefined;
215
216
  purgeIfFull?: boolean | undefined;
216
- allowEsxiSlots?: boolean | undefined;
217
217
  }>;
218
218
  export type ClaimSlotInput = z.infer<typeof ClaimSlotInputSchema>;
219
219
  export type ClaimSlotRawInput = z.input<typeof ClaimSlotInputSchema>;
@@ -137,8 +137,8 @@ export declare const VmActionInputSchema: z.ZodEffects<z.ZodObject<{
137
137
  vmid?: string | number | undefined;
138
138
  reason?: string | undefined;
139
139
  timeoutSeconds?: number | undefined;
140
- assetId?: string | undefined;
141
140
  hostAssetId?: string | undefined;
141
+ assetId?: string | undefined;
142
142
  artifactReceipt?: string | undefined;
143
143
  receiptFile?: string | undefined;
144
144
  confirmAssetId?: string | undefined;
@@ -168,8 +168,8 @@ export declare const VmActionInputSchema: z.ZodEffects<z.ZodObject<{
168
168
  format?: "table" | "json" | undefined;
169
169
  reason?: string | undefined;
170
170
  timeoutSeconds?: number | undefined;
171
- assetId?: string | undefined;
172
171
  hostAssetId?: string | undefined;
172
+ assetId?: string | undefined;
173
173
  artifactReceipt?: string | undefined;
174
174
  apply?: boolean | undefined;
175
175
  receiptFile?: string | undefined;
@@ -207,8 +207,8 @@ export declare const VmActionInputSchema: z.ZodEffects<z.ZodObject<{
207
207
  vmid?: string | number | undefined;
208
208
  reason?: string | undefined;
209
209
  timeoutSeconds?: number | undefined;
210
- assetId?: string | undefined;
211
210
  hostAssetId?: string | undefined;
211
+ assetId?: string | undefined;
212
212
  artifactReceipt?: string | undefined;
213
213
  receiptFile?: string | undefined;
214
214
  confirmAssetId?: string | undefined;
@@ -238,8 +238,8 @@ export declare const VmActionInputSchema: z.ZodEffects<z.ZodObject<{
238
238
  format?: "table" | "json" | undefined;
239
239
  reason?: string | undefined;
240
240
  timeoutSeconds?: number | undefined;
241
- assetId?: string | undefined;
242
241
  hostAssetId?: string | undefined;
242
+ assetId?: string | undefined;
243
243
  artifactReceipt?: string | undefined;
244
244
  apply?: boolean | undefined;
245
245
  receiptFile?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/transports/sse.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAqB,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAE7E,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAYnE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,iBAAiB,CAAC,EAAE,sBAAsB,CAAC;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,OAAO,CAAC;IACb,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,uBAAuB,EAAE,SAAS,GAAG,CAAC,MAAM,SAAS,CAAC,EACtD,OAAO,GAAE,gBAAqB,GAC7B,iBAAiB,CAuRnB"}
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/transports/sse.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAqB,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAE7E,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAKnE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,iBAAiB,CAAC,EAAE,sBAAsB,CAAC;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,OAAO,CAAC;IACb,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,uBAAuB,EAAE,SAAS,GAAG,CAAC,MAAM,SAAS,CAAC,EACtD,OAAO,GAAE,gBAAqB,GAC7B,iBAAiB,CA8TnB"}
@@ -5,19 +5,9 @@
5
5
  */
6
6
  import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
7
7
  import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
8
- import fs from "node:fs";
9
- import path from "node:path";
10
- import { fileURLToPath } from "node:url";
8
+ import { RUNTIME_VERSION } from "../provenance.js";
11
9
  import { logger } from "../utils/logger.js";
12
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
13
- const pkgPath = path.resolve(__dirname, "../../package.json");
14
- let pkgVersion = "0.1.2";
15
- try {
16
- if (fs.existsSync(pkgPath)) {
17
- pkgVersion = JSON.parse(fs.readFileSync(pkgPath, "utf-8")).version || "0.1.2";
18
- }
19
- }
20
- catch { }
10
+ const pkgVersion = RUNTIME_VERSION;
21
11
  /**
22
12
  * Creates an Express application and SSE server instance configured for Call Telemetry Lab MCP.
23
13
  */
@@ -31,6 +21,7 @@ export function createSseServer(serverFactoryOrInstance, options = {}) {
31
21
  : { host });
32
22
  const sessions = new Map();
33
23
  let activeHttpServer;
24
+ let isClosing = false;
34
25
  // Background session cleanup timer
35
26
  const cleanupInterval = setInterval(() => {
36
27
  const now = Date.now();
@@ -49,14 +40,19 @@ export function createSseServer(serverFactoryOrInstance, options = {}) {
49
40
  // Background caching for external hypervisor capacity checks to keep /health sub-millisecond
50
41
  let cachedHostCapacities = null;
51
42
  let isRefreshingHostCapacities = false;
43
+ let hostCapacitiesObservedAt = null;
44
+ let hostCapacityRefreshFailed = false;
52
45
  const refreshHostCapacities = async () => {
53
46
  if (isRefreshingHostCapacities || !options.hypervisorManager)
54
47
  return;
55
48
  isRefreshingHostCapacities = true;
56
49
  try {
57
- cachedHostCapacities = await options.hypervisorManager.listAllHostsCapacity();
50
+ cachedHostCapacities = await options.hypervisorManager.listAllHostsCapacity({ allowEsxiSlots: options.slotManager?.allowsEsxiSlots ?? process.env.ALLOW_ESXI_SLOTS === "true" });
51
+ hostCapacitiesObservedAt = new Date().toISOString();
52
+ hostCapacityRefreshFailed = false;
58
53
  }
59
54
  catch (err) {
55
+ hostCapacityRefreshFailed = true;
60
56
  logger.error("Failed to query hypervisor capacities in background:", err);
61
57
  }
62
58
  finally {
@@ -72,24 +68,39 @@ export function createSseServer(serverFactoryOrInstance, options = {}) {
72
68
  if (capacityRefreshInterval.unref) {
73
69
  capacityRefreshInterval.unref();
74
70
  }
71
+ const freshness = (observedAt) => {
72
+ const elapsed = observedAt ? Date.now() - Date.parse(observedAt) : NaN;
73
+ const ageMs = Number.isFinite(elapsed) ? Math.max(0, elapsed) : null;
74
+ return { ageMs, stale: ageMs === null || ageMs > 40_000, state: ageMs === null ? "unknown" : ageMs > 40_000 ? "stale" : "cached" };
75
+ };
75
76
  // 1. Health Status Endpoint (GET /health)
76
- app.get("/health", async (_req, res) => {
77
- let capacity;
78
- if (options.slotManager) {
79
- try {
80
- capacity = await options.slotManager.listHosts();
81
- }
82
- catch (err) {
83
- logger.error("Failed to query capacity for /health:", err);
84
- }
85
- }
86
- res.status(200).json({
87
- status: "healthy",
77
+ app.get("/health", (_req, res) => {
78
+ const diagnostics = options.slotManager?.getDiagnosticSnapshot?.();
79
+ const ready = Boolean(activeHttpServer?.listening && !isClosing);
80
+ res.status(ready ? 200 : 503).json({
81
+ status: ready ? "healthy" : "not_ready",
82
+ healthScope: "process",
83
+ processHealthy: true,
84
+ sessionRoutingReady: ready,
85
+ ready,
86
+ lifecycle: isClosing ? "draining" : activeHttpServer?.listening ? "listening" : "starting",
88
87
  timestamp: new Date().toISOString(),
89
88
  version: pkgVersion,
90
89
  activeSessions: sessions.size,
91
- capacity,
92
- hostCapacities: cachedHostCapacities,
90
+ capacity: diagnostics?.capacity ?? null,
91
+ capacitySource: "cached_diagnostics",
92
+ capacityObservedAt: diagnostics?.capacityObservedAt ?? null,
93
+ capacityFreshness: freshness(diagnostics?.capacityObservedAt ?? null),
94
+ hostCapacities: Array.isArray(cachedHostCapacities) ? cachedHostCapacities.map((capacity) => ({
95
+ name: capacity.name, type: capacity.type, status: capacity.status,
96
+ cpuTotalCores: capacity.cpuTotalCores, cpuUsedPercent: capacity.cpuUsedPercent,
97
+ memoryTotalBytes: capacity.memoryTotalBytes, memoryUsedBytes: capacity.memoryUsedBytes, memoryFreeBytes: capacity.memoryFreeBytes,
98
+ storageTotalBytes: capacity.storageTotalBytes, storageFreeBytes: capacity.storageFreeBytes,
99
+ })) : null,
100
+ hostCapacitiesObservedAt,
101
+ hostCapacityFreshness: freshness(hostCapacitiesObservedAt),
102
+ hostCapacityRefreshing: isRefreshingHostCapacities,
103
+ hostCapacityRefreshFailed,
93
104
  });
94
105
  });
95
106
  // 1.1 Prometheus / OpenMetrics Metrics Exporter (GET /metrics)
@@ -105,9 +116,22 @@ export function createSseServer(serverFactoryOrInstance, options = {}) {
105
116
  `ct_lab_active_sessions ${sessions.size}`,
106
117
  "",
107
118
  ];
119
+ const diagnostics = options.slotManager?.getDiagnosticSnapshot?.();
120
+ const capacityAge = freshness(diagnostics?.capacityObservedAt ?? null);
121
+ const hostAge = freshness(hostCapacitiesObservedAt);
122
+ lines.push("# HELP ct_lab_capacity_observed Whether a cached capacity observation exists");
123
+ lines.push("# TYPE ct_lab_capacity_observed gauge", `ct_lab_capacity_observed ${capacityAge.ageMs === null ? 0 : 1}`);
124
+ lines.push("# HELP ct_lab_capacity_stale Whether cached capacity is stale or unknown");
125
+ lines.push("# TYPE ct_lab_capacity_stale gauge", `ct_lab_capacity_stale ${capacityAge.stale ? 1 : 0}`);
126
+ if (capacityAge.ageMs !== null)
127
+ lines.push("# TYPE ct_lab_capacity_age_seconds gauge", `ct_lab_capacity_age_seconds ${capacityAge.ageMs / 1000}`);
128
+ lines.push("# TYPE ct_lab_host_capacity_observed gauge", `ct_lab_host_capacity_observed ${hostAge.ageMs === null ? 0 : 1}`);
129
+ lines.push("# TYPE ct_lab_host_capacity_stale gauge", `ct_lab_host_capacity_stale ${hostAge.stale ? 1 : 0}`);
130
+ if (hostAge.ageMs !== null)
131
+ lines.push("# TYPE ct_lab_host_capacity_age_seconds gauge", `ct_lab_host_capacity_age_seconds ${hostAge.ageMs / 1000}`);
108
132
  if (options.slotManager) {
109
133
  try {
110
- const hostsData = await options.slotManager.listHosts();
134
+ const hostsData = diagnostics?.capacity;
111
135
  const hostList = Array.isArray(hostsData) ? hostsData : hostsData?.hosts ? Object.values(hostsData.hosts) : [];
112
136
  lines.push("# HELP ct_lab_fleet_capacity_pure_slots Total pure hardware 8GB slots per host");
113
137
  lines.push("# TYPE ct_lab_fleet_capacity_pure_slots gauge");
@@ -133,8 +157,9 @@ export function createSseServer(serverFactoryOrInstance, options = {}) {
133
157
  lines.push(`ct_lab_fleet_capacity_allocated_slots{host="${hostId}",hypervisor="${hyp}"} ${h.allocatedSlots ?? 0}`);
134
158
  }
135
159
  lines.push("");
136
- const allSlots = await options.slotManager.listSlots();
137
- const activeCount = allSlots.filter((s) => s.status === "CLAIMED" || s.status === "active").length;
160
+ const allSlots = diagnostics?.leases ?? [];
161
+ const activeCount = allSlots.filter((s) => (s.status === "CLAIMED" || s.status === "active")
162
+ && s.expiresAt && Number.isFinite(Date.parse(s.expiresAt)) && Date.parse(s.expiresAt) > Date.now()).length;
138
163
  const expiredCount = allSlots.filter((s) => s.status === "EXPIRED" || (s.expiresAt && new Date(s.expiresAt).getTime() <= Date.now())).length;
139
164
  lines.push("# HELP ct_lab_active_leases_count Total active claimed slot leases in fleet");
140
165
  lines.push("# TYPE ct_lab_active_leases_count gauge");
@@ -172,6 +197,10 @@ export function createSseServer(serverFactoryOrInstance, options = {}) {
172
197
  });
173
198
  // 2. SSE Connection Endpoint (GET /sse)
174
199
  app.get("/sse", async (_req, res) => {
200
+ if (isClosing) {
201
+ res.status(503).json({ error: "MCP session routing is draining" });
202
+ return;
203
+ }
175
204
  try {
176
205
  const serverInstance = typeof serverFactoryOrInstance === "function"
177
206
  ? serverFactoryOrInstance()
@@ -232,6 +261,7 @@ export function createSseServer(serverFactoryOrInstance, options = {}) {
232
261
  app,
233
262
  sessions,
234
263
  async listen(customPort, customHost) {
264
+ isClosing = false;
235
265
  const targetPort = customPort !== undefined ? customPort : port;
236
266
  const targetHost = customHost || host;
237
267
  return new Promise((resolve) => {
@@ -243,6 +273,7 @@ export function createSseServer(serverFactoryOrInstance, options = {}) {
243
273
  });
244
274
  },
245
275
  async close() {
276
+ isClosing = true;
246
277
  clearInterval(cleanupInterval);
247
278
  clearInterval(capacityRefreshInterval);
248
279
  for (const [id, session] of sessions.entries()) {