@calltelemetry/ct-lab-mcp 0.8.49 → 0.8.51

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 (35) hide show
  1. package/README.md +11 -0
  2. package/dist/src/appliance/commands.d.ts.map +1 -1
  3. package/dist/src/appliance/commands.js +39 -0
  4. package/dist/src/appliance/commands.js.map +1 -1
  5. package/dist/src/appliance/types.d.ts +4 -1
  6. package/dist/src/appliance/types.d.ts.map +1 -1
  7. package/dist/src/appliance/types.js.map +1 -1
  8. package/dist/src/hypervisors/esxi/client.d.ts.map +1 -1
  9. package/dist/src/hypervisors/esxi/client.js +29 -15
  10. package/dist/src/hypervisors/esxi/client.js.map +1 -1
  11. package/dist/src/tools/appliance-claim-tools.d.ts +188 -0
  12. package/dist/src/tools/appliance-claim-tools.d.ts.map +1 -0
  13. package/dist/src/tools/appliance-claim-tools.js +365 -0
  14. package/dist/src/tools/appliance-claim-tools.js.map +1 -0
  15. package/dist/src/tools/appliance-id.d.ts +33 -0
  16. package/dist/src/tools/appliance-id.d.ts.map +1 -0
  17. package/dist/src/tools/appliance-id.js +88 -0
  18. package/dist/src/tools/appliance-id.js.map +1 -0
  19. package/dist/src/tools/index.d.ts +4 -0
  20. package/dist/src/tools/index.d.ts.map +1 -1
  21. package/dist/src/tools/index.js +41 -1
  22. package/dist/src/tools/index.js.map +1 -1
  23. package/dist/src/tools/license-tools.d.ts +88 -0
  24. package/dist/src/tools/license-tools.d.ts.map +1 -1
  25. package/dist/src/tools/license-tools.js +253 -0
  26. package/dist/src/tools/license-tools.js.map +1 -1
  27. package/dist/src/tools/sideload-runner.d.ts +56 -0
  28. package/dist/src/tools/sideload-runner.d.ts.map +1 -0
  29. package/dist/src/tools/sideload-runner.js +175 -0
  30. package/dist/src/tools/sideload-runner.js.map +1 -0
  31. package/dist/src/tools/verify-demo.d.ts +125 -0
  32. package/dist/src/tools/verify-demo.d.ts.map +1 -0
  33. package/dist/src/tools/verify-demo.js +435 -0
  34. package/dist/src/tools/verify-demo.js.map +1 -0
  35. package/package.json +1 -1
