@bldg-7/proxmox-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.
Files changed (139) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1033 -0
  3. package/dist/client/proxmox.d.ts +14 -0
  4. package/dist/client/proxmox.d.ts.map +1 -0
  5. package/dist/client/proxmox.js +82 -0
  6. package/dist/client/proxmox.js.map +1 -0
  7. package/dist/config/index.d.ts +4 -0
  8. package/dist/config/index.d.ts.map +1 -0
  9. package/dist/config/index.js +24 -0
  10. package/dist/config/index.js.map +1 -0
  11. package/dist/config/schema.d.ts +31 -0
  12. package/dist/config/schema.d.ts.map +1 -0
  13. package/dist/config/schema.js +32 -0
  14. package/dist/config/schema.js.map +1 -0
  15. package/dist/formatters/index.d.ts +42 -0
  16. package/dist/formatters/index.d.ts.map +1 -0
  17. package/dist/formatters/index.js +85 -0
  18. package/dist/formatters/index.js.map +1 -0
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +40 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/middleware/index.d.ts +41 -0
  24. package/dist/middleware/index.d.ts.map +1 -0
  25. package/dist/middleware/index.js +69 -0
  26. package/dist/middleware/index.js.map +1 -0
  27. package/dist/prompts/index.d.ts +2 -0
  28. package/dist/prompts/index.d.ts.map +1 -0
  29. package/dist/prompts/index.js +2 -0
  30. package/dist/prompts/index.js.map +1 -0
  31. package/dist/resources/index.d.ts +2 -0
  32. package/dist/resources/index.d.ts.map +1 -0
  33. package/dist/resources/index.js +2 -0
  34. package/dist/resources/index.js.map +1 -0
  35. package/dist/schemas/backup.d.ts +101 -0
  36. package/dist/schemas/backup.d.ts.map +1 -0
  37. package/dist/schemas/backup.js +43 -0
  38. package/dist/schemas/backup.js.map +1 -0
  39. package/dist/schemas/disk.d.ts +144 -0
  40. package/dist/schemas/disk.d.ts.map +1 -0
  41. package/dist/schemas/disk.js +60 -0
  42. package/dist/schemas/disk.js.map +1 -0
  43. package/dist/schemas/index.d.ts +7 -0
  44. package/dist/schemas/index.d.ts.map +1 -0
  45. package/dist/schemas/index.js +7 -0
  46. package/dist/schemas/index.js.map +1 -0
  47. package/dist/schemas/network.d.ts +140 -0
  48. package/dist/schemas/network.d.ts.map +1 -0
  49. package/dist/schemas/network.js +56 -0
  50. package/dist/schemas/network.js.map +1 -0
  51. package/dist/schemas/node.d.ts +16 -0
  52. package/dist/schemas/node.d.ts.map +1 -0
  53. package/dist/schemas/node.js +12 -0
  54. package/dist/schemas/node.js.map +1 -0
  55. package/dist/schemas/snapshot.d.ts +116 -0
  56. package/dist/schemas/snapshot.d.ts.map +1 -0
  57. package/dist/schemas/snapshot.js +34 -0
  58. package/dist/schemas/snapshot.js.map +1 -0
  59. package/dist/schemas/vm.d.ts +330 -0
  60. package/dist/schemas/vm.d.ts.map +1 -0
  61. package/dist/schemas/vm.js +111 -0
  62. package/dist/schemas/vm.js.map +1 -0
  63. package/dist/server.d.ts +5 -0
  64. package/dist/server.d.ts.map +1 -0
  65. package/dist/server.js +142 -0
  66. package/dist/server.js.map +1 -0
  67. package/dist/tools/backup.d.ts +35 -0
  68. package/dist/tools/backup.d.ts.map +1 -0
  69. package/dist/tools/backup.js +210 -0
  70. package/dist/tools/backup.js.map +1 -0
  71. package/dist/tools/cluster.d.ts +15 -0
  72. package/dist/tools/cluster.d.ts.map +1 -0
  73. package/dist/tools/cluster.js +82 -0
  74. package/dist/tools/cluster.js.map +1 -0
  75. package/dist/tools/command.d.ts +6 -0
  76. package/dist/tools/command.d.ts.map +1 -0
  77. package/dist/tools/command.js +26 -0
  78. package/dist/tools/command.js.map +1 -0
  79. package/dist/tools/disk.d.ts +45 -0
  80. package/dist/tools/disk.d.ts.map +1 -0
  81. package/dist/tools/disk.js +243 -0
  82. package/dist/tools/disk.js.map +1 -0
  83. package/dist/tools/index.d.ts +12 -0
  84. package/dist/tools/index.d.ts.map +1 -0
  85. package/dist/tools/index.js +20 -0
  86. package/dist/tools/index.js.map +1 -0
  87. package/dist/tools/network.d.ts +35 -0
  88. package/dist/tools/network.d.ts.map +1 -0
  89. package/dist/tools/network.js +270 -0
  90. package/dist/tools/network.js.map +1 -0
  91. package/dist/tools/node.d.ts +15 -0
  92. package/dist/tools/node.d.ts.map +1 -0
  93. package/dist/tools/node.js +73 -0
  94. package/dist/tools/node.js.map +1 -0
  95. package/dist/tools/registry.d.ts +12 -0
  96. package/dist/tools/registry.d.ts.map +1 -0
  97. package/dist/tools/registry.js +87 -0
  98. package/dist/tools/registry.js.map +1 -0
  99. package/dist/tools/snapshot.d.ts +45 -0
  100. package/dist/tools/snapshot.d.ts.map +1 -0
  101. package/dist/tools/snapshot.js +249 -0
  102. package/dist/tools/snapshot.js.map +1 -0
  103. package/dist/tools/vm-create.d.ts +8 -0
  104. package/dist/tools/vm-create.d.ts.map +1 -0
  105. package/dist/tools/vm-create.js +129 -0
  106. package/dist/tools/vm-create.js.map +1 -0
  107. package/dist/tools/vm-lifecycle.d.ts +67 -0
  108. package/dist/tools/vm-lifecycle.d.ts.map +1 -0
  109. package/dist/tools/vm-lifecycle.js +319 -0
  110. package/dist/tools/vm-lifecycle.js.map +1 -0
  111. package/dist/tools/vm-modify.d.ts +25 -0
  112. package/dist/tools/vm-modify.d.ts.map +1 -0
  113. package/dist/tools/vm-modify.js +155 -0
  114. package/dist/tools/vm-modify.js.map +1 -0
  115. package/dist/tools/vm-query.d.ts +20 -0
  116. package/dist/tools/vm-query.d.ts.map +1 -0
  117. package/dist/tools/vm-query.js +166 -0
  118. package/dist/tools/vm-query.js.map +1 -0
  119. package/dist/types/index.d.ts +5 -0
  120. package/dist/types/index.d.ts.map +1 -0
  121. package/dist/types/index.js +2 -0
  122. package/dist/types/index.js.map +1 -0
  123. package/dist/types/proxmox.d.ts +166 -0
  124. package/dist/types/proxmox.d.ts.map +1 -0
  125. package/dist/types/proxmox.js +2 -0
  126. package/dist/types/proxmox.js.map +1 -0
  127. package/dist/types/tools.d.ts +12 -0
  128. package/dist/types/tools.d.ts.map +1 -0
  129. package/dist/types/tools.js +64 -0
  130. package/dist/types/tools.js.map +1 -0
  131. package/dist/utils/index.d.ts +3 -0
  132. package/dist/utils/index.d.ts.map +1 -0
  133. package/dist/utils/index.js +8 -0
  134. package/dist/utils/index.js.map +1 -0
  135. package/dist/validators/index.d.ts +75 -0
  136. package/dist/validators/index.d.ts.map +1 -0
  137. package/dist/validators/index.js +185 -0
  138. package/dist/validators/index.js.map +1 -0
  139. package/package.json +51 -0
