@calltelemetry/ct-lab-mcp 0.8.69 → 0.8.71

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 (86) hide show
  1. package/README.md +8 -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/proxmox/client.d.ts.map +1 -1
  9. package/dist/src/proxmox/client.js +17 -0
  10. package/dist/src/proxmox/client.js.map +1 -1
  11. package/dist/src/proxmox/mock.d.ts.map +1 -1
  12. package/dist/src/proxmox/mock.js +28 -0
  13. package/dist/src/proxmox/mock.js.map +1 -1
  14. package/dist/src/server.d.ts.map +1 -1
  15. package/dist/src/server.js +1 -0
  16. package/dist/src/server.js.map +1 -1
  17. package/dist/src/slot/purge-controller.d.ts +1 -0
  18. package/dist/src/slot/purge-controller.d.ts.map +1 -1
  19. package/dist/src/slot/purge-controller.js +4 -33
  20. package/dist/src/slot/purge-controller.js.map +1 -1
  21. package/dist/src/tools/appliance-claim-tools.d.ts +11 -7
  22. package/dist/src/tools/appliance-claim-tools.d.ts.map +1 -1
  23. package/dist/src/tools/appliance-claim-tools.js +28 -81
  24. package/dist/src/tools/appliance-claim-tools.js.map +1 -1
  25. package/dist/src/tools/appliance-exec.d.ts +4 -4
  26. package/dist/src/tools/claim-creation-projection.d.ts +7 -0
  27. package/dist/src/tools/claim-creation-projection.d.ts.map +1 -0
  28. package/dist/src/tools/claim-creation-projection.js +112 -0
  29. package/dist/src/tools/claim-creation-projection.js.map +1 -0
  30. package/dist/src/tools/claim-first.d.ts.map +1 -1
  31. package/dist/src/tools/claim-first.js +19 -15
  32. package/dist/src/tools/claim-first.js.map +1 -1
  33. package/dist/src/tools/claimed-import-qcow.d.ts +3 -3
  34. package/dist/src/tools/claimed-import-qcow.d.ts.map +1 -1
  35. package/dist/src/tools/claimed-import-qcow.js +11 -1
  36. package/dist/src/tools/claimed-import-qcow.js.map +1 -1
  37. package/dist/src/tools/cube-provision.d.ts +11 -0
  38. package/dist/src/tools/cube-provision.d.ts.map +1 -1
  39. package/dist/src/tools/cube-provision.js +12 -3
  40. package/dist/src/tools/cube-provision.js.map +1 -1
  41. package/dist/src/tools/host-migrate-vm.d.ts.map +1 -1
  42. package/dist/src/tools/host-migrate-vm.js +10 -1
  43. package/dist/src/tools/host-migrate-vm.js.map +1 -1
  44. package/dist/src/tools/import-qcow.d.ts +7 -7
  45. package/dist/src/tools/import-qcow.d.ts.map +1 -1
  46. package/dist/src/tools/import-qcow.js +13 -3
  47. package/dist/src/tools/import-qcow.js.map +1 -1
  48. package/dist/src/tools/index.d.ts.map +1 -1
  49. package/dist/src/tools/index.js +9 -5
  50. package/dist/src/tools/index.js.map +1 -1
  51. package/dist/src/tools/legacy-guest-guard.d.ts +4 -0
  52. package/dist/src/tools/legacy-guest-guard.d.ts.map +1 -0
  53. package/dist/src/tools/legacy-guest-guard.js +26 -0
  54. package/dist/src/tools/legacy-guest-guard.js.map +1 -0
  55. package/dist/src/tools/license-tools.d.ts +2 -2
  56. package/dist/src/tools/physical-slot-claim-spec-schema.v1.json +1 -0
  57. package/dist/src/tools/physical-slot.d.ts +205 -0
  58. package/dist/src/tools/physical-slot.d.ts.map +1 -0
  59. package/dist/src/tools/physical-slot.js +295 -0
  60. package/dist/src/tools/physical-slot.js.map +1 -0
  61. package/dist/src/tools/provision-tools.d.ts +16 -16
  62. package/dist/src/tools/provision-tools.d.ts.map +1 -1
  63. package/dist/src/tools/provision-tools.js +36 -2
  64. package/dist/src/tools/provision-tools.js.map +1 -1
  65. package/dist/src/tools/quick-provision.d.ts +2 -0
  66. package/dist/src/tools/quick-provision.d.ts.map +1 -1
  67. package/dist/src/tools/quick-provision.js +15 -1
  68. package/dist/src/tools/quick-provision.js.map +1 -1
  69. package/dist/src/tools/sandbox-tools.d.ts +2 -2
  70. package/dist/src/tools/sandbox-tools.d.ts.map +1 -1
  71. package/dist/src/tools/sandbox-tools.js +11 -1
  72. package/dist/src/tools/sandbox-tools.js.map +1 -1
  73. package/dist/src/tools/slot-kubernetes.d.ts +13 -0
  74. package/dist/src/tools/slot-kubernetes.d.ts.map +1 -0
  75. package/dist/src/tools/slot-kubernetes.js +108 -0
  76. package/dist/src/tools/slot-kubernetes.js.map +1 -0
  77. package/dist/src/tools/storage-tools.d.ts +19 -0
  78. package/dist/src/tools/storage-tools.d.ts.map +1 -1
  79. package/dist/src/tools/storage-tools.js +15 -0
  80. package/dist/src/tools/storage-tools.js.map +1 -1
  81. package/dist/src/tools/thin-storage-policy.d.ts +99 -0
  82. package/dist/src/tools/thin-storage-policy.d.ts.map +1 -0
  83. package/dist/src/tools/thin-storage-policy.js +236 -0
  84. package/dist/src/tools/thin-storage-policy.js.map +1 -0
  85. package/dist/src/tools/vm-action.d.ts +8 -8
  86. package/package.json +2 -2
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Thin-only guest disk policy (REL-1588, operator decision 2026-10-08:
3
+ * "Never thick disks").
4
+ *
5
+ * Every guest disk this server creates, clones or imports on Proxmox must live
6
+ * on thin-provisioned storage: `lvmthin` always, `zfspool` only when the pool
7
+ * is proven `sparse`. Anything else (plain `lvm`, `dir`, `nfs`, `iscsi`,
8
+ * `cifs`, `rbd`, an unknown or undeterminable type) is REFUSED with the stable
9
+ * code THICK_STORAGE_REFUSED before the mutating canonical call is made.
10
+ *
11
+ * Fail closed: when the storage type cannot be proven (host unreachable,
12
+ * malformed receipt, pool missing from the host, ...) the request is refused
13
+ * with the same code and a message that says the type could not be determined.
14
+ *
15
+ * Scope note: this module owns the TypeScript layer only. The canonical shell
16
+ * transports in ct-meta carry their own independent guard
17
+ * (`proxmox-thin-storage.sh`); this layer refuses earlier and with a typed
18
+ * error, it does not replace that one. Nothing here builds Proxmox disk
19
+ * options, so discard=on is owned by the transports/templates, not by this
20
+ * server (see docs in README).
21
+ *
22
+ * Storage that is NOT a guest-disk target is deliberately out of scope:
23
+ * `importStorage` (the dir storage that holds the downloaded image before it is
24
+ * imported) and ESXi datastores.
25
+ */
26
+ import { CanonicalLabBridge } from "../canonical/bridge.js";
27
+ import type { IHypervisorDriver } from "../hypervisors/types.js";
28
+ import { CallToolResult } from "../types/mcp.js";
29
+ /** Stable, machine-matchable error code for every thin-only refusal. */
30
+ export declare const THICK_STORAGE_REFUSED: "THICK_STORAGE_REFUSED";
31
+ /**
32
+ * The thin pool on every Proxmox lab host (`local-lvm`, type `lvmthin`). This is
33
+ * also the canonical CLI's default VM-disk storage, so an omitted `storage` is
34
+ * enforced against this pool rather than skipped.
35
+ */
36
+ export declare const DEFAULT_THIN_STORAGE = "local-lvm";
37
+ export type ThinStorageRefusalReason = "thick_storage_type" | "storage_type_undeterminable";
38
+ export interface ThinStorageRefusalDetails extends Record<string, unknown> {
39
+ reason: ThinStorageRefusalReason;
40
+ storage: string;
41
+ storageType?: string;
42
+ hostAssetId?: string;
43
+ thinPool: string;
44
+ }
45
+ export declare class ThickStorageRefusedError extends Error {
46
+ readonly code: "THICK_STORAGE_REFUSED";
47
+ readonly details: ThinStorageRefusalDetails;
48
+ constructor(message: string, details: ThinStorageRefusalDetails);
49
+ }
50
+ /** True when a Proxmox storage of this type provides thin guest disks. */
51
+ export declare function isThinGuestDiskStorage(storageType: string | null | undefined, options?: {
52
+ sparse?: boolean;
53
+ }): boolean;
54
+ export interface AssertThinStorageOptions {
55
+ /** Storage pool name the request targets. */
56
+ storage: string;
57
+ hostAssetId?: string;
58
+ /** Thin pool to recommend in the refusal message. */
59
+ thinPool?: string;
60
+ /** Proven `sparse` flag of a zfspool; absent means not proven. */
61
+ sparse?: boolean;
62
+ }
63
+ /**
64
+ * Pure policy check. Throws ThickStorageRefusedError (code THICK_STORAGE_REFUSED)
65
+ * unless the storage type is thin. An undefined/blank/"unknown" type means the
66
+ * type could not be determined and is refused as such (fail closed).
67
+ */
68
+ export declare function assertThinStorage(storageType: string | null | undefined, options: AssertThinStorageOptions): void;
69
+ export interface CanonicalThinStorageRequest {
70
+ /** Tool name for error details. */
71
+ operation: string;
72
+ /** Exact host asset id, or "auto"/undefined to check every canonical Proxmox host. */
73
+ hostAssetId?: string;
74
+ /** Requested VM-disk storage; omitted means the canonical CLI default pool. */
75
+ storage?: string;
76
+ }
77
+ /**
78
+ * Canonical-mode guard. Resolves the storage type through the same
79
+ * `host capacity` read path as list_storage (no new credentials) and refuses
80
+ * thick or undeterminable storage. Returns an error result to hand straight
81
+ * back to the caller, or undefined when the request may proceed. It must be
82
+ * called BEFORE the mutating canonical CLI call.
83
+ */
84
+ export declare function guardCanonicalThinStorage(bridge: CanonicalLabBridge | undefined, request: CanonicalThinStorageRequest): Promise<CallToolResult | undefined>;
85
+ /**
86
+ * Legacy (non-canonical) clone guard. A clone lands on the explicit `storage`
87
+ * when one is given and otherwise on the storage that holds the source
88
+ * template's disks, so both are resolved against the driver's own storage list.
89
+ * ESXi drivers are out of scope. Missing driver capability fails closed.
90
+ */
91
+ export declare function guardLegacyCloneThinStorage(plan: {
92
+ host: string;
93
+ source: string | number;
94
+ driver: IHypervisorDriver;
95
+ }, request: {
96
+ operation: string;
97
+ storage?: string;
98
+ }): Promise<CallToolResult | undefined>;
99
+ //# sourceMappingURL=thin-storage-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thin-storage-policy.d.ts","sourceRoot":"","sources":["../../../src/tools/thin-storage-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAyB,MAAM,iBAAiB,CAAC;AAOxE,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,EAAG,uBAAgC,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,cAAc,CAAC;AAIhD,MAAM,MAAM,wBAAwB,GAAG,oBAAoB,GAAG,6BAA6B,CAAC;AAE5F,MAAM,WAAW,yBAA0B,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACxE,MAAM,EAAE,wBAAwB,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,IAAI,0BAAyB;IACtC,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC;gBAEhC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB;CAKhE;AAED,0EAA0E;AAC1E,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACtC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAMT;AAED,MAAM,WAAW,wBAAwB;IACvC,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACtC,OAAO,EAAE,wBAAwB,GAChC,IAAI,CA6BN;AAkCD,MAAM,WAAW,2BAA2B;IAC1C,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,kBAAkB,GAAG,SAAS,EACtC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CA0ErC;AAED;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,EAC1E,OAAO,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAgErC"}
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Thin-only guest disk policy (REL-1588, operator decision 2026-10-08:
3
+ * "Never thick disks").
4
+ *
5
+ * Every guest disk this server creates, clones or imports on Proxmox must live
6
+ * on thin-provisioned storage: `lvmthin` always, `zfspool` only when the pool
7
+ * is proven `sparse`. Anything else (plain `lvm`, `dir`, `nfs`, `iscsi`,
8
+ * `cifs`, `rbd`, an unknown or undeterminable type) is REFUSED with the stable
9
+ * code THICK_STORAGE_REFUSED before the mutating canonical call is made.
10
+ *
11
+ * Fail closed: when the storage type cannot be proven (host unreachable,
12
+ * malformed receipt, pool missing from the host, ...) the request is refused
13
+ * with the same code and a message that says the type could not be determined.
14
+ *
15
+ * Scope note: this module owns the TypeScript layer only. The canonical shell
16
+ * transports in ct-meta carry their own independent guard
17
+ * (`proxmox-thin-storage.sh`); this layer refuses earlier and with a typed
18
+ * error, it does not replace that one. Nothing here builds Proxmox disk
19
+ * options, so discard=on is owned by the transports/templates, not by this
20
+ * server (see docs in README).
21
+ *
22
+ * Storage that is NOT a guest-disk target is deliberately out of scope:
23
+ * `importStorage` (the dir storage that holds the downloaded image before it is
24
+ * imported) and ESXi datastores.
25
+ */
26
+ import { createToolErrorResult } from "../types/mcp.js";
27
+ import { parseCanonicalHostCapacity } from "./storage-tools.js";
28
+ import { PROXMOX_SLOT_POLICIES, } from "./proxmox-host-policy.js";
29
+ /** Stable, machine-matchable error code for every thin-only refusal. */
30
+ export const THICK_STORAGE_REFUSED = "THICK_STORAGE_REFUSED";
31
+ /**
32
+ * The thin pool on every Proxmox lab host (`local-lvm`, type `lvmthin`). This is
33
+ * also the canonical CLI's default VM-disk storage, so an omitted `storage` is
34
+ * enforced against this pool rather than skipped.
35
+ */
36
+ export const DEFAULT_THIN_STORAGE = "local-lvm";
37
+ const CANONICAL_PROXMOX_HOSTS = ["proxmox-lab", "proxmox-minis-lab"];
38
+ export class ThickStorageRefusedError extends Error {
39
+ code = THICK_STORAGE_REFUSED;
40
+ details;
41
+ constructor(message, details) {
42
+ super(message);
43
+ this.name = "ThickStorageRefusedError";
44
+ this.details = details;
45
+ }
46
+ }
47
+ /** True when a Proxmox storage of this type provides thin guest disks. */
48
+ export function isThinGuestDiskStorage(storageType, options = {}) {
49
+ const type = (storageType ?? "").trim().toLowerCase();
50
+ if (type === "lvmthin")
51
+ return true;
52
+ // ZFS zvols are thin only when the pool is configured sparse.
53
+ if (type === "zfspool")
54
+ return options.sparse === true;
55
+ return false;
56
+ }
57
+ /**
58
+ * Pure policy check. Throws ThickStorageRefusedError (code THICK_STORAGE_REFUSED)
59
+ * unless the storage type is thin. An undefined/blank/"unknown" type means the
60
+ * type could not be determined and is refused as such (fail closed).
61
+ */
62
+ export function assertThinStorage(storageType, options) {
63
+ const thinPool = options.thinPool ?? DEFAULT_THIN_STORAGE;
64
+ const type = (storageType ?? "").trim();
65
+ const where = options.hostAssetId ? ` on host '${options.hostAssetId}'` : "";
66
+ const base = {
67
+ storage: options.storage,
68
+ thinPool,
69
+ ...(options.hostAssetId ? { hostAssetId: options.hostAssetId } : {}),
70
+ };
71
+ if (!type || type.toLowerCase() === "unknown") {
72
+ throw new ThickStorageRefusedError(`${THICK_STORAGE_REFUSED}: the type of storage '${options.storage}'${where} could not be determined, so it cannot be proven thin. `
73
+ + `Guest disks must be thin-provisioned (lvmthin, or zfspool with sparse=1) with discard=on; refusing fail-closed. `
74
+ + `Use thin pool '${thinPool}'. No Proxmox change was made.`, { ...base, reason: "storage_type_undeterminable" });
75
+ }
76
+ if (isThinGuestDiskStorage(type, { sparse: options.sparse }))
77
+ return;
78
+ const detail = type.toLowerCase() === "zfspool"
79
+ ? "zfspool is thin only with sparse=1, which was not proven"
80
+ : "not thin-provisioned";
81
+ throw new ThickStorageRefusedError(`${THICK_STORAGE_REFUSED}: storage '${options.storage}'${where} has type '${type}' (${detail}). `
82
+ + `Guest disks must be thin-provisioned (lvmthin, or zfspool with sparse=1) with discard=on; never thick. `
83
+ + `Use thin pool '${thinPool}' instead. No Proxmox change was made.`, { ...base, reason: "thick_storage_type", storageType: type });
84
+ }
85
+ function refusalResult(error, operation) {
86
+ return createToolErrorResult(error.code, error.message, { operation, ...error.details });
87
+ }
88
+ function undeterminable(storage, hostAssetId, why, thinPool) {
89
+ const where = hostAssetId ? ` on host '${hostAssetId}'` : "";
90
+ return new ThickStorageRefusedError(`${THICK_STORAGE_REFUSED}: the type of storage '${storage}'${where} could not be determined (${why}), so it cannot be proven thin. `
91
+ + `Guest disks must be thin-provisioned (lvmthin, or zfspool with sparse=1) with discard=on; refusing fail-closed. `
92
+ + `Use thin pool '${thinPool}'. No Proxmox change was made.`, {
93
+ reason: "storage_type_undeterminable",
94
+ storage,
95
+ thinPool,
96
+ ...(hostAssetId ? { hostAssetId } : {}),
97
+ });
98
+ }
99
+ function canonicalHostAlias(hostAssetId) {
100
+ return hostAssetId === "proxmox-mini" ? "proxmox-minis-lab" : hostAssetId;
101
+ }
102
+ function defaultThinPoolFor(hostAssetId) {
103
+ return PROXMOX_SLOT_POLICIES[hostAssetId]?.storage ?? DEFAULT_THIN_STORAGE;
104
+ }
105
+ /**
106
+ * Canonical-mode guard. Resolves the storage type through the same
107
+ * `host capacity` read path as list_storage (no new credentials) and refuses
108
+ * thick or undeterminable storage. Returns an error result to hand straight
109
+ * back to the caller, or undefined when the request may proceed. It must be
110
+ * called BEFORE the mutating canonical CLI call.
111
+ */
112
+ export async function guardCanonicalThinStorage(bridge, request) {
113
+ const requestedHost = request.hostAssetId?.trim();
114
+ const hosts = !requestedHost || requestedHost === "auto"
115
+ ? [...CANONICAL_PROXMOX_HOSTS]
116
+ : [canonicalHostAlias(requestedHost)];
117
+ const auto = hosts.length > 1;
118
+ let verified = 0;
119
+ let missingOn;
120
+ try {
121
+ for (const hostAssetId of hosts) {
122
+ // An omitted storage means the canonical CLI default pool: still enforce it.
123
+ const storage = request.storage?.trim() || defaultThinPoolFor(hostAssetId);
124
+ const fallbackThin = defaultThinPoolFor(hostAssetId);
125
+ if (!bridge) {
126
+ throw undeterminable(storage, hostAssetId, "the canonical lab bridge is not available", fallbackThin);
127
+ }
128
+ let result;
129
+ try {
130
+ result = await bridge.run(["host", "capacity", "--asset-id", hostAssetId]);
131
+ }
132
+ catch (error) {
133
+ throw undeterminable(storage, hostAssetId, `host capacity failed: ${error instanceof Error ? error.message : String(error)}`, fallbackThin);
134
+ }
135
+ if (result.timedOut || result.exitCode !== 0) {
136
+ throw undeterminable(storage, hostAssetId, result.timedOut ? "host capacity timed out" : `host capacity exited ${result.exitCode}`, fallbackThin);
137
+ }
138
+ const capacity = parseCanonicalHostCapacity(result.stdout, hostAssetId);
139
+ if (!capacity) {
140
+ throw undeterminable(storage, hostAssetId, "host capacity returned an invalid receipt", fallbackThin);
141
+ }
142
+ // ESXi datastores are outside the Proxmox thin-only decision.
143
+ if (capacity.hypervisor !== "proxmox")
144
+ continue;
145
+ const thinPool = capacity.pools.find((pool) => pool.type.toLowerCase() === "lvmthin" && pool.content?.split(",").includes("images"))?.storage ?? fallbackThin;
146
+ const pool = capacity.pools.find((candidate) => candidate.storage === storage);
147
+ if (!pool) {
148
+ const known = capacity.pools.map((p) => p.storage).join(", ") || "none";
149
+ // With host=auto the canonical CLI cannot place on a host that lacks the
150
+ // pool, so only an exact host (or every host lacking it) is undeterminable.
151
+ if (!auto) {
152
+ throw undeterminable(storage, hostAssetId, `the pool is not defined on that host; known pools: ${known}`, thinPool);
153
+ }
154
+ missingOn ??= { storage, hostAssetId, known, thinPool };
155
+ continue;
156
+ }
157
+ assertThinStorage(pool.type, { storage, hostAssetId, thinPool, sparse: pool.sparse });
158
+ verified += 1;
159
+ }
160
+ if (auto && verified === 0 && missingOn) {
161
+ throw undeterminable(missingOn.storage, undefined, `the pool is not defined on any canonical Proxmox host; known pools on ${missingOn.hostAssetId}: ${missingOn.known}`, missingOn.thinPool);
162
+ }
163
+ }
164
+ catch (error) {
165
+ if (error instanceof ThickStorageRefusedError)
166
+ return refusalResult(error, request.operation);
167
+ throw error;
168
+ }
169
+ return undefined;
170
+ }
171
+ /**
172
+ * Legacy (non-canonical) clone guard. A clone lands on the explicit `storage`
173
+ * when one is given and otherwise on the storage that holds the source
174
+ * template's disks, so both are resolved against the driver's own storage list.
175
+ * ESXi drivers are out of scope. Missing driver capability fails closed.
176
+ */
177
+ export async function guardLegacyCloneThinStorage(plan, request) {
178
+ const { driver } = plan;
179
+ if (driver.hypervisorType !== "proxmox")
180
+ return undefined;
181
+ const hostAssetId = plan.host;
182
+ const fallbackThin = defaultThinPoolFor(canonicalHostAlias(hostAssetId));
183
+ try {
184
+ let targets;
185
+ if (request.storage?.trim()) {
186
+ targets = [request.storage.trim()];
187
+ }
188
+ else {
189
+ if (!driver.getVmStorage) {
190
+ throw undeterminable(String(plan.source), hostAssetId, "the clone source's disks cannot be read", fallbackThin);
191
+ }
192
+ let report;
193
+ try {
194
+ report = await driver.getVmStorage(plan.source);
195
+ }
196
+ catch (error) {
197
+ throw undeterminable(String(plan.source), hostAssetId, `reading the clone source's disks failed: ${error instanceof Error ? error.message : String(error)}`, fallbackThin);
198
+ }
199
+ targets = [...new Set(report.disks.map((disk) => disk.storage))];
200
+ if (targets.length === 0) {
201
+ throw undeterminable(String(plan.source), hostAssetId, "the clone source reports no disks", fallbackThin);
202
+ }
203
+ }
204
+ if (!driver.listStorage) {
205
+ throw undeterminable(targets[0], hostAssetId, "the host cannot list its storage pools", fallbackThin);
206
+ }
207
+ let pools;
208
+ try {
209
+ pools = await driver.listStorage();
210
+ }
211
+ catch (error) {
212
+ throw undeterminable(targets[0], hostAssetId, `listing storage pools failed: ${error instanceof Error ? error.message : String(error)}`, fallbackThin);
213
+ }
214
+ const thinPool = pools.find((pool) => pool.type.toLowerCase() === "lvmthin" && pool.content?.split(",").includes("images"))
215
+ ?.storage ?? fallbackThin;
216
+ for (const storage of targets) {
217
+ const pool = pools.find((candidate) => candidate.storage === storage);
218
+ if (!pool) {
219
+ throw undeterminable(storage, hostAssetId, "the pool is not defined on that host", thinPool);
220
+ }
221
+ assertThinStorage(pool.type, {
222
+ storage,
223
+ hostAssetId,
224
+ thinPool,
225
+ sparse: pool.sparse,
226
+ });
227
+ }
228
+ }
229
+ catch (error) {
230
+ if (error instanceof ThickStorageRefusedError)
231
+ return refusalResult(error, request.operation);
232
+ throw error;
233
+ }
234
+ return undefined;
235
+ }
236
+ //# sourceMappingURL=thin-storage-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thin-storage-policy.js","sourceRoot":"","sources":["../../../src/tools/thin-storage-policy.ts"],"names":[],"mappings":"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"}
@@ -137,17 +137,17 @@ 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;
145
145
  targetHost?: string | undefined;
