@calltelemetry/ct-lab-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +309 -0
- package/dist/bin/ct-lab-mcp.d.ts +60 -0
- package/dist/bin/ct-lab-mcp.d.ts.map +1 -0
- package/dist/bin/ct-lab-mcp.js +261 -0
- package/dist/bin/ct-lab-mcp.js.map +1 -0
- package/dist/bin/proxmox-mcp.d.ts +58 -0
- package/dist/bin/proxmox-mcp.d.ts.map +1 -0
- package/dist/bin/proxmox-mcp.js +248 -0
- package/dist/bin/proxmox-mcp.js.map +1 -0
- package/dist/src/appliance/commands.d.ts +33 -0
- package/dist/src/appliance/commands.d.ts.map +1 -0
- package/dist/src/appliance/commands.js +241 -0
- package/dist/src/appliance/commands.js.map +1 -0
- package/dist/src/appliance/executor.d.ts +34 -0
- package/dist/src/appliance/executor.d.ts.map +1 -0
- package/dist/src/appliance/executor.js +214 -0
- package/dist/src/appliance/executor.js.map +1 -0
- package/dist/src/appliance/index.d.ts +8 -0
- package/dist/src/appliance/index.d.ts.map +1 -0
- package/dist/src/appliance/index.js +8 -0
- package/dist/src/appliance/index.js.map +1 -0
- package/dist/src/appliance/mock.d.ts +66 -0
- package/dist/src/appliance/mock.d.ts.map +1 -0
- package/dist/src/appliance/mock.js +339 -0
- package/dist/src/appliance/mock.js.map +1 -0
- package/dist/src/appliance/types.d.ts +83 -0
- package/dist/src/appliance/types.d.ts.map +1 -0
- package/dist/src/appliance/types.js +58 -0
- package/dist/src/appliance/types.js.map +1 -0
- package/dist/src/credentials/doppler.d.ts +25 -0
- package/dist/src/credentials/doppler.d.ts.map +1 -0
- package/dist/src/credentials/doppler.js +68 -0
- package/dist/src/credentials/doppler.js.map +1 -0
- package/dist/src/credentials/index.d.ts +4 -0
- package/dist/src/credentials/index.d.ts.map +1 -0
- package/dist/src/credentials/index.js +4 -0
- package/dist/src/credentials/index.js.map +1 -0
- package/dist/src/credentials/resolver.d.ts +36 -0
- package/dist/src/credentials/resolver.d.ts.map +1 -0
- package/dist/src/credentials/resolver.js +427 -0
- package/dist/src/credentials/resolver.js.map +1 -0
- package/dist/src/credentials/types.d.ts +73 -0
- package/dist/src/credentials/types.d.ts.map +1 -0
- package/dist/src/credentials/types.js +5 -0
- package/dist/src/credentials/types.js.map +1 -0
- package/dist/src/guardrails/index.d.ts +3 -0
- package/dist/src/guardrails/index.d.ts.map +1 -0
- package/dist/src/guardrails/index.js +3 -0
- package/dist/src/guardrails/index.js.map +1 -0
- package/dist/src/guardrails/safety.d.ts +45 -0
- package/dist/src/guardrails/safety.d.ts.map +1 -0
- package/dist/src/guardrails/safety.js +217 -0
- package/dist/src/guardrails/safety.js.map +1 -0
- package/dist/src/guardrails/types.d.ts +36 -0
- package/dist/src/guardrails/types.d.ts.map +1 -0
- package/dist/src/guardrails/types.js +20 -0
- package/dist/src/guardrails/types.js.map +1 -0
- package/dist/src/hypervisors/esxi/client.d.ts +103 -0
- package/dist/src/hypervisors/esxi/client.d.ts.map +1 -0
- package/dist/src/hypervisors/esxi/client.js +395 -0
- package/dist/src/hypervisors/esxi/client.js.map +1 -0
- package/dist/src/hypervisors/esxi/mock.d.ts +45 -0
- package/dist/src/hypervisors/esxi/mock.d.ts.map +1 -0
- package/dist/src/hypervisors/esxi/mock.js +202 -0
- package/dist/src/hypervisors/esxi/mock.js.map +1 -0
- package/dist/src/hypervisors/index.d.ts +10 -0
- package/dist/src/hypervisors/index.d.ts.map +1 -0
- package/dist/src/hypervisors/index.js +10 -0
- package/dist/src/hypervisors/index.js.map +1 -0
- package/dist/src/hypervisors/manager.d.ts +78 -0
- package/dist/src/hypervisors/manager.d.ts.map +1 -0
- package/dist/src/hypervisors/manager.js +415 -0
- package/dist/src/hypervisors/manager.js.map +1 -0
- package/dist/src/hypervisors/proxmox/client.d.ts +29 -0
- package/dist/src/hypervisors/proxmox/client.d.ts.map +1 -0
- package/dist/src/hypervisors/proxmox/client.js +278 -0
- package/dist/src/hypervisors/proxmox/client.js.map +1 -0
- package/dist/src/hypervisors/proxmox/mock.d.ts +17 -0
- package/dist/src/hypervisors/proxmox/mock.d.ts.map +1 -0
- package/dist/src/hypervisors/proxmox/mock.js +26 -0
- package/dist/src/hypervisors/proxmox/mock.js.map +1 -0
- package/dist/src/hypervisors/types.d.ts +159 -0
- package/dist/src/hypervisors/types.d.ts.map +1 -0
- package/dist/src/hypervisors/types.js +6 -0
- package/dist/src/hypervisors/types.js.map +1 -0
- package/dist/src/index.d.ts +19 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +19 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/proxmox/client.d.ts +37 -0
- package/dist/src/proxmox/client.d.ts.map +1 -0
- package/dist/src/proxmox/client.js +282 -0
- package/dist/src/proxmox/client.js.map +1 -0
- package/dist/src/proxmox/index.d.ts +53 -0
- package/dist/src/proxmox/index.d.ts.map +1 -0
- package/dist/src/proxmox/index.js +109 -0
- package/dist/src/proxmox/index.js.map +1 -0
- package/dist/src/proxmox/mock.d.ts +40 -0
- package/dist/src/proxmox/mock.d.ts.map +1 -0
- package/dist/src/proxmox/mock.js +362 -0
- package/dist/src/proxmox/mock.js.map +1 -0
- package/dist/src/proxmox/poller.d.ts +29 -0
- package/dist/src/proxmox/poller.d.ts.map +1 -0
- package/dist/src/proxmox/poller.js +107 -0
- package/dist/src/proxmox/poller.js.map +1 -0
- package/dist/src/server/index.d.ts +2 -0
- package/dist/src/server/index.d.ts.map +1 -0
- package/dist/src/server/index.js +2 -0
- package/dist/src/server/index.js.map +1 -0
- package/dist/src/server/mcp-server.d.ts +5 -0
- package/dist/src/server/mcp-server.d.ts.map +1 -0
- package/dist/src/server/mcp-server.js +5 -0
- package/dist/src/server/mcp-server.js.map +1 -0
- package/dist/src/server.d.ts +35 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +95 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/slot/gc.d.ts +42 -0
- package/dist/src/slot/gc.d.ts.map +1 -0
- package/dist/src/slot/gc.js +79 -0
- package/dist/src/slot/gc.js.map +1 -0
- package/dist/src/slot/index.d.ts +4 -0
- package/dist/src/slot/index.d.ts.map +1 -0
- package/dist/src/slot/index.js +4 -0
- package/dist/src/slot/index.js.map +1 -0
- package/dist/src/slot/manager.d.ts +92 -0
- package/dist/src/slot/manager.d.ts.map +1 -0
- package/dist/src/slot/manager.js +650 -0
- package/dist/src/slot/manager.js.map +1 -0
- package/dist/src/slot/types.d.ts +184 -0
- package/dist/src/slot/types.d.ts.map +1 -0
- package/dist/src/slot/types.js +67 -0
- package/dist/src/slot/types.js.map +1 -0
- package/dist/src/tools/appliance-exec.d.ts +81 -0
- package/dist/src/tools/appliance-exec.d.ts.map +1 -0
- package/dist/src/tools/appliance-exec.js +134 -0
- package/dist/src/tools/appliance-exec.js.map +1 -0
- package/dist/src/tools/claim-slot.d.ts +5 -0
- package/dist/src/tools/claim-slot.d.ts.map +1 -0
- package/dist/src/tools/claim-slot.js +5 -0
- package/dist/src/tools/claim-slot.js.map +1 -0
- package/dist/src/tools/index.d.ts +26 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +63 -0
- package/dist/src/tools/index.js.map +1 -0
- package/dist/src/tools/list-hosts.d.ts +41 -0
- package/dist/src/tools/list-hosts.d.ts.map +1 -0
- package/dist/src/tools/list-hosts.js +91 -0
- package/dist/src/tools/list-hosts.js.map +1 -0
- package/dist/src/tools/list-inventory.d.ts +50 -0
- package/dist/src/tools/list-inventory.d.ts.map +1 -0
- package/dist/src/tools/list-inventory.js +112 -0
- package/dist/src/tools/list-inventory.js.map +1 -0
- package/dist/src/tools/list-slots.d.ts +5 -0
- package/dist/src/tools/list-slots.d.ts.map +1 -0
- package/dist/src/tools/list-slots.js +5 -0
- package/dist/src/tools/list-slots.js.map +1 -0
- package/dist/src/tools/provision-tools.d.ts +231 -0
- package/dist/src/tools/provision-tools.d.ts.map +1 -0
- package/dist/src/tools/provision-tools.js +289 -0
- package/dist/src/tools/provision-tools.js.map +1 -0
- package/dist/src/tools/release-slot.d.ts +5 -0
- package/dist/src/tools/release-slot.d.ts.map +1 -0
- package/dist/src/tools/release-slot.js +5 -0
- package/dist/src/tools/release-slot.js.map +1 -0
- package/dist/src/tools/slot-tools.d.ts +173 -0
- package/dist/src/tools/slot-tools.d.ts.map +1 -0
- package/dist/src/tools/slot-tools.js +296 -0
- package/dist/src/tools/slot-tools.js.map +1 -0
- package/dist/src/tools/vm-action.d.ts +189 -0
- package/dist/src/tools/vm-action.d.ts.map +1 -0
- package/dist/src/tools/vm-action.js +300 -0
- package/dist/src/tools/vm-action.js.map +1 -0
- package/dist/src/transports/index.d.ts +3 -0
- package/dist/src/transports/index.d.ts.map +1 -0
- package/dist/src/transports/index.js +3 -0
- package/dist/src/transports/index.js.map +1 -0
- package/dist/src/transports/sse.d.ts +38 -0
- package/dist/src/transports/sse.d.ts.map +1 -0
- package/dist/src/transports/sse.js +167 -0
- package/dist/src/transports/sse.js.map +1 -0
- package/dist/src/transports/stdio.d.ts +15 -0
- package/dist/src/transports/stdio.d.ts.map +1 -0
- package/dist/src/transports/stdio.js +34 -0
- package/dist/src/transports/stdio.js.map +1 -0
- package/dist/src/types/config.d.ts +17 -0
- package/dist/src/types/config.d.ts.map +1 -0
- package/dist/src/types/config.js +5 -0
- package/dist/src/types/config.js.map +1 -0
- package/dist/src/types/index.d.ts +4 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +4 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/mcp.d.ts +38 -0
- package/dist/src/types/mcp.d.ts.map +1 -0
- package/dist/src/types/mcp.js +46 -0
- package/dist/src/types/mcp.js.map +1 -0
- package/dist/src/types/proxmox.d.ts +181 -0
- package/dist/src/types/proxmox.d.ts.map +1 -0
- package/dist/src/types/proxmox.js +5 -0
- package/dist/src/types/proxmox.js.map +1 -0
- package/dist/src/types/slot.d.ts +5 -0
- package/dist/src/types/slot.d.ts.map +1 -0
- package/dist/src/types/slot.js +5 -0
- package/dist/src/types/slot.js.map +1 -0
- package/dist/src/utils/formatters.d.ts +71 -0
- package/dist/src/utils/formatters.d.ts.map +1 -0
- package/dist/src/utils/formatters.js +480 -0
- package/dist/src/utils/formatters.js.map +1 -0
- package/dist/src/utils/index.d.ts +6 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +6 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/logger.d.ts +28 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +74 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/mutex.d.ts +32 -0
- package/dist/src/utils/mutex.d.ts.map +1 -0
- package/dist/src/utils/mutex.js +86 -0
- package/dist/src/utils/mutex.js.map +1 -0
- package/dist/src/utils/redact.d.ts +6 -0
- package/dist/src/utils/redact.d.ts.map +1 -0
- package/dist/src/utils/redact.js +6 -0
- package/dist/src/utils/redact.js.map +1 -0
- package/dist/src/utils/redactor.d.ts +50 -0
- package/dist/src/utils/redactor.d.ts.map +1 -0
- package/dist/src/utils/redactor.js +170 -0
- package/dist/src/utils/redactor.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VM Action MCP Tool Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles VM lifecycle operations (start, stop, reboot, shutdown, reset, status, clone, destroy)
|
|
5
|
+
* with non-bypassable safety guardrail enforcement protecting core fixtures and templates.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { ProxmoxErrorCode, createToolErrorResult, } from "../types/index.js";
|
|
9
|
+
import { defaultSafetyGuardrailEngine, ProtectedVmViolationError, } from "../guardrails/safety.js";
|
|
10
|
+
import { formatVmActionResult } from "../utils/formatters.js";
|
|
11
|
+
export const VmActionInputShape = {
|
|
12
|
+
vmIdOrName: z
|
|
13
|
+
.union([z.string().min(1), z.number().int().positive("VMID must be a positive integer.")])
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("Target VMID (e.g. 105, 104) or VM name/path (e.g. 'ct-appliance-uat-105', 'CUCM14-01-6-30')."),
|
|
16
|
+
vmid: z
|
|
17
|
+
.union([z.string().min(1), z.number().int().positive("VMID must be a positive integer.")])
|
|
18
|
+
.optional()
|
|
19
|
+
.describe("Proxmox Virtual Machine ID or identifier (alias for vmIdOrName)."),
|
|
20
|
+
host: z
|
|
21
|
+
.string()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("Target hypervisor host hosting the VM (e.g. 'proxmox-lab', 'proxmox-mini', 'esxi-intel-192-168-123-176')."),
|
|
24
|
+
targetHost: z
|
|
25
|
+
.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe("Alias for host."),
|
|
28
|
+
action: z
|
|
29
|
+
.enum(["start", "stop", "reboot", "shutdown", "reset", "status", "clone", "destroy", "config"])
|
|
30
|
+
.describe("VM lifecycle action to execute."),
|
|
31
|
+
cloneOptions: z
|
|
32
|
+
.object({
|
|
33
|
+
newid: z.number().int().positive().optional().describe("Target VMID for the cloned VM."),
|
|
34
|
+
newVmId: z.union([z.string(), z.number()]).optional(),
|
|
35
|
+
name: z.string().optional().describe("Name for the new cloned VM."),
|
|
36
|
+
newVmName: z.string().optional(),
|
|
37
|
+
targetHost: z.string().optional().describe("Target host for the clone if cross-node."),
|
|
38
|
+
full: z.boolean().optional().default(true).describe("Full clone vs linked clone."),
|
|
39
|
+
vlan: z.number().int().optional(),
|
|
40
|
+
ipAddress: z.string().optional(),
|
|
41
|
+
macAddress: z.string().optional(),
|
|
42
|
+
linearIssue: z.string().optional(),
|
|
43
|
+
tags: z.union([z.array(z.string()), z.string()]).optional(),
|
|
44
|
+
})
|
|
45
|
+
.optional()
|
|
46
|
+
.describe("Configuration options required when action is 'clone'."),
|
|
47
|
+
force: z
|
|
48
|
+
.boolean()
|
|
49
|
+
.optional()
|
|
50
|
+
.default(false)
|
|
51
|
+
.describe("Force action (e.g. hard power-off stop or force destroy). Note: Guardrails cannot be bypassed with force=true."),
|
|
52
|
+
timeoutSeconds: z
|
|
53
|
+
.number()
|
|
54
|
+
.int()
|
|
55
|
+
.min(1)
|
|
56
|
+
.max(600)
|
|
57
|
+
.optional()
|
|
58
|
+
.describe("Timeout in seconds to wait for task completion."),
|
|
59
|
+
};
|
|
60
|
+
export const VmActionInputSchema = z
|
|
61
|
+
.object(VmActionInputShape)
|
|
62
|
+
.refine((data) => data.vmIdOrName !== undefined || data.vmid !== undefined, { message: "Either 'vmIdOrName' or 'vmid' must be provided." });
|
|
63
|
+
export async function handleVmAction(rawArgs, context) {
|
|
64
|
+
try {
|
|
65
|
+
const parseResult = VmActionInputSchema.safeParse(rawArgs);
|
|
66
|
+
if (!parseResult.success) {
|
|
67
|
+
const errMsg = parseResult.error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join("; ");
|
|
68
|
+
return createToolErrorResult(ProxmoxErrorCode.VALIDATION_ERROR, errMsg);
|
|
69
|
+
}
|
|
70
|
+
const args = parseResult.data;
|
|
71
|
+
const targetVm = (args.vmIdOrName !== undefined ? args.vmIdOrName : args.vmid);
|
|
72
|
+
const targetHost = args.host || args.targetHost;
|
|
73
|
+
const guardrailEngine = context.guardrailEngine || defaultSafetyGuardrailEngine;
|
|
74
|
+
let vmName = String(targetVm);
|
|
75
|
+
let isProtected;
|
|
76
|
+
let protectionReason;
|
|
77
|
+
let isTemplate;
|
|
78
|
+
let tags;
|
|
79
|
+
let hostName = targetHost || "unknown";
|
|
80
|
+
if (context.hypervisorManager) {
|
|
81
|
+
const found = await context.hypervisorManager.findVm(targetVm, targetHost);
|
|
82
|
+
if (found) {
|
|
83
|
+
vmName = found.vm.name;
|
|
84
|
+
isProtected = found.vm.isProtected;
|
|
85
|
+
protectionReason = found.vm.protectionReason;
|
|
86
|
+
isTemplate = found.vm.isTemplate;
|
|
87
|
+
tags = found.vm.tags;
|
|
88
|
+
hostName = found.driver.hostName;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (vmName === String(targetVm) && context.proxmoxManager) {
|
|
92
|
+
const hostId = (targetHost || "proxmox-lab");
|
|
93
|
+
try {
|
|
94
|
+
const client = context.proxmoxManager.getClient(hostId);
|
|
95
|
+
const vms = await client.listVms();
|
|
96
|
+
const found = vms.find((v) => v.vmid === Number(targetVm) || v.name.toLowerCase() === String(targetVm).toLowerCase());
|
|
97
|
+
if (found) {
|
|
98
|
+
vmName = found.name;
|
|
99
|
+
isTemplate = found.template;
|
|
100
|
+
tags = typeof found.tags === "string" ? found.tags.split(";") : undefined;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch { }
|
|
104
|
+
}
|
|
105
|
+
// Validate guardrails
|
|
106
|
+
const vmTarget = {
|
|
107
|
+
vmid: targetVm,
|
|
108
|
+
name: vmName,
|
|
109
|
+
isProtected,
|
|
110
|
+
protectionReason,
|
|
111
|
+
template: isTemplate,
|
|
112
|
+
tags,
|
|
113
|
+
hostId: hostName,
|
|
114
|
+
};
|
|
115
|
+
try {
|
|
116
|
+
guardrailEngine.validateAction(vmTarget, args.action, args.force);
|
|
117
|
+
}
|
|
118
|
+
catch (guardrailErr) {
|
|
119
|
+
if (guardrailErr instanceof ProtectedVmViolationError) {
|
|
120
|
+
return createToolErrorResult(ProxmoxErrorCode.PROTECTED_VM_ACTION_DENIED, guardrailErr.message, {
|
|
121
|
+
vmid: guardrailErr.vmid,
|
|
122
|
+
vmName: guardrailErr.vmName,
|
|
123
|
+
action: guardrailErr.action,
|
|
124
|
+
reason: guardrailErr.reason,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
throw guardrailErr;
|
|
128
|
+
}
|
|
129
|
+
// 1. If hypervisorManager is available, use unified multi-hypervisor manager
|
|
130
|
+
if (context.hypervisorManager) {
|
|
131
|
+
if (args.action === "clone") {
|
|
132
|
+
const cloneOpts = args.cloneOptions;
|
|
133
|
+
const newName = cloneOpts?.name || cloneOpts?.newVmName || `clone-${targetVm}`;
|
|
134
|
+
const newId = cloneOpts?.newid || cloneOpts?.newVmId;
|
|
135
|
+
const res = await context.hypervisorManager.provisionVm({
|
|
136
|
+
sourceVmIdOrName: targetVm,
|
|
137
|
+
newVmName: newName,
|
|
138
|
+
newVmId: newId,
|
|
139
|
+
targetHost: cloneOpts?.targetHost || targetHost,
|
|
140
|
+
fullClone: cloneOpts?.full,
|
|
141
|
+
vlan: cloneOpts?.vlan,
|
|
142
|
+
ipAddress: cloneOpts?.ipAddress,
|
|
143
|
+
macAddress: cloneOpts?.macAddress,
|
|
144
|
+
linearIssue: cloneOpts?.linearIssue,
|
|
145
|
+
tags: Array.isArray(cloneOpts?.tags) ? cloneOpts.tags : (cloneOpts?.tags ? [cloneOpts.tags] : undefined),
|
|
146
|
+
});
|
|
147
|
+
const formatted = formatVmActionResult({
|
|
148
|
+
host: res.hostName,
|
|
149
|
+
vmid: typeof targetVm === "number" ? targetVm : parseInt(String(targetVm), 10) || 100,
|
|
150
|
+
action: "clone",
|
|
151
|
+
success: true,
|
|
152
|
+
message: `Successfully cloned VM '${targetVm}' to '${res.name}' (${res.vmId}) on host '${res.hostName}'.`,
|
|
153
|
+
details: { clonedVm: res },
|
|
154
|
+
});
|
|
155
|
+
return {
|
|
156
|
+
content: [{ type: "text", text: formatted.markdown }],
|
|
157
|
+
structuredContent: formatted.structuredContent,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
const actionParams = {
|
|
161
|
+
vmIdOrName: targetVm,
|
|
162
|
+
action: args.action,
|
|
163
|
+
force: args.force,
|
|
164
|
+
targetHost: targetHost,
|
|
165
|
+
timeoutSeconds: args.timeoutSeconds,
|
|
166
|
+
};
|
|
167
|
+
const result = await context.hypervisorManager.vmAction(actionParams);
|
|
168
|
+
const formatted = formatVmActionResult({
|
|
169
|
+
host: result.hostName,
|
|
170
|
+
vmid: typeof targetVm === "number" ? targetVm : parseInt(String(targetVm), 10) || 100,
|
|
171
|
+
action: result.action,
|
|
172
|
+
success: result.success,
|
|
173
|
+
message: result.message,
|
|
174
|
+
details: {
|
|
175
|
+
previousStatus: result.previousStatus,
|
|
176
|
+
newStatus: result.newStatus,
|
|
177
|
+
hypervisor: result.hypervisor,
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
return {
|
|
181
|
+
content: [{ type: "text", text: formatted.markdown }],
|
|
182
|
+
structuredContent: formatted.structuredContent,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
// 2. Standalone ProxmoxManager fallback
|
|
186
|
+
if (!context.proxmoxManager) {
|
|
187
|
+
return createToolErrorResult(ProxmoxErrorCode.UPSTREAM_API_ERROR, "No hypervisor manager configured on this MCP server instance.");
|
|
188
|
+
}
|
|
189
|
+
const numericVmid = typeof targetVm === "number" ? targetVm : parseInt(String(targetVm), 10);
|
|
190
|
+
const hostId = (targetHost || "proxmox-lab");
|
|
191
|
+
const client = context.proxmoxManager.getClient(hostId);
|
|
192
|
+
// Guardrail validation
|
|
193
|
+
let fallbackVmTarget = { vmid: numericVmid, hostId };
|
|
194
|
+
let vmStatus;
|
|
195
|
+
try {
|
|
196
|
+
vmStatus = await client.getVmStatus(numericVmid);
|
|
197
|
+
fallbackVmTarget = {
|
|
198
|
+
vmid: numericVmid,
|
|
199
|
+
name: vmStatus.name,
|
|
200
|
+
template: vmStatus.template,
|
|
201
|
+
tags: vmStatus.tags,
|
|
202
|
+
hostId,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
// ignore get status failure
|
|
207
|
+
}
|
|
208
|
+
let taskResult;
|
|
209
|
+
let message;
|
|
210
|
+
switch (args.action) {
|
|
211
|
+
case "status":
|
|
212
|
+
if (!vmStatus) {
|
|
213
|
+
vmStatus = await client.getVmStatus(numericVmid);
|
|
214
|
+
}
|
|
215
|
+
message = `VM ${numericVmid} is currently ${vmStatus.status} (${vmStatus.name}).`;
|
|
216
|
+
break;
|
|
217
|
+
case "start":
|
|
218
|
+
taskResult = await client.startVm(numericVmid);
|
|
219
|
+
message = `Start command dispatched for VM ${numericVmid}.`;
|
|
220
|
+
break;
|
|
221
|
+
case "stop":
|
|
222
|
+
taskResult = await client.stopVm(numericVmid);
|
|
223
|
+
message = `Stop command dispatched for VM ${numericVmid}.`;
|
|
224
|
+
break;
|
|
225
|
+
case "shutdown":
|
|
226
|
+
taskResult = await client.shutdownVm(numericVmid);
|
|
227
|
+
message = `Graceful shutdown initiated for VM ${numericVmid}.`;
|
|
228
|
+
break;
|
|
229
|
+
case "reboot":
|
|
230
|
+
taskResult = await client.rebootVm(numericVmid);
|
|
231
|
+
message = `Reboot command initiated for VM ${numericVmid}.`;
|
|
232
|
+
break;
|
|
233
|
+
case "clone": {
|
|
234
|
+
const newid = args.cloneOptions?.newid || (numericVmid >= 9000 ? 500 : numericVmid + 100);
|
|
235
|
+
const name = args.cloneOptions?.name || `vm-${newid}-clone`;
|
|
236
|
+
const full = args.cloneOptions?.full ?? true;
|
|
237
|
+
taskResult = await client.cloneVm(numericVmid, newid, name, {
|
|
238
|
+
full,
|
|
239
|
+
target: args.cloneOptions?.targetHost,
|
|
240
|
+
});
|
|
241
|
+
message = `Successfully cloned VM ${numericVmid} to new VM ${newid} ('${name}').`;
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
case "destroy":
|
|
245
|
+
taskResult = await client.destroyVm(numericVmid, { purge: true });
|
|
246
|
+
message = `Successfully destroyed VM ${numericVmid}.`;
|
|
247
|
+
break;
|
|
248
|
+
default:
|
|
249
|
+
return createToolErrorResult(ProxmoxErrorCode.VALIDATION_ERROR, `Unsupported VM action: '${args.action}'.`);
|
|
250
|
+
}
|
|
251
|
+
if (args.action !== "destroy" && args.action !== "status") {
|
|
252
|
+
try {
|
|
253
|
+
vmStatus = await client.getVmStatus(numericVmid);
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
// Status may not be immediately updated
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
const formatted = formatVmActionResult({
|
|
260
|
+
host: hostId,
|
|
261
|
+
vmid: numericVmid,
|
|
262
|
+
action: args.action,
|
|
263
|
+
success: taskResult ? taskResult.success : true,
|
|
264
|
+
taskResult,
|
|
265
|
+
vmStatus,
|
|
266
|
+
message,
|
|
267
|
+
});
|
|
268
|
+
return {
|
|
269
|
+
content: [{ type: "text", text: formatted.markdown }],
|
|
270
|
+
structuredContent: formatted.structuredContent,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
if (error instanceof ProtectedVmViolationError) {
|
|
275
|
+
return createToolErrorResult(ProxmoxErrorCode.PROTECTED_VM_ACTION_DENIED, error.message, {
|
|
276
|
+
vmid: error.vmid,
|
|
277
|
+
vmName: error.vmName,
|
|
278
|
+
action: error.action,
|
|
279
|
+
reason: error.reason,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
if (error instanceof z.ZodError) {
|
|
283
|
+
return createToolErrorResult(ProxmoxErrorCode.VALIDATION_ERROR, `Validation error: ${error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ")}`);
|
|
284
|
+
}
|
|
285
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
286
|
+
const msgLower = msg.toLowerCase();
|
|
287
|
+
let code = ProxmoxErrorCode.UPSTREAM_API_ERROR;
|
|
288
|
+
if (msgLower.includes("not found") || msgLower.includes("404") || msgLower.includes("does not exist")) {
|
|
289
|
+
code = ProxmoxErrorCode.VM_NOT_FOUND;
|
|
290
|
+
}
|
|
291
|
+
else if (msgLower.includes("invalid state") || msgLower.includes("already running") || msgLower.includes("not running")) {
|
|
292
|
+
code = ProxmoxErrorCode.INVALID_VM_STATE;
|
|
293
|
+
}
|
|
294
|
+
else if (msgLower.includes("401") || msgLower.includes("unauthorized") || msgLower.includes("auth")) {
|
|
295
|
+
code = ProxmoxErrorCode.AUTHENTICATION_ERROR;
|
|
296
|
+
}
|
|
297
|
+
return createToolErrorResult(code, msg);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=vm-action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vm-action.js","sourceRoot":"","sources":["../../../src/tools/vm-action.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transports/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/transports/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP with Server-Sent Events (SSE) Transport for Call Telemetry Lab MCP Server
|
|
3
|
+
* Provides multi-client networked HTTP communication over SSE with session routing,
|
|
4
|
+
* health status monitoring, and DNS rebinding protection.
|
|
5
|
+
*/
|
|
6
|
+
import { Express } from "express";
|
|
7
|
+
import { Server as HttpServer } from "node:http";
|
|
8
|
+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
9
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
10
|
+
import { SlotManager } from "../slot/manager.js";
|
|
11
|
+
import { MultiHypervisorManager } from "../hypervisors/manager.js";
|
|
12
|
+
export interface ActiveSession {
|
|
13
|
+
sessionId: string;
|
|
14
|
+
transport: SSEServerTransport;
|
|
15
|
+
server: McpServer;
|
|
16
|
+
createdAt: number;
|
|
17
|
+
lastActiveAt: number;
|
|
18
|
+
}
|
|
19
|
+
export interface SseServerOptions {
|
|
20
|
+
port?: number;
|
|
21
|
+
host?: string;
|
|
22
|
+
allowedHosts?: string[];
|
|
23
|
+
slotManager?: SlotManager;
|
|
24
|
+
hypervisorManager?: MultiHypervisorManager;
|
|
25
|
+
sessionTimeoutMs?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface SseServerInstance {
|
|
28
|
+
app: Express;
|
|
29
|
+
httpServer?: HttpServer;
|
|
30
|
+
sessions: Map<string, ActiveSession>;
|
|
31
|
+
listen(port?: number, host?: string): Promise<HttpServer>;
|
|
32
|
+
close(): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Creates an Express application and SSE server instance configured for Call Telemetry Lab MCP.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createSseServer(serverFactoryOrInstance: McpServer | (() => McpServer), options?: SseServerOptions): SseServerInstance;
|
|
38
|
+
//# sourceMappingURL=sse.d.ts.map
|
|
@@ -0,0 +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;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGnE,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,CA4KnB"}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP with Server-Sent Events (SSE) Transport for Call Telemetry Lab MCP Server
|
|
3
|
+
* Provides multi-client networked HTTP communication over SSE with session routing,
|
|
4
|
+
* health status monitoring, and DNS rebinding protection.
|
|
5
|
+
*/
|
|
6
|
+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
7
|
+
import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
|
|
8
|
+
import { logger } from "../utils/logger.js";
|
|
9
|
+
/**
|
|
10
|
+
* Creates an Express application and SSE server instance configured for Call Telemetry Lab MCP.
|
|
11
|
+
*/
|
|
12
|
+
export function createSseServer(serverFactoryOrInstance, options = {}) {
|
|
13
|
+
const host = options.host || "127.0.0.1";
|
|
14
|
+
const port = options.port || 3000;
|
|
15
|
+
const sessionTimeoutMs = options.sessionTimeoutMs || 30 * 60 * 1000; // 30 minutes
|
|
16
|
+
// createMcpExpressApp includes express.json() and DNS rebinding validation
|
|
17
|
+
const app = createMcpExpressApp(options.allowedHosts
|
|
18
|
+
? { host, allowedHosts: options.allowedHosts }
|
|
19
|
+
: { host });
|
|
20
|
+
const sessions = new Map();
|
|
21
|
+
let activeHttpServer;
|
|
22
|
+
// Background session cleanup timer
|
|
23
|
+
const cleanupInterval = setInterval(() => {
|
|
24
|
+
const now = Date.now();
|
|
25
|
+
for (const [id, session] of sessions.entries()) {
|
|
26
|
+
if (now - session.lastActiveAt > sessionTimeoutMs) {
|
|
27
|
+
logger.warn(`Pruning timed out SSE session: ${id}`);
|
|
28
|
+
sessions.delete(id);
|
|
29
|
+
session.transport.close().catch(() => { });
|
|
30
|
+
session.server.close().catch(() => { });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}, 60000);
|
|
34
|
+
if (cleanupInterval.unref) {
|
|
35
|
+
cleanupInterval.unref();
|
|
36
|
+
}
|
|
37
|
+
// 1. Health Status Endpoint (GET /health)
|
|
38
|
+
app.get("/health", async (_req, res) => {
|
|
39
|
+
let capacity;
|
|
40
|
+
if (options.slotManager) {
|
|
41
|
+
try {
|
|
42
|
+
capacity = await options.slotManager.listHosts();
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
logger.error("Failed to query capacity for /health:", err);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
let hostCapacities;
|
|
49
|
+
if (options.hypervisorManager) {
|
|
50
|
+
try {
|
|
51
|
+
hostCapacities = await options.hypervisorManager.listAllHostsCapacity();
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
logger.error("Failed to query hypervisor capacities for /health:", err);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
res.status(200).json({
|
|
58
|
+
status: "healthy",
|
|
59
|
+
timestamp: new Date().toISOString(),
|
|
60
|
+
version: "0.1.0",
|
|
61
|
+
activeSessions: sessions.size,
|
|
62
|
+
capacity,
|
|
63
|
+
hostCapacities,
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
// 2. SSE Connection Endpoint (GET /sse)
|
|
67
|
+
app.get("/sse", async (_req, res) => {
|
|
68
|
+
try {
|
|
69
|
+
const serverInstance = typeof serverFactoryOrInstance === "function"
|
|
70
|
+
? serverFactoryOrInstance()
|
|
71
|
+
: serverFactoryOrInstance;
|
|
72
|
+
const transport = new SSEServerTransport("/messages", res);
|
|
73
|
+
const sessionId = transport.sessionId;
|
|
74
|
+
logger.info(`Established SSE connection: ${sessionId}`);
|
|
75
|
+
const session = {
|
|
76
|
+
sessionId,
|
|
77
|
+
transport,
|
|
78
|
+
server: serverInstance,
|
|
79
|
+
createdAt: Date.now(),
|
|
80
|
+
lastActiveAt: Date.now(),
|
|
81
|
+
};
|
|
82
|
+
sessions.set(sessionId, session);
|
|
83
|
+
res.on("close", async () => {
|
|
84
|
+
logger.info(`SSE connection closed for session: ${sessionId}`);
|
|
85
|
+
sessions.delete(sessionId);
|
|
86
|
+
try {
|
|
87
|
+
await transport.close();
|
|
88
|
+
}
|
|
89
|
+
catch { }
|
|
90
|
+
try {
|
|
91
|
+
await serverInstance.close();
|
|
92
|
+
}
|
|
93
|
+
catch { }
|
|
94
|
+
});
|
|
95
|
+
// server.connect() starts the transport automatically
|
|
96
|
+
await serverInstance.connect(transport);
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
logger.error("Error establishing SSE session:", err);
|
|
100
|
+
if (!res.headersSent) {
|
|
101
|
+
res.status(500).json({ error: "Failed to establish SSE session" });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
// 3. Message Ingestion Endpoint (POST /messages)
|
|
106
|
+
app.post("/messages", async (req, res) => {
|
|
107
|
+
const sessionId = req.query.sessionId || req.headers["x-session-id"];
|
|
108
|
+
if (!sessionId || !sessions.has(sessionId)) {
|
|
109
|
+
res.status(404).json({ error: `Session not found: ${sessionId || "none"}` });
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const session = sessions.get(sessionId);
|
|
113
|
+
session.lastActiveAt = Date.now();
|
|
114
|
+
try {
|
|
115
|
+
await session.transport.handlePostMessage(req, res, req.body);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
logger.error(`Error handling POST message for session ${sessionId}:`, err);
|
|
119
|
+
if (!res.headersSent) {
|
|
120
|
+
res.status(500).json({ error: "Failed to handle message" });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
const instance = {
|
|
125
|
+
app,
|
|
126
|
+
sessions,
|
|
127
|
+
async listen(customPort, customHost) {
|
|
128
|
+
const targetPort = customPort !== undefined ? customPort : port;
|
|
129
|
+
const targetHost = customHost || host;
|
|
130
|
+
return new Promise((resolve) => {
|
|
131
|
+
activeHttpServer = app.listen(targetPort, targetHost, () => {
|
|
132
|
+
console.error(`[ct-lab-mcp-sse] Call Telemetry Lab MCP SSE server listening at http://${targetHost}:${targetPort}`);
|
|
133
|
+
resolve(activeHttpServer);
|
|
134
|
+
});
|
|
135
|
+
instance.httpServer = activeHttpServer;
|
|
136
|
+
});
|
|
137
|
+
},
|
|
138
|
+
async close() {
|
|
139
|
+
clearInterval(cleanupInterval);
|
|
140
|
+
for (const [id, session] of sessions.entries()) {
|
|
141
|
+
try {
|
|
142
|
+
await session.transport.close();
|
|
143
|
+
}
|
|
144
|
+
catch { }
|
|
145
|
+
try {
|
|
146
|
+
await session.server.close();
|
|
147
|
+
}
|
|
148
|
+
catch { }
|
|
149
|
+
sessions.delete(id);
|
|
150
|
+
}
|
|
151
|
+
if (activeHttpServer) {
|
|
152
|
+
await new Promise((resolve, reject) => {
|
|
153
|
+
activeHttpServer.close((err) => {
|
|
154
|
+
if (err)
|
|
155
|
+
reject(err);
|
|
156
|
+
else
|
|
157
|
+
resolve();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
activeHttpServer = undefined;
|
|
161
|
+
instance.httpServer = undefined;
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
return instance;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=sse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../../src/transports/sse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdio Server Transport for Call Telemetry Lab MCP Server
|
|
3
|
+
* Operates over standard input and standard output for local MCP clients (Claude Desktop, Cursor).
|
|
4
|
+
* Stderr is strictly used for logging to prevent corrupting JSON-RPC stdout stream.
|
|
5
|
+
*/
|
|
6
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
8
|
+
export interface StdioServerOptions {
|
|
9
|
+
installSignalHandlers?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Connects an McpServer instance to the StdioServerTransport.
|
|
13
|
+
*/
|
|
14
|
+
export declare function startStdioServer(server: McpServer, options?: StdioServerOptions): Promise<StdioServerTransport>;
|
|
15
|
+
//# sourceMappingURL=stdio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../../src/transports/stdio.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAGjF,MAAM,WAAW,kBAAkB;IACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,oBAAoB,CAAC,CAwB/B"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stdio Server Transport for Call Telemetry Lab MCP Server
|
|
3
|
+
* Operates over standard input and standard output for local MCP clients (Claude Desktop, Cursor).
|
|
4
|
+
* Stderr is strictly used for logging to prevent corrupting JSON-RPC stdout stream.
|
|
5
|
+
*/
|
|
6
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
|
+
import { logger } from "../utils/logger.js";
|
|
8
|
+
/**
|
|
9
|
+
* Connects an McpServer instance to the StdioServerTransport.
|
|
10
|
+
*/
|
|
11
|
+
export async function startStdioServer(server, options = {}) {
|
|
12
|
+
const transport = new StdioServerTransport();
|
|
13
|
+
if (options.installSignalHandlers !== false) {
|
|
14
|
+
const handleSignal = async (signal) => {
|
|
15
|
+
logger.info(`Received ${signal}, shutting down...`);
|
|
16
|
+
try {
|
|
17
|
+
await server.close();
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
logger.error("Error closing server during signal handling:", err);
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
process.once("SIGINT", () => handleSignal("SIGINT"));
|
|
27
|
+
process.once("SIGTERM", () => handleSignal("SIGTERM"));
|
|
28
|
+
}
|
|
29
|
+
await server.connect(transport);
|
|
30
|
+
console.error("[proxmox-mcp] Proxmox MCP Server connected via stdio transport.");
|
|
31
|
+
console.error("[ct-lab-mcp] Call Telemetry Lab MCP Server connected via stdio transport.");
|
|
32
|
+
return transport;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=stdio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../../src/transports/stdio.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAM5C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,MAAiB,EACjB,UAA8B,EAAE;IAEhC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAE7C,IAAI,OAAO,CAAC,qBAAqB,KAAK,KAAK,EAAE,CAAC;QAC5C,MAAM,YAAY,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;YAC5C,MAAM,CAAC,IAAI,CAAC,YAAY,MAAM,oBAAoB,CAAC,CAAC;YACpD,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACvB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,8CAA8C,EAAE,GAAG,CAAC,CAAC;YACpE,CAAC;oBAAS,CAAC;gBACT,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACjF,OAAO,CAAC,KAAK,CAAC,2EAA2E,CAAC,CAAC;IAE3F,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host and credential configuration types for Proxmox and ESXi Lab MCP Server.
|
|
3
|
+
*/
|
|
4
|
+
export * from "../credentials/types.js";
|
|
5
|
+
import { ProxmoxHostConfig, EsxiHostConfig, VmCredentialConfig, DopplerConfig } from "../credentials/types.js";
|
|
6
|
+
export interface ServerConfig {
|
|
7
|
+
hosts?: ProxmoxHostConfig[];
|
|
8
|
+
proxmoxHosts?: ProxmoxHostConfig[];
|
|
9
|
+
esxiHosts?: EsxiHostConfig[];
|
|
10
|
+
vmCredentials?: VmCredentialConfig;
|
|
11
|
+
doppler?: DopplerConfig;
|
|
12
|
+
mockMode?: boolean;
|
|
13
|
+
transport?: "stdio" | "sse";
|
|
14
|
+
port?: number;
|
|
15
|
+
host?: string;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/types/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,yBAAyB,CAAC;AAExC,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE/G,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC5B,YAAY,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACnC,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|