@@ -0,0 +1,14 @@
1
+ import type { Config } from '../config/schema.js';
2
+ export declare class ProxmoxApiError extends Error {
3
+ readonly statusCode: number;
4
+ readonly endpoint: string;
5
+ constructor(message: string, statusCode: number, endpoint: string);
6
+ }
7
+ export declare class ProxmoxApiClient {
8
+ private readonly baseUrl;
9
+ private readonly authHeader;
10
+ private readonly agent;
11
+ constructor(config: Config);
12
+ request<T>(endpoint: string, method?: string, body?: unknown): Promise<T>;
13
+ }
14
+ //# sourceMappingURL=proxmox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxmox.d.ts","sourceRoot":"","sources":["../../src/client/proxmox.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAKlD,qBAAa,eAAgB,SAAQ,KAAK;aAGtB,UAAU,EAAE,MAAM;aAClB,QAAQ,EAAE,MAAM;gBAFhC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM;CAKnC;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;gBAExB,MAAM,EAAE,MAAM;IAmBpB,OAAO,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAQ,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;CAiE/E"}
@@ -0,0 +1,82 @@
1
+ import https from 'node:https';
2
+ import fs from 'node:fs';
3
+ import { logger } from '../utils/index.js';
4
+ const DEFAULT_TIMEOUT_MS = 30_000;
5
+ export class ProxmoxApiError extends Error {
6
+ statusCode;
7
+ endpoint;
8
+ constructor(message, statusCode, endpoint) {
9
+ super(message);
10
+ this.statusCode = statusCode;
11
+ this.endpoint = endpoint;
12
+ this.name = 'ProxmoxApiError';
13
+ }
14
+ }
15
+ export class ProxmoxApiClient {
16
+ baseUrl;
17
+ authHeader;
18
+ agent;
19
+ constructor(config) {
20
+ this.baseUrl = `https://${config.host}:${config.port}/api2/json`;
21
+ this.authHeader = `PVEAPIToken=${config.user}!${config.tokenName}=${config.tokenValue}`;
22
+ if (config.sslVerify && config.sslCaCert) {
23
+ this.agent = new https.Agent({
24
+ ca: fs.readFileSync(config.sslCaCert),
25
+ });
26
+ }
27
+ else if (config.sslVerify) {
28
+ this.agent = new https.Agent({
29
+ rejectUnauthorized: true,
30
+ });
31
+ }
32
+ else {
33
+ this.agent = new https.Agent({
34
+ rejectUnauthorized: false,
35
+ });
36
+ }
37
+ }
38
+ async request(endpoint, method = 'GET', body) {
39
+ const url = `${this.baseUrl}${endpoint}`;
40
+ const headers = {
41
+ 'Authorization': this.authHeader,
42
+ 'Content-Type': 'application/json',
43
+ };
44
+ const options = {
45
+ method,
46
+ headers,
47
+ signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),
48
+ };
49
+ // Pass the HTTPS agent via the Node.js-specific dispatcher
50
+ // Node's native fetch accepts an agent-like option
51
+ options['agent'] = this.agent;
52
+ if (body !== undefined) {
53
+ options.body = JSON.stringify(body);
54
+ }
55
+ logger.debug({ method, endpoint }, 'Proxmox API request');
56
+ try {
57
+ const response = await fetch(url, options);
58
+ if (!response.ok) {
59
+ const errorText = await response.text();
60
+ logger.error({ statusCode: response.status, endpoint, error: errorText }, 'Proxmox API error');
61
+ throw new ProxmoxApiError(`Proxmox API error: ${response.status} - ${errorText}`, response.status, endpoint);
62
+ }
63
+ const textResponse = await response.text();
64
+ if (!textResponse.trim()) {
65
+ throw new ProxmoxApiError('Empty response from Proxmox API', 0, endpoint);
66
+ }
67
+ const data = JSON.parse(textResponse);
68
+ return data.data;
69
+ }
70
+ catch (error) {
71
+ if (error instanceof ProxmoxApiError) {
72
+ throw error;
73
+ }
74
+ if (error instanceof SyntaxError) {
75
+ throw new ProxmoxApiError(`Failed to parse Proxmox API response: ${error.message}`, 0, endpoint);
76
+ }
77
+ const message = error instanceof Error ? error.message : String(error);
78
+ throw new ProxmoxApiError(`Failed to connect to Proxmox: ${message}`, 0, endpoint);
79
+ }
80
+ }
81
+ }
82
+ //# sourceMappingURL=proxmox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxmox.js","sourceRoot":"","sources":["../../src/client/proxmox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type Config } from './schema.js';
2
+ export { type Config } from './schema.js';
3
+ export declare function loadConfig(): Config;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,wBAAgB,UAAU,IAAI,MAAM,CAwBnC"}
@@ -0,0 +1,24 @@
1
+ import dotenv from 'dotenv';
2
+ import { configSchema } from './schema.js';
3
+ export function loadConfig() {
4
+ dotenv.config();
5
+ const rawConfig = {
6
+ host: process.env.PROXMOX_HOST,
7
+ port: process.env.PROXMOX_PORT ? parseInt(process.env.PROXMOX_PORT, 10) : undefined,
8
+ user: process.env.PROXMOX_USER || undefined,
9
+ tokenName: process.env.PROXMOX_TOKEN_NAME,
10
+ tokenValue: process.env.PROXMOX_TOKEN_VALUE,
11
+ allowElevated: process.env.PROXMOX_ALLOW_ELEVATED === 'true',
12
+ sslVerify: process.env.PROXMOX_SSL_VERIFY === 'true',
13
+ sslCaCert: process.env.PROXMOX_SSL_CA_CERT || undefined,
14
+ };
15
+ const result = configSchema.safeParse(rawConfig);
16
+ if (!result.success) {
17
+ const errors = result.error.issues
18
+ .map((issue) => ` ${issue.path.join('.')}: ${issue.message}`)
19
+ .join('\n');
20
+ throw new Error(`Invalid configuration:\n${errors}`);
21
+ }
22
+ return result.data;
23
+ }
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAe,MAAM,aAAa,CAAC;AAIxD,MAAM,UAAU,UAAU;IACxB,MAAM,CAAC,MAAM,EAAE,CAAC;IAEhB,MAAM,SAAS,GAAG;QAChB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QAC9B,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;QACnF,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,SAAS;QAC3C,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;QACzC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;QAC3C,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,MAAM;QAC5D,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM;QACpD,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,SAAS;KACxD,CAAC;IAEF,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAEjD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM;aAC/B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;aAC7D,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { z } from 'zod';
2
+ export declare const configSchema: z.ZodObject<{
3
+ host: z.ZodString;
4
+ port: z.ZodDefault<z.ZodNumber>;
5
+ user: z.ZodDefault<z.ZodString>;
6
+ tokenName: z.ZodString;
7
+ tokenValue: z.ZodString;
8
+ allowElevated: z.ZodDefault<z.ZodBoolean>;
9
+ sslVerify: z.ZodDefault<z.ZodBoolean>;
10
+ sslCaCert: z.ZodOptional<z.ZodString>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ host: string;
13
+ port: number;
14
+ user: string;
15
+ tokenName: string;
16
+ tokenValue: string;
17
+ allowElevated: boolean;
18
+ sslVerify: boolean;
19
+ sslCaCert?: string | undefined;
20
+ }, {
21
+ host: string;
22
+ tokenName: string;
23
+ tokenValue: string;
24
+ port?: number | undefined;
25
+ user?: string | undefined;
26
+ allowElevated?: boolean | undefined;
27
+ sslVerify?: boolean | undefined;
28
+ sslCaCert?: string | undefined;
29
+ }>;
30
+ export type Config = z.infer<typeof configSchema>;
31
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BvB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { z } from 'zod';
2
+ export const configSchema = z.object({
3
+ host: z
4
+ .string({ required_error: 'PROXMOX_HOST is required' })
5
+ .min(1, 'PROXMOX_HOST cannot be empty'),
6
+ port: z
7
+ .number()
8
+ .int()
9
+ .min(1)
10
+ .max(65535)
11
+ .default(8006),
12
+ user: z
13
+ .string()
14
+ .min(1)
15
+ .default('root@pam'),
16
+ tokenName: z
17
+ .string({ required_error: 'PROXMOX_TOKEN_NAME is required' })
18
+ .min(1, 'PROXMOX_TOKEN_NAME cannot be empty'),
19
+ tokenValue: z
20
+ .string({ required_error: 'PROXMOX_TOKEN_VALUE is required' })
21
+ .min(1, 'PROXMOX_TOKEN_VALUE cannot be empty'),
22
+ allowElevated: z
23
+ .boolean()
24
+ .default(false),
25
+ sslVerify: z
26
+ .boolean()
27
+ .default(false),
28
+ sslCaCert: z
29
+ .string()
30
+ .optional(),
31
+ });
32
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC;SACJ,MAAM,CAAC,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC;SACtD,GAAG,CAAC,CAAC,EAAE,8BAA8B,CAAC;IACzC,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,KAAK,CAAC;SACV,OAAO,CAAC,IAAI,CAAC;IAChB,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,OAAO,CAAC,UAAU,CAAC;IACtB,SAAS,EAAE,CAAC;SACT,MAAM,CAAC,EAAE,cAAc,EAAE,gCAAgC,EAAE,CAAC;SAC5D,GAAG,CAAC,CAAC,EAAE,oCAAoC,CAAC;IAC/C,UAAU,EAAE,CAAC;SACV,MAAM,CAAC,EAAE,cAAc,EAAE,iCAAiC,EAAE,CAAC;SAC7D,GAAG,CAAC,CAAC,EAAE,qCAAqC,CAAC;IAChD,aAAa,EAAE,CAAC;SACb,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;IACjB,SAAS,EAAE,CAAC;SACT,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;IACjB,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,QAAQ,EAAE;CACd,CAAC,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Format a byte count into a human-readable string.
3
+ *
4
+ * @example formatBytes(0) // '0 B'
5
+ * @example formatBytes(1024) // '1 KB'
6
+ * @example formatBytes(1073741824) // '1 GB'
7
+ */
8
+ export declare function formatBytes(bytes: number): string;
9
+ /**
10
+ * Format an uptime value (in seconds) into a human-readable string.
11
+ *
12
+ * @example formatUptime(60) // '1 minute'
13
+ * @example formatUptime(3600) // '1 hour'
14
+ * @example formatUptime(86400) // '1 day'
15
+ */
16
+ export declare function formatUptime(seconds: number): string;
17
+ /**
18
+ * Format a CPU usage fraction as a percentage string.
19
+ *
20
+ * @example formatCpuPercent(0.5123) // '51.23%'
21
+ */
22
+ export declare function formatCpuPercent(fraction: number): string;
23
+ import type { ToolResponse } from '../types/tools.js';
24
+ /**
25
+ * Format a successful tool response.
26
+ *
27
+ * @example formatToolResponse('VM started successfully')
28
+ */
29
+ export declare function formatToolResponse(text: string): ToolResponse;
30
+ /**
31
+ * Format an error response with context.
32
+ *
33
+ * @example formatErrorResponse(new Error('Connection failed'), 'Get VM Status')
34
+ */
35
+ export declare function formatErrorResponse(error: Error, context: string): ToolResponse;
36
+ /**
37
+ * Format a permission denied response.
38
+ *
39
+ * @example formatPermissionDenied('delete_vm')
40
+ */
41
+ export declare function formatPermissionDenied(action: string): ToolResponse;
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/formatters/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASjD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAepD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAK7D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAM/E;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CASnE"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Format a byte count into a human-readable string.
3
+ *
4
+ * @example formatBytes(0) // '0 B'
5
+ * @example formatBytes(1024) // '1 KB'
6
+ * @example formatBytes(1073741824) // '1 GB'
7
+ */
8
+ export function formatBytes(bytes) {
9
+ if (bytes === 0)
10
+ return '0 B';
11
+ const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
12
+ const k = 1024;
13
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
14
+ const value = bytes / Math.pow(k, i);
15
+ return `${parseFloat(value.toFixed(2))} ${units[i]}`;
16
+ }
17
+ /**
18
+ * Format an uptime value (in seconds) into a human-readable string.
19
+ *
20
+ * @example formatUptime(60) // '1 minute'
21
+ * @example formatUptime(3600) // '1 hour'
22
+ * @example formatUptime(86400) // '1 day'
23
+ */
24
+ export function formatUptime(seconds) {
25
+ if (seconds < 60) {
26
+ return `${seconds} second${seconds !== 1 ? 's' : ''}`;
27
+ }
28
+ const days = Math.floor(seconds / 86400);
29
+ const hours = Math.floor((seconds % 86400) / 3600);
30
+ const minutes = Math.floor((seconds % 3600) / 60);
31
+ const parts = [];
32
+ if (days > 0)
33
+ parts.push(`${days} day${days !== 1 ? 's' : ''}`);
34
+ if (hours > 0)
35
+ parts.push(`${hours} hour${hours !== 1 ? 's' : ''}`);
36
+ if (minutes > 0 && days === 0)
37
+ parts.push(`${minutes} minute${minutes !== 1 ? 's' : ''}`);
38
+ return parts.join(', ');
39
+ }
40
+ /**
41
+ * Format a CPU usage fraction as a percentage string.
42
+ *
43
+ * @example formatCpuPercent(0.5123) // '51.23%'
44
+ */
45
+ export function formatCpuPercent(fraction) {
46
+ return `${(fraction * 100).toFixed(2)}%`;
47
+ }
48
+ /**
49
+ * Format a successful tool response.
50
+ *
51
+ * @example formatToolResponse('VM started successfully')
52
+ */
53
+ export function formatToolResponse(text) {
54
+ return {
55
+ content: [{ type: 'text', text }],
56
+ isError: false,
57
+ };
58
+ }
59
+ /**
60
+ * Format an error response with context.
61
+ *
62
+ * @example formatErrorResponse(new Error('Connection failed'), 'Get VM Status')
63
+ */
64
+ export function formatErrorResponse(error, context) {
65
+ const message = `❌ **Error in ${context}**\n\n${error.message}`;
66
+ return {
67
+ content: [{ type: 'text', text: message }],
68
+ isError: true,
69
+ };
70
+ }
71
+ /**
72
+ * Format a permission denied response.
73
+ *
74
+ * @example formatPermissionDenied('delete_vm')
75
+ */
76
+ export function formatPermissionDenied(action) {
77
+ const message = `🚫 **Permission Denied**\n\n` +
78
+ `The action "${action}" requires elevated permissions.\n` +
79
+ `Set PROXMOX_ALLOW_ELEVATED=true to enable.`;
80
+ return {
81
+ content: [{ type: 'text', text: message }],
82
+ isError: true,
83
+ };
84
+ }
85
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/formatters/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export declare function main(): Promise<void>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAQA,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAsB1C"}
package/dist/index.js ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { loadConfig } from './config/index.js';
4
+ import { ProxmoxApiClient } from './client/proxmox.js';
5
+ import { createServer } from './server.js';
6
+ import { logger } from './utils/index.js';
7
+ export async function main() {
8
+ try {
9
+ // Load configuration from environment variables
10
+ const config = loadConfig();
11
+ logger.info('Configuration loaded successfully');
12
+ // Create Proxmox API client
13
+ const client = new ProxmoxApiClient(config);
14
+ logger.info('Proxmox API client initialized');
15
+ // Create MCP server with all tools registered
16
+ const server = createServer(client, config);
17
+ logger.info('MCP server created with 55 tools registered');
18
+ // Create stdio transport and connect server
19
+ const transport = new StdioServerTransport();
20
+ await server.connect(transport);
21
+ logger.info('MCP server started on stdio transport');
22
+ }
23
+ catch (error) {
24
+ logger.error({ error }, 'Fatal error during startup');
25
+ process.exit(1);
26
+ }
27
+ }
28
+ // Handle uncaught exceptions
29
+ process.on('uncaughtException', (error) => {
30
+ logger.error({ error }, 'Uncaught exception');
31
+ process.exit(1);
32
+ });
33
+ // Handle unhandled promise rejections
34
+ process.on('unhandledRejection', (reason) => {
35
+ logger.error({ reason }, 'Unhandled rejection');
36
+ process.exit(1);
37
+ });
38
+ // Start the server
39
+ main();
40
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,IAAI;IACxB,IAAI,CAAC;QACH,gDAAgD;QAChD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QAEjD,4BAA4B;QAC5B,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAE9C,8CAA8C;QAC9C,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAE3D,4CAA4C;QAC5C,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,4BAA4B,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,6BAA6B;AAC7B,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;IACxC,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,oBAAoB,CAAC,CAAC;IAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,sCAAsC;AACtC,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC1C,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,mBAAmB;AACnB,IAAI,EAAE,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { Config } from '../config/index.js';
2
+ /**
3
+ * Checks if elevated permissions are allowed and throws if not.
4
+ * Used to guard dangerous operations that require explicit opt-in.
5
+ *
6
+ * @throws {Error} If elevated permissions are not allowed
7
+ */
8
+ export declare function requireElevated(config: Config, action: string): void;
9
+ /**
10
+ * Simple in-memory rate limiter using a sliding window approach.
11
+ * Tracks requests per key and enforces a maximum request count within a time window.
12
+ */
13
+ export declare class RateLimiter {
14
+ private maxRequests;
15
+ private windowMs;
16
+ private requests;
17
+ /**
18
+ * @param maxRequests Maximum number of requests allowed in the window
19
+ * @param windowMs Time window in milliseconds
20
+ */
21
+ constructor(maxRequests: number, windowMs: number);
22
+ /**
23
+ * Check if a request is allowed for the given key.
24
+ * Returns true if allowed, false if rate limited.
25
+ *
26
+ * @param key Identifier for the rate limit bucket (e.g., user ID, IP address)
27
+ * @returns true if request is allowed, false if rate limited
28
+ */
29
+ check(key: string): boolean;
30
+ /**
31
+ * Reset the rate limiter (clear all tracked requests).
32
+ * Useful for testing or manual reset.
33
+ */
34
+ reset(): void;
35
+ /**
36
+ * Get the number of requests for a key within the current window.
37
+ * Useful for monitoring and testing.
38
+ */
39
+ getRequestCount(key: string): number;
40
+ }
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAIpE;AAED;;;GAGG;AACH,qBAAa,WAAW;IAQpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,QAAQ;IARlB,OAAO,CAAC,QAAQ,CAAoC;IAEpD;;;OAGG;gBAEO,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM;IAG1B;;;;;;OAMG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAsB3B;;;OAGG;IACH,KAAK,IAAI,IAAI;IAIb;;;OAGG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAMrC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Checks if elevated permissions are allowed and throws if not.
3
+ * Used to guard dangerous operations that require explicit opt-in.
4
+ *
5
+ * @throws {Error} If elevated permissions are not allowed
6
+ */
7
+ export function requireElevated(config, action) {
8
+ if (!config.allowElevated) {
9
+ throw new Error(`Permission denied: ${action} requires elevated permissions`);
10
+ }
11
+ }
12
+ /**
13
+ * Simple in-memory rate limiter using a sliding window approach.
14
+ * Tracks requests per key and enforces a maximum request count within a time window.
15
+ */
16
+ export class RateLimiter {
17
+ maxRequests;
18
+ windowMs;
19
+ requests = new Map();
20
+ /**
21
+ * @param maxRequests Maximum number of requests allowed in the window
22
+ * @param windowMs Time window in milliseconds
23
+ */
24
+ constructor(maxRequests, windowMs) {
25
+ this.maxRequests = maxRequests;
26
+ this.windowMs = windowMs;
27
+ }
28
+ /**
29
+ * Check if a request is allowed for the given key.
30
+ * Returns true if allowed, false if rate limited.
31
+ *
32
+ * @param key Identifier for the rate limit bucket (e.g., user ID, IP address)
33
+ * @returns true if request is allowed, false if rate limited
34
+ */
35
+ check(key) {
36
+ const now = Date.now();
37
+ const windowStart = now - this.windowMs;
38
+ // Get or initialize request timestamps for this key
39
+ let timestamps = this.requests.get(key) || [];
40
+ // Remove timestamps outside the window
41
+ timestamps = timestamps.filter((ts) => ts > windowStart);
42
+ // Check if we've exceeded the limit
43
+ if (timestamps.length >= this.maxRequests) {
44
+ return false;
45
+ }
46
+ // Add current request timestamp
47
+ timestamps.push(now);
48
+ this.requests.set(key, timestamps);
49
+ return true;
50
+ }
51
+ /**
52
+ * Reset the rate limiter (clear all tracked requests).
53
+ * Useful for testing or manual reset.
54
+ */
55
+ reset() {
56
+ this.requests.clear();
57
+ }
58
+ /**
59
+ * Get the number of requests for a key within the current window.
60
+ * Useful for monitoring and testing.
61
+ */
62
+ getRequestCount(key) {
63
+ const now = Date.now();
64
+ const windowStart = now - this.windowMs;
65
+ const timestamps = this.requests.get(key) || [];
66
+ return timestamps.filter((ts) => ts > windowStart).length;
67
+ }
68
+ }
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middleware/index.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,MAAc;IAC5D,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,gCAAgC,CAAC,CAAC;IAChF,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,WAAW;IAQZ;IACA;IARF,QAAQ,GAA0B,IAAI,GAAG,EAAE,CAAC;IAEpD;;;OAGG;IACH,YACU,WAAmB,EACnB,QAAgB;QADhB,gBAAW,GAAX,WAAW,CAAQ;QACnB,aAAQ,GAAR,QAAQ,CAAQ;IACvB,CAAC;IAEJ;;;;;;OAMG;IACH,KAAK,CAAC,GAAW;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QAExC,oDAAoD;QACpD,IAAI,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAE9C,uCAAuC;QACvC,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC;QAEzD,oCAAoC;QACpC,IAAI,UAAU,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,gCAAgC;QAChC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAEnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,GAAW;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QACxC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAChD,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC,MAAM,CAAC;IAC5D,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":""}