146
+ vmIdOrName?: string | number | undefined;
146
147
  confirmVmid?: string | number | undefined;
147
148
  smbiosUuid?: string | undefined;
148
149
  confirmHostAssetId?: string | undefined;
149
150
  confirmSmbiosUuid?: string | undefined;
150
- vmIdOrName?: string | number | undefined;
151
151
  cloneOptions?: {
152
152
  full: boolean;
153
153
  name?: string | undefined;
@@ -168,21 +168,21 @@ 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;
176
176
  force?: boolean | undefined;
177
177
  confirmAssetId?: string | undefined;
178
178
  targetHost?: string | undefined;
179
+ vmIdOrName?: string | number | undefined;
179
180
  confirmVmid?: string | number | undefined;
180
181
  smbiosUuid?: string | undefined;
181
182
  confirmHostAssetId?: string | undefined;
182
183
  confirmSmbiosUuid?: string | undefined;
183
184
  ackUntracked?: boolean | undefined;
184
185
  ackManualCleanup?: boolean | undefined;
185
- vmIdOrName?: string | number | undefined;
186
186
  cloneOptions?: {
187
187
  name?: string | undefined;
188
188
  tags?: string | string[] | undefined;
@@ -207,17 +207,17 @@ 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;
215
215
  targetHost?: string | undefined;
216
+ vmIdOrName?: string | number | undefined;
216
217
  confirmVmid?: string | number | undefined;
217
218
  smbiosUuid?: string | undefined;
218
219
  confirmHostAssetId?: string | undefined;
219
220
  confirmSmbiosUuid?: string | undefined;
220
- vmIdOrName?: string | number | undefined;
221
221
  cloneOptions?: {
222
222
  full: boolean;
223
223
  name?: string | undefined;
@@ -238,21 +238,21 @@ 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;
246
246
  force?: boolean | undefined;
247
247
  confirmAssetId?: string | undefined;
248
248
  targetHost?: string | undefined;
249
+ vmIdOrName?: string | number | undefined;
249
250
  confirmVmid?: string | number | undefined;
250
251
  smbiosUuid?: string | undefined;
251
252
  confirmHostAssetId?: string | undefined;
252
253
  confirmSmbiosUuid?: string | undefined;
253
254
  ackUntracked?: boolean | undefined;
254
255
  ackManualCleanup?: boolean | undefined;
255
- vmIdOrName?: string | number | undefined;
256
256
  cloneOptions?: {
257
257
  name?: string | undefined;
258
258
  tags?: string | string[] | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@calltelemetry/ct-lab-mcp",
3
- "version": "0.8.69",
3
+ "version": "0.8.71",
4
4
  "description": "Expanded Model Context Protocol (MCP) server for Call Telemetry lab, fleet, and appliance management across Proxmox VE and VMware ESXi.",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -15,7 +15,7 @@
15
15
  "LICENSE"
16
16
  ],
17
17
  "scripts": {
18
- "build": "tsc -p tsconfig.build.json && chmod +x dist/bin/*.js",
18
+ "build": "tsc -p tsconfig.build.json && node tools/copy-physical-slot-schema.mjs && chmod +x dist/bin/*.js",
19
19
  "typecheck": "tsc --noEmit",
20
20
  "pretest": "npm run build",
21
21
  "test": "vitest run",