@@ -0,0 +1,365 @@
1
+ /**
2
+ * ApplianceClaim Kubernetes CRD MCP Tools
3
+ *
4
+ * apiVersion: calltelemetry.com/v1alpha1
5
+ * kind: ApplianceClaim
6
+ *
7
+ * Provides declarative inspection, provisioning, and teardown of appliance claims
8
+ * managed by ct-appliance-operator in Kubernetes (namespace: ct-lab).
9
+ */
10
+ import { z } from "zod";
11
+ import { execFile } from "node:child_process";
12
+ import { promisify } from "node:util";
13
+ import { fetch, Agent } from "undici";
14
+ import * as fs from "node:fs";
15
+ import { ProxmoxErrorCode, createToolErrorResult } from "../types/mcp.js";
16
+ import { logger } from "../utils/logger.js";
17
+ const execFileAsync = promisify(execFile);
18
+ export const RECOGNIZED_CHANNELS = ["stable", "beta", "rc", "candidate", "dev", "edge"];
19
+ export function resolveAndValidateChannel(version, trainOrChannel) {
20
+ const isPrerelease = version.includes("-rc") || version.includes("-dev") || version.includes("-beta") || version.includes("-candidate");
21
+ const is087Line = version.startsWith("0.8.7");
22
+ let channel;
23
+ if (!trainOrChannel) {
24
+ if (isPrerelease) {
25
+ channel = "rc";
26
+ }
27
+ else if (is087Line) {
28
+ channel = "beta";
29
+ }
30
+ else {
31
+ channel = "stable";
32
+ }
33
+ }
34
+ else {
35
+ channel = trainOrChannel.toLowerCase().trim();
36
+ }
37
+ if (!RECOGNIZED_CHANNELS.includes(channel)) {
38
+ throw new Error(`Invalid release train/channel '${trainOrChannel}'. Must be one of: ${RECOGNIZED_CHANNELS.join(", ")}`);
39
+ }
40
+ if (channel === "stable") {
41
+ if (is087Line) {
42
+ throw new Error(`Release Channel Violation: Version '${version}' cannot be provisioned on channel 'stable'. ` +
43
+ `The 0.8.7 line does not have a GA stable release; use channel 'beta' or 'rc'.`);
44
+ }
45
+ if (isPrerelease) {
46
+ throw new Error(`Release Channel Violation: Pre-release version '${version}' cannot be deployed on channel 'stable'. ` +
47
+ `Use channel 'rc' or 'candidate'.`);
48
+ }
49
+ }
50
+ return channel;
51
+ }
52
+ export const ListApplianceClaimsInputShape = {
53
+ namespace: z.string().optional().default("ct-lab").describe("Kubernetes namespace (default: 'ct-lab')."),
54
+ phase: z.enum(["Pending", "Provisioning", "Bootstrapping", "Ready", "Failed", "Closed"]).optional().describe("Filter by phase."),
55
+ claimType: z.enum(["dynamic", "fixture"]).optional().describe("Filter by claimType ('dynamic' vs 'fixture').")
56
+ };
57
+ export const ListApplianceClaimsInputSchema = z.object(ListApplianceClaimsInputShape);
58
+ export const GetApplianceClaimInputShape = {
59
+ name: z.string().min(1).describe("Name of the ApplianceClaim resource (metadata.name)."),
60
+ namespace: z.string().optional().default("ct-lab").describe("Kubernetes namespace (default: 'ct-lab').")
61
+ };
62
+ export const GetApplianceClaimInputSchema = z.object(GetApplianceClaimInputShape);
63
+ export const CreateApplianceClaimInputShape = {
64
+ name: z.string().optional().describe("Name of the ApplianceClaim resource (metadata.name). Auto-generated if omitted."),
65
+ namespace: z.string().optional().default("ct-lab").describe("Kubernetes namespace (default: 'ct-lab')."),
66
+ targetIp: z.string().regex(/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/, "Must be valid IPv4 address").describe("Target IP address for the appliance VM."),
67
+ vmid: z.number().int().min(100).max(8999).optional().describe("Proxmox VMID for the appliance."),
68
+ node: z.string().optional().default("minis").describe("Proxmox node name (default: 'minis')."),
69
+ version: z.string().optional().default("0.8.6.27").describe("Target appliance version (default: '0.8.6.27')."),
70
+ train: z.enum(["stable", "beta", "rc", "candidate", "dev", "edge"]).optional().describe("Release channel / train. Auto-resolved if omitted."),
71
+ linearIssue: z.string().optional().describe("Associated Linear issue (e.g. 'QA-480', 'UAT-1728')."),
72
+ preset: z.enum(["comprehensive_demo", "standard_demo", "minimal_demo", "empty"]).optional().default("comprehensive_demo").describe("Scenario preset to bootstrap (default: 'comprehensive_demo')."),
73
+ ttlHours: z.number().int().min(0).max(8760).optional().default(24).describe("TTL in hours before automated scavenger cleanup (default: 24, 0 = no expiry)."),
74
+ licenseTier: z.enum(["Demo", "Community", "Standard", "Enterprise"]).optional().default("Demo").describe("License tier (default: 'Demo')."),
75
+ licenseDays: z.number().int().min(1).max(3650).optional().default(90).describe("License duration in days (default: 90)."),
76
+ adminEmail: z.string().email().optional().default("demo@calltelemetry.com").describe("Admin user email."),
77
+ containerOverrides: z.record(z.string()).optional().describe("Container git hash or image overrides (e.g. { web: '3f0962a4', vue: 'a67c9610' })."),
78
+ dryRun: z.boolean().optional().default(false).describe("Validate inputs and simulate creation without mutating Kubernetes.")
79
+ };
80
+ export const CreateApplianceClaimInputSchema = z.object(CreateApplianceClaimInputShape);
81
+ export const DeleteApplianceClaimInputShape = {
82
+ name: z.string().min(1).describe("Name of the ApplianceClaim resource to delete."),
83
+ namespace: z.string().optional().default("ct-lab").describe("Kubernetes namespace (default: 'ct-lab').")
84
+ };
85
+ export const DeleteApplianceClaimInputSchema = z.object(DeleteApplianceClaimInputShape);
86
+ const K8S_IN_CLUSTER_TOKEN = "/var/run/secrets/kubernetes.io/serviceaccount/token";
87
+ const K8S_IN_CLUSTER_CA = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt";
88
+ async function queryKubernetesApi(path, options = {}) {
89
+ const isCluster = fs.existsSync(K8S_IN_CLUSTER_TOKEN);
90
+ if (isCluster) {
91
+ const host = process.env.KUBERNETES_SERVICE_HOST || "kubernetes.default.svc";
92
+ const port = process.env.KUBERNETES_SERVICE_PORT || "443";
93
+ const token = fs.readFileSync(K8S_IN_CLUSTER_TOKEN, "utf-8").trim();
94
+ const ca = fs.existsSync(K8S_IN_CLUSTER_CA) ? fs.readFileSync(K8S_IN_CLUSTER_CA) : undefined;
95
+ const agent = new Agent({
96
+ connect: {
97
+ ca,
98
+ rejectUnauthorized: false
99
+ }
100
+ });
101
+ const url = `https://${host}:${port}${path}`;
102
+ const res = await fetch(url, {
103
+ method: options.method || "GET",
104
+ headers: {
105
+ Authorization: `Bearer ${token}`,
106
+ "Content-Type": "application/json"
107
+ },
108
+ body: options.body ? JSON.stringify(options.body) : undefined,
109
+ dispatcher: agent
110
+ });
111
+ if (!res.ok) {
112
+ const errText = await res.text().catch(() => "");
113
+ throw new Error(`Kubernetes API error (${res.status}): ${errText}`);
114
+ }
115
+ return res.json();
116
+ }
117
+ // Fallback to kubectl
118
+ return null;
119
+ }
120
+ export async function handleListApplianceClaims(args, _context) {
121
+ const parsed = ListApplianceClaimsInputSchema.safeParse(args);
122
+ if (!parsed.success) {
123
+ const issues = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
124
+ return createToolErrorResult(ProxmoxErrorCode.VALIDATION_ERROR, issues);
125
+ }
126
+ const { namespace, phase, claimType } = parsed.data;
127
+ try {
128
+ let items = [];
129
+ // Try in-cluster API first
130
+ const apiPath = `/apis/calltelemetry.com/v1alpha1/namespaces/${namespace}/applianceclaims`;
131
+ const apiRes = await queryKubernetesApi(apiPath).catch(() => null);
132
+ if (apiRes && apiRes.items) {
133
+ items = apiRes.items;
134
+ }
135
+ else {
136
+ // Execute via kubectl
137
+ const { stdout } = await execFileAsync("kubectl", [
138
+ "get",
139
+ "applianceclaims",
140
+ "-n",
141
+ namespace,
142
+ "-o",
143
+ "json"
144
+ ]);
145
+ const parsedK8s = JSON.parse(stdout);
146
+ items = parsedK8s.items || [];
147
+ }
148
+ if (phase) {
149
+ items = items.filter((item) => item.status?.phase === phase);
150
+ }
151
+ if (claimType) {
152
+ items = items.filter((item) => (item.spec?.claimType || "dynamic") === claimType);
153
+ }
154
+ const summary = items.map((claim) => ({
155
+ name: claim.metadata?.name,
156
+ phase: claim.status?.phase || "Unknown",
157
+ ip: claim.spec?.targetIp,
158
+ vmid: claim.spec?.vmid,
159
+ node: claim.spec?.node || "minis",
160
+ version: claim.spec?.version,
161
+ train: claim.spec?.train,
162
+ claimType: claim.spec?.claimType || "dynamic",
163
+ ttlHours: claim.spec?.ttlHours,
164
+ createdAt: claim.metadata?.creationTimestamp,
165
+ linearIssue: claim.metadata?.labels?.["calltelemetry.com/linear-issue"] || null
166
+ }));
167
+ return {
168
+ content: [
169
+ {
170
+ type: "text",
171
+ text: JSON.stringify({
172
+ success: true,
173
+ namespace,
174
+ total: items.length,
175
+ claims: summary
176
+ }, null, 2)
177
+ }
178
+ ]
179
+ };
180
+ }
181
+ catch (err) {
182
+ logger.error(`Failed to list appliance claims: ${err.message}`);
183
+ return createToolErrorResult(ProxmoxErrorCode.UPSTREAM_API_ERROR, `Failed to list appliance claims in namespace '${namespace}': ${err.message}`);
184
+ }
185
+ }
186
+ export async function handleGetApplianceClaim(args, _context) {
187
+ const parsed = GetApplianceClaimInputSchema.safeParse(args);
188
+ if (!parsed.success) {
189
+ const issues = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
190
+ return createToolErrorResult(ProxmoxErrorCode.VALIDATION_ERROR, issues);
191
+ }
192
+ const { name, namespace } = parsed.data;
193
+ try {
194
+ let claim = null;
195
+ const apiPath = `/apis/calltelemetry.com/v1alpha1/namespaces/${namespace}/applianceclaims/${name}`;
196
+ const apiRes = await queryKubernetesApi(apiPath).catch(() => null);
197
+ if (apiRes && apiRes.metadata) {
198
+ claim = apiRes;
199
+ }
200
+ else {
201
+ const { stdout } = await execFileAsync("kubectl", [
202
+ "get",
203
+ "applianceclaim",
204
+ name,
205
+ "-n",
206
+ namespace,
207
+ "-o",
208
+ "json"
209
+ ]);
210
+ claim = JSON.parse(stdout);
211
+ }
212
+ return {
213
+ content: [
214
+ {
215
+ type: "text",
216
+ text: JSON.stringify({
217
+ success: true,
218
+ claim
219
+ }, null, 2)
220
+ }
221
+ ]
222
+ };
223
+ }
224
+ catch (err) {
225
+ return createToolErrorResult(ProxmoxErrorCode.VALIDATION_ERROR, `ApplianceClaim '${name}' not found in namespace '${namespace}': ${err.message}`);
226
+ }
227
+ }
228
+ export async function handleCreateApplianceClaim(args, _context) {
229
+ const parsed = CreateApplianceClaimInputSchema.safeParse(args);
230
+ if (!parsed.success) {
231
+ const issues = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
232
+ return createToolErrorResult(ProxmoxErrorCode.VALIDATION_ERROR, issues);
233
+ }
234
+ const { namespace, targetIp, vmid, node, version, preset, ttlHours, licenseTier, licenseDays, adminEmail, linearIssue, containerOverrides, dryRun } = parsed.data;
235
+ let train;
236
+ try {
237
+ train = resolveAndValidateChannel(version, parsed.data.train);
238
+ }
239
+ catch (valErr) {
240
+ return createToolErrorResult(ProxmoxErrorCode.VALIDATION_ERROR, valErr.message);
241
+ }
242
+ const claimName = parsed.data.name || (linearIssue
243
+ ? `claim-${linearIssue.toLowerCase().replace(/[^a-z0-9-]/g, "")}-${vmid || Math.floor(Math.random() * 900 + 100)}`
244
+ : `claim-appliance-${Math.floor(Date.now() / 1000)}`);
245
+ const manifest = {
246
+ apiVersion: "calltelemetry.com/v1alpha1",
247
+ kind: "ApplianceClaim",
248
+ metadata: {
249
+ name: claimName,
250
+ namespace,
251
+ labels: {
252
+ "app.kubernetes.io/managed-by": "ct-lab-mcp",
253
+ ...(linearIssue ? { "calltelemetry.com/linear-issue": linearIssue } : {})
254
+ }
255
+ },
256
+ spec: {
257
+ targetIp,
258
+ node,
259
+ version,
260
+ train,
261
+ preset,
262
+ ttlHours,
263
+ licenseTier,
264
+ licenseDays,
265
+ adminEmail,
266
+ ...(vmid ? { vmid } : {}),
267
+ ...(containerOverrides && Object.keys(containerOverrides).length > 0 ? { containerOverrides } : {})
268
+ }
269
+ };
270
+ if (dryRun) {
271
+ return {
272
+ content: [
273
+ {
274
+ type: "text",
275
+ text: JSON.stringify({
276
+ success: true,
277
+ dryRun: true,
278
+ status: "validated",
279
+ claimName,
280
+ manifest
281
+ }, null, 2)
282
+ }
283
+ ]
284
+ };
285
+ }
286
+ try {
287
+ const apiPath = `/apis/calltelemetry.com/v1alpha1/namespaces/${namespace}/applianceclaims`;
288
+ const apiRes = await queryKubernetesApi(apiPath, {
289
+ method: "POST",
290
+ body: manifest
291
+ }).catch(() => null);
292
+ let createdClaim = apiRes;
293
+ if (!createdClaim) {
294
+ // Create via kubectl stdin
295
+ const { stdout } = await new Promise((resolve, reject) => {
296
+ const proc = execFile("kubectl", ["apply", "-f", "-"], (err, stdout, stderr) => {
297
+ if (err)
298
+ return reject(new Error(stderr || err.message));
299
+ resolve({ stdout, stderr });
300
+ });
301
+ proc.stdin?.write(JSON.stringify(manifest));
302
+ proc.stdin?.end();
303
+ });
304
+ createdClaim = { output: stdout.trim(), name: claimName };
305
+ }
306
+ return {
307
+ content: [
308
+ {
309
+ type: "text",
310
+ text: JSON.stringify({
311
+ success: true,
312
+ message: `ApplianceClaim '${claimName}' created in namespace '${namespace}'`,
313
+ claimName,
314
+ targetIp,
315
+ train,
316
+ version,
317
+ manifest
318
+ }, null, 2)
319
+ }
320
+ ]
321
+ };
322
+ }
323
+ catch (err) {
324
+ logger.error(`Failed to create ApplianceClaim '${claimName}': ${err.message}`);
325
+ return createToolErrorResult(ProxmoxErrorCode.UPSTREAM_API_ERROR, `Failed to create ApplianceClaim '${claimName}': ${err.message}`);
326
+ }
327
+ }
328
+ export async function handleDeleteApplianceClaim(args, _context) {
329
+ const parsed = DeleteApplianceClaimInputSchema.safeParse(args);
330
+ if (!parsed.success) {
331
+ const issues = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
332
+ return createToolErrorResult(ProxmoxErrorCode.VALIDATION_ERROR, issues);
333
+ }
334
+ const { name, namespace } = parsed.data;
335
+ try {
336
+ const apiPath = `/apis/calltelemetry.com/v1alpha1/namespaces/${namespace}/applianceclaims/${name}`;
337
+ const apiRes = await queryKubernetesApi(apiPath, { method: "DELETE" }).catch(() => null);
338
+ if (!apiRes) {
339
+ await execFileAsync("kubectl", [
340
+ "delete",
341
+ "applianceclaim",
342
+ name,
343
+ "-n",
344
+ namespace,
345
+ "--ignore-not-found=true"
346
+ ]);
347
+ }
348
+ return {
349
+ content: [
350
+ {
351
+ type: "text",
352
+ text: JSON.stringify({
353
+ success: true,
354
+ message: `ApplianceClaim '${name}' deleted in namespace '${namespace}'. Operator teardown initiated.`
355
+ }, null, 2)
356
+ }
357
+ ]
358
+ };
359
+ }
360
+ catch (err) {
361
+ logger.error(`Failed to delete ApplianceClaim '${name}': ${err.message}`);
362
+ return createToolErrorResult(ProxmoxErrorCode.UPSTREAM_API_ERROR, `Failed to delete ApplianceClaim '${name}': ${err.message}`);
363
+ }
364
+ }
365
+ //# sourceMappingURL=appliance-claim-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appliance-claim-tools.js","sourceRoot":"","sources":["../../../src/tools/appliance-claim-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Appliance ID Discovery & Standardized Licensing Helper
3
+ *
4
+ * Implements hardware UUID derivation for CallTelemetry 0.8.7+ standardized appliance licensing.
5
+ * Matches the canonical pattern: CT-APP-XXXX-XXXX-XXXX
6
+ */
7
+ import { z } from "zod";
8
+ import { ToolContext } from "./list-hosts.js";
9
+ import { CallToolResult } from "../types/mcp.js";
10
+ export declare const APPLIANCE_ID_REGEX: RegExp;
11
+ export declare function formatApplianceIdFromUuid(rawUuid: string): string;
12
+ export declare function isValidApplianceId(applianceId: string): boolean;
13
+ export declare const GetApplianceIdInputShape: {
14
+ targetIp: z.ZodString;
15
+ port: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
16
+ timeoutMs: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
17
+ };
18
+ export declare const GetApplianceIdInputSchema: z.ZodObject<{
19
+ targetIp: z.ZodString;
20
+ port: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
21
+ timeoutMs: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
22
+ }, "strip", z.ZodTypeAny, {
23
+ targetIp: string;
24
+ port: number;
25
+ timeoutMs: number;
26
+ }, {
27
+ targetIp: string;
28
+ port?: number | undefined;
29
+ timeoutMs?: number | undefined;
30
+ }>;
31
+ export type GetApplianceIdInput = z.infer<typeof GetApplianceIdInputSchema>;
32
+ export declare function handleGetApplianceId(args: unknown, context: ToolContext): Promise<CallToolResult>;
33
+ //# sourceMappingURL=appliance-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appliance-id.d.ts","sourceRoot":"","sources":["../../../src/tools/appliance-id.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAA2C,MAAM,iBAAiB,CAAC;AAI1F,eAAO,MAAM,kBAAkB,QAAiD,CAAC;AAEjF,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOjE;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,eAAO,MAAM,wBAAwB;;;;CAqBpC,CAAC;AAEF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;EAAqC,CAAC;AAC5E,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CAoDzB"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Appliance ID Discovery & Standardized Licensing Helper
3
+ *
4
+ * Implements hardware UUID derivation for CallTelemetry 0.8.7+ standardized appliance licensing.
5
+ * Matches the canonical pattern: CT-APP-XXXX-XXXX-XXXX
6
+ */
7
+ import { z } from "zod";
8
+ import * as crypto from "node:crypto";
9
+ import { ProxmoxErrorCode, createToolErrorResult } from "../types/mcp.js";
10
+ import { applianceSshExecutor } from "../appliance/executor.js";
11
+ import { logger } from "../utils/logger.js";
12
+ export const APPLIANCE_ID_REGEX = /^CT-APP-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}$/;
13
+ export function formatApplianceIdFromUuid(rawUuid) {
14
+ const normalized = rawUuid.trim().toLowerCase().replace(/[^a-z0-9]/g, "");
15
+ if (!normalized) {
16
+ throw new Error("Cannot format Appliance ID from empty hardware UUID.");
17
+ }
18
+ const hash = crypto.createHash("sha256").update(normalized).digest("hex").toUpperCase();
19
+ return `CT-APP-${hash.substring(0, 4)}-${hash.substring(4, 8)}-${hash.substring(8, 12)}`;
20
+ }
21
+ export function isValidApplianceId(applianceId) {
22
+ return APPLIANCE_ID_REGEX.test(applianceId);
23
+ }
24
+ export const GetApplianceIdInputShape = {
25
+ targetIp: z
26
+ .string()
27
+ .min(1)
28
+ .describe("Target IP address or hostname of the Call Telemetry appliance (e.g. '192.168.124.221')."),
29
+ port: z
30
+ .number()
31
+ .int()
32
+ .min(1)
33
+ .max(65535)
34
+ .optional()
35
+ .default(2222)
36
+ .describe("SSH port (default: 2222)."),
37
+ timeoutMs: z
38
+ .number()
39
+ .int()
40
+ .min(2000)
41
+ .max(60000)
42
+ .optional()
43
+ .default(15000)
44
+ .describe("Execution timeout in milliseconds (default: 15000).")
45
+ };
46
+ export const GetApplianceIdInputSchema = z.object(GetApplianceIdInputShape);
47
+ export async function handleGetApplianceId(args, context) {
48
+ const parsed = GetApplianceIdInputSchema.safeParse(args);
49
+ if (!parsed.success) {
50
+ const issues = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
51
+ return createToolErrorResult(ProxmoxErrorCode.VALIDATION_ERROR, issues);
52
+ }
53
+ const { targetIp, port, timeoutMs } = parsed.data;
54
+ const executor = context.applianceExecutor || applianceSshExecutor;
55
+ logger.info(`Discovering hardware UUID on ${targetIp}:${port}...`);
56
+ try {
57
+ const res = await executor.execute({
58
+ targetIp,
59
+ port,
60
+ action: "get_hardware_uuid",
61
+ timeoutMs
62
+ });
63
+ const rawUuid = res.stdout.trim().split("\n")[0] || "";
64
+ if (!rawUuid || rawUuid === "00000000-0000-0000-0000-000000000000") {
65
+ throw new Error(`Invalid hardware UUID received from host: '${rawUuid}'`);
66
+ }
67
+ const applianceId = formatApplianceIdFromUuid(rawUuid);
68
+ return {
69
+ content: [
70
+ {
71
+ type: "text",
72
+ text: JSON.stringify({
73
+ success: true,
74
+ targetIp,
75
+ rawHardwareUuid: rawUuid,
76
+ applianceId,
77
+ standard: "calltelemetry-license-v2"
78
+ }, null, 2)
79
+ }
80
+ ]
81
+ };
82
+ }
83
+ catch (err) {
84
+ logger.error(`Failed to resolve appliance ID on ${targetIp}: ${err.message}`);
85
+ return createToolErrorResult(ProxmoxErrorCode.APPLIANCE_EXECUTION_FAILED, `Failed to resolve appliance ID on ${targetIp}: ${err.message}`);
86
+ }
87
+ }
88
+ //# sourceMappingURL=appliance-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appliance-id.js","sourceRoot":"","sources":["../../../src/tools/appliance-id.ts"],"names":[],"mappings":"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"}
@@ -53,5 +53,9 @@ export * from "./appliance-candidate-retire.js";
53
53
  export * from "./host-migrate-vm.js";
54
54
  export * from "./sandbox-tools.js";
55
55
  export * from "./fleet-metrics.js";
56
+ export * from "./appliance-claim-tools.js";
57
+ export * from "./sideload-runner.js";
58
+ export * from "./appliance-id.js";
59
+ export * from "./verify-demo.js";
56
60
  export declare function registerAllTools(mcpServer: McpServer, context: ToolContext): void;
57
61
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAIL,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAoQzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AAYnC,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAmwBjF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAIL,WAAW,EACZ,MAAM,iBAAiB,CAAC;AA4RzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC;AAChD,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AAYjC,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAm1BjF"}
@@ -50,10 +50,14 @@ import { FleetVersionsInputShape, handleFleetVersions, FleetCandidatesInputShape
50
50
  import { HostMaintenanceShutdownInputShape, handleHostMaintenanceShutdown, } from "./host-maintenance-shutdown.js";
51
51
  import { CubeListInputShape, handleCubeList, CubeStatusInputShape, handleCubeStatus, CubeExecInputShape, handleCubeExec, CubeConfigInputShape, handleCubeConfig, CubeDialpeerShowInputShape, handleCubeDialpeerShow, CubeDialpeerApplyInputShape, handleCubeDialpeerApply, CubeXccEnableInputShape, handleCubeXccEnable, CubeXccStatusInputShape, handleCubeXccStatus, CubeIosSnapshotInputShape, handleCubeIosSnapshot, } from "./cube-canonical.js";
52
52
  import { ApplyManifestInputShape, handleApplyManifest, GetManifestInputShape, handleGetManifest, DeleteManifestInputShape, handleDeleteManifest, RenewManifestInputShape, handleRenewManifest, ListManifestsInputShape, handleListManifests, } from "./manifest-tools.js";
53
- import { ApplyLicenseInputShape, handleApplyLicense, } from "./license-tools.js";
53
+ import { ApplyLicenseInputShape, handleApplyLicense, SideloadLicenseInputShape, handleSideloadLicense, } from "./license-tools.js";
54
54
  import { HostMigrateVmInputShape, handleHostMigrateVm, } from "./host-migrate-vm.js";
55
55
  import { SandboxCloneInputShape, handleSandboxClone, SandboxResetInputShape, handleSandboxReset, } from "./sandbox-tools.js";
56
56
  import { FerrumFleetMetricsInputShape, handleFerrumFleetMetrics, } from "./fleet-metrics.js";
57
+ import { ListApplianceClaimsInputShape, handleListApplianceClaims, GetApplianceClaimInputShape, handleGetApplianceClaim, CreateApplianceClaimInputShape, handleCreateApplianceClaim, DeleteApplianceClaimInputShape, handleDeleteApplianceClaim, } from "./appliance-claim-tools.js";
58
+ import { SideloadApplianceRunnerInputShape, handleSideloadApplianceRunner, } from "./sideload-runner.js";
59
+ import { GetApplianceIdInputShape, handleGetApplianceId, } from "./appliance-id.js";
60
+ import { VerifyApplianceDemoInputShape, handleVerifyApplianceDemo, } from "./verify-demo.js";
57
61
  import { canonicalBridgeOwnsCredentials, canonicalMode, canonicalOperationBlocked, } from "./canonical-guard.js";
58
62
  import { createToolErrorResult } from "../types/mcp.js";
59
63
  import { buildProvenance, stampProvenance } from "../provenance.js";
@@ -96,6 +100,10 @@ export * from "./appliance-candidate-retire.js";
96
100
  export * from "./host-migrate-vm.js";
97
101
  export * from "./sandbox-tools.js";
98
102
  export * from "./fleet-metrics.js";
103
+ export * from "./appliance-claim-tools.js";
104
+ export * from "./sideload-runner.js";
105
+ export * from "./appliance-id.js";
106
+ export * from "./verify-demo.js";
99
107
  export function registerAllTools(mcpServer, context) {
100
108
  // This registry uses only Zod 3 object shapes and the four-argument tool
101
109
  // form. Keep schema-to-handler inference without expanding the SDK's
@@ -418,5 +426,37 @@ export function registerAllTools(mcpServer, context) {
418
426
  server.tool("ferrum_fleet_metrics", "Query fleet-wide hypervisor telemetry, dynamic 8GB slot occupancy, and Prometheus capacity alert readiness across Proxmox standalone nodes.", FerrumFleetMetricsInputShape, async (args) => {
419
427
  return handleFerrumFleetMetrics(args, context);
420
428
  });
429
+ // 43. list_appliance_claims
430
+ server.tool("list_appliance_claims", "Lists active Kubernetes ApplianceClaim resources (dynamic & fixtures) in ct-lab with phase, IP, VMID, train, and TTL.", ListApplianceClaimsInputShape, async (args) => {
431
+ return handleListApplianceClaims(args, context);
432
+ });
433
+ // 44. get_appliance_claim
434
+ server.tool("get_appliance_claim", "Retrieves full details of a specific ApplianceClaim resource including status, containerOverrides, and conditions.", GetApplianceClaimInputShape, async (args) => {
435
+ return handleGetApplianceClaim(args, context);
436
+ });
437
+ // 45. create_appliance_claim
438
+ server.tool("create_appliance_claim", "Declaratively creates a new ApplianceClaim in Kubernetes with release channel governance, container overrides, and TTL.", CreateApplianceClaimInputShape, async (args) => {
439
+ return handleCreateApplianceClaim(args, context);
440
+ });
441
+ // 46. delete_appliance_claim
442
+ server.tool("delete_appliance_claim", "Deletes an ApplianceClaim in Kubernetes, triggering operator teardown and Proxmox VM cleanup.", DeleteApplianceClaimInputShape, async (args) => {
443
+ return handleDeleteApplianceClaim(args, context);
444
+ });
445
+ // 47. sideload_appliance_runner
446
+ server.tool("sideload_appliance_runner", "Executes isolated sideloaded runner actions (execute, container_override, systemd_reset, diagnostic_bundle) over SSH without mutating in-VM scripts.", SideloadApplianceRunnerInputShape, async (args) => {
447
+ return handleSideloadApplianceRunner(args, context);
448
+ });
449
+ // 48. get_appliance_id
450
+ server.tool("get_appliance_id", "Discovers host hardware UUID over SSH and computes the canonical CT-APP-XXXX-XXXX-XXXX appliance identifier.", GetApplianceIdInputShape, async (args) => {
451
+ return handleGetApplianceId(args, context);
452
+ });
453
+ // 49. sideload_license
454
+ server.tool("sideload_license", "Sideloads a standardized calltelemetry-license-v2 envelope directly to /etc/calltelemetry/calltelemetry.lic with chmod 600.", SideloadLicenseInputShape, async (args) => {
455
+ return handleSideloadLicense(args, context);
456
+ });
457
+ // 50. verify_appliance_demo
458
+ server.tool("verify_appliance_demo", "Executes an automated 5-point demo verification check (API Session, License, CUBEs, Phones, Call Records) certifying demo readiness.", VerifyApplianceDemoInputShape, async (args) => {
459
+ return handleVerifyApplianceDemo(args, context);
460
+ });
421
461
  }
422
462
  //# sourceMappingURL=index.js.map