nandi-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.
- package/LICENSE +21 -0
- package/README.md +60 -0
- package/dist/src/cli/doctor.d.ts +2 -0
- package/dist/src/cli/doctor.d.ts.map +1 -0
- package/dist/src/cli/doctor.js +127 -0
- package/dist/src/cli/doctor.js.map +1 -0
- package/dist/src/cli/main.d.ts +3 -0
- package/dist/src/cli/main.d.ts.map +1 -0
- package/dist/src/cli/main.js +30 -0
- package/dist/src/cli/main.js.map +1 -0
- package/dist/src/cli/report.d.ts +7 -0
- package/dist/src/cli/report.d.ts.map +1 -0
- package/dist/src/cli/report.js +9 -0
- package/dist/src/cli/report.js.map +1 -0
- package/dist/src/cli/setup.d.ts +2 -0
- package/dist/src/cli/setup.d.ts.map +1 -0
- package/dist/src/cli/setup.js +150 -0
- package/dist/src/cli/setup.js.map +1 -0
- package/dist/src/config/env.d.ts +3 -0
- package/dist/src/config/env.d.ts.map +1 -0
- package/dist/src/config/env.js +19 -0
- package/dist/src/config/env.js.map +1 -0
- package/dist/src/config/fileConfig.d.ts +4 -0
- package/dist/src/config/fileConfig.d.ts.map +1 -0
- package/dist/src/config/fileConfig.js +13 -0
- package/dist/src/config/fileConfig.js.map +1 -0
- package/dist/src/config/installDescriptor.d.ts +36 -0
- package/dist/src/config/installDescriptor.d.ts.map +1 -0
- package/dist/src/config/installDescriptor.js +91 -0
- package/dist/src/config/installDescriptor.js.map +1 -0
- package/dist/src/config/templates.d.ts +15 -0
- package/dist/src/config/templates.d.ts.map +1 -0
- package/dist/src/config/templates.js +21 -0
- package/dist/src/config/templates.js.map +1 -0
- package/dist/src/config/validate.d.ts +40 -0
- package/dist/src/config/validate.d.ts.map +1 -0
- package/dist/src/config/validate.js +15 -0
- package/dist/src/config/validate.js.map +1 -0
- package/dist/src/guardian/errorMap.d.ts +3 -0
- package/dist/src/guardian/errorMap.d.ts.map +1 -0
- package/dist/src/guardian/errorMap.js +35 -0
- package/dist/src/guardian/errorMap.js.map +1 -0
- package/dist/src/guardian/guardian.d.ts +8 -0
- package/dist/src/guardian/guardian.d.ts.map +1 -0
- package/dist/src/guardian/guardian.js +38 -0
- package/dist/src/guardian/guardian.js.map +1 -0
- package/dist/src/guardian/result.d.ts +20 -0
- package/dist/src/guardian/result.d.ts.map +1 -0
- package/dist/src/guardian/result.js +17 -0
- package/dist/src/guardian/result.js.map +1 -0
- package/dist/src/guardian/retryPolicy.d.ts +9 -0
- package/dist/src/guardian/retryPolicy.d.ts.map +1 -0
- package/dist/src/guardian/retryPolicy.js +15 -0
- package/dist/src/guardian/retryPolicy.js.map +1 -0
- package/dist/src/guardian/timeout.d.ts +2 -0
- package/dist/src/guardian/timeout.d.ts.map +1 -0
- package/dist/src/guardian/timeout.js +10 -0
- package/dist/src/guardian/timeout.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +35 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/logging/logger.d.ts +6 -0
- package/dist/src/logging/logger.d.ts.map +1 -0
- package/dist/src/logging/logger.js +16 -0
- package/dist/src/logging/logger.js.map +1 -0
- package/dist/src/logging/redaction.d.ts +2 -0
- package/dist/src/logging/redaction.d.ts.map +1 -0
- package/dist/src/logging/redaction.js +13 -0
- package/dist/src/logging/redaction.js.map +1 -0
- package/dist/src/proxmox/auth.d.ts +3 -0
- package/dist/src/proxmox/auth.d.ts.map +1 -0
- package/dist/src/proxmox/auth.js +4 -0
- package/dist/src/proxmox/auth.js.map +1 -0
- package/dist/src/proxmox/client.d.ts +21 -0
- package/dist/src/proxmox/client.d.ts.map +1 -0
- package/dist/src/proxmox/client.js +70 -0
- package/dist/src/proxmox/client.js.map +1 -0
- package/dist/src/proxmox/endpoints.d.ts +13 -0
- package/dist/src/proxmox/endpoints.d.ts.map +1 -0
- package/dist/src/proxmox/endpoints.js +13 -0
- package/dist/src/proxmox/endpoints.js.map +1 -0
- package/dist/src/proxmox/errors.d.ts +10 -0
- package/dist/src/proxmox/errors.d.ts.map +1 -0
- package/dist/src/proxmox/errors.js +33 -0
- package/dist/src/proxmox/errors.js.map +1 -0
- package/dist/src/proxmox/types.d.ts +29 -0
- package/dist/src/proxmox/types.d.ts.map +1 -0
- package/dist/src/proxmox/types.js +2 -0
- package/dist/src/proxmox/types.js.map +1 -0
- package/dist/src/server/mcpServer.d.ts +10 -0
- package/dist/src/server/mcpServer.d.ts.map +1 -0
- package/dist/src/server/mcpServer.js +25 -0
- package/dist/src/server/mcpServer.js.map +1 -0
- package/dist/src/server/schemas.d.ts +103 -0
- package/dist/src/server/schemas.d.ts.map +1 -0
- package/dist/src/server/schemas.js +41 -0
- package/dist/src/server/schemas.js.map +1 -0
- package/dist/src/server/toolRegistry.d.ts +4 -0
- package/dist/src/server/toolRegistry.d.ts.map +1 -0
- package/dist/src/server/toolRegistry.js +47 -0
- package/dist/src/server/toolRegistry.js.map +1 -0
- package/dist/src/ssh/batchDiagnostics.d.ts +8 -0
- package/dist/src/ssh/batchDiagnostics.d.ts.map +1 -0
- package/dist/src/ssh/batchDiagnostics.js +36 -0
- package/dist/src/ssh/batchDiagnostics.js.map +1 -0
- package/dist/src/ssh/pctExec.d.ts +3 -0
- package/dist/src/ssh/pctExec.d.ts.map +1 -0
- package/dist/src/ssh/pctExec.js +13 -0
- package/dist/src/ssh/pctExec.js.map +1 -0
- package/dist/src/ssh/sshClient.d.ts +14 -0
- package/dist/src/ssh/sshClient.d.ts.map +1 -0
- package/dist/src/ssh/sshClient.js +22 -0
- package/dist/src/ssh/sshClient.js.map +1 -0
- package/dist/src/tools/control.d.ts +7 -0
- package/dist/src/tools/control.d.ts.map +1 -0
- package/dist/src/tools/control.js +14 -0
- package/dist/src/tools/control.js.map +1 -0
- package/dist/src/tools/diagnostics.d.ts +4 -0
- package/dist/src/tools/diagnostics.d.ts.map +1 -0
- package/dist/src/tools/diagnostics.js +6 -0
- package/dist/src/tools/diagnostics.js.map +1 -0
- package/dist/src/tools/inventory.d.ts +8 -0
- package/dist/src/tools/inventory.d.ts.map +1 -0
- package/dist/src/tools/inventory.js +21 -0
- package/dist/src/tools/inventory.js.map +1 -0
- package/dist/src/tools/operations.d.ts +7 -0
- package/dist/src/tools/operations.d.ts.map +1 -0
- package/dist/src/tools/operations.js +37 -0
- package/dist/src/tools/operations.js.map +1 -0
- package/dist/src/tools/status.d.ts +6 -0
- package/dist/src/tools/status.d.ts.map +1 -0
- package/dist/src/tools/status.js +11 -0
- package/dist/src/tools/status.js.map +1 -0
- package/dist/src/utils/parsing.d.ts +3 -0
- package/dist/src/utils/parsing.d.ts.map +1 -0
- package/dist/src/utils/parsing.js +14 -0
- package/dist/src/utils/parsing.js.map +1 -0
- package/dist/src/utils/safeExec.d.ts +7 -0
- package/dist/src/utils/safeExec.d.ts.map +1 -0
- package/dist/src/utils/safeExec.js +31 -0
- package/dist/src/utils/safeExec.js.map +1 -0
- package/dist/src/utils/time.d.ts +2 -0
- package/dist/src/utils/time.d.ts.map +1 -0
- package/dist/src/utils/time.js +2 -0
- package/dist/src/utils/time.js.map +1 -0
- package/mcp-manifest.json +19 -0
- package/package.json +49 -0
- package/scripts/setup-win.ps1 +14 -0
- package/scripts/validate-manifest.mjs +26 -0
- package/scripts/verify-config.ps1 +22 -0
- package/templates/env.template +11 -0
- package/templates/mcp.config.template.json +13 -0
- package/templates/vscode.mcp.template.json +11 -0
- package/templates/vscode.user.mcp.template.json +11 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 NANDI Services
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# nandi-proxmox-mcp
|
|
2
|
+
|
|
3
|
+
Open source MCP Server for Proxmox, powered by NANDI Services.
|
|
4
|
+
|
|
5
|
+
`nandi-proxmox-mcp` lets users connect to their own Proxmox server and operate nodes, VMs, and CT/LXC securely via MCP tools in VS Code.
|
|
6
|
+
|
|
7
|
+
## Important: API token ownership
|
|
8
|
+
The Proxmox API token is **not** delivered by npm, VS Code, or this MCP package.
|
|
9
|
+
Each user must create a token in their own Proxmox environment with minimum ACL permissions.
|
|
10
|
+
|
|
11
|
+
## 5-minute Quickstart (Windows)
|
|
12
|
+
1. Install Node.js 20+.
|
|
13
|
+
2. Run `npm install -g nandi-proxmox-mcp`.
|
|
14
|
+
3. Run `nandi-proxmox-mcp setup` and complete guided onboarding.
|
|
15
|
+
4. Run `nandi-proxmox-mcp doctor --check mcp-config,nodes,vms,cts,node-status,remote-op`.
|
|
16
|
+
5. Open VS Code and confirm MCP server is registered (`.vscode/mcp.json`).
|
|
17
|
+
|
|
18
|
+
Alternative direct run:
|
|
19
|
+
- `npx nandi-proxmox-mcp setup`
|
|
20
|
+
- `npx nandi-proxmox-mcp run`
|
|
21
|
+
|
|
22
|
+
## VS Code / Codex plug-and-play paths
|
|
23
|
+
- Custom server: use `.vscode/mcp.json` (root `servers` format).
|
|
24
|
+
- Manifest install: use `mcp-manifest.json`.
|
|
25
|
+
- User-level config template: `templates/vscode.user.mcp.template.json`.
|
|
26
|
+
|
|
27
|
+
## MCP tools included
|
|
28
|
+
- Inventory: `listNodes`, `listVMs`, `listContainers`
|
|
29
|
+
- Status: `getNodeStatus`, `getVMStatus`, `getContainerStatus`
|
|
30
|
+
- Control: `startVM`, `stopVM`, `startContainer`, `stopContainer`
|
|
31
|
+
- CT operations: `execInContainer`, `dockerPsInContainer`, `dockerLogsInContainer`, `runRemoteDiagnostic`, `sshBatchDiagnostics`
|
|
32
|
+
|
|
33
|
+
## Security principles
|
|
34
|
+
- No hardcoded host/token secrets in versioned files.
|
|
35
|
+
- Local sensitive config generated in `.nandi-proxmox-mcp/config.json`.
|
|
36
|
+
- Templates with placeholders only.
|
|
37
|
+
- CI includes secret scanning and dependency scanning.
|
|
38
|
+
|
|
39
|
+
## Docs
|
|
40
|
+
- [Quickstart](docs/QUICKSTART.md)
|
|
41
|
+
- [Windows Installation](docs/INSTALL_WINDOWS.md)
|
|
42
|
+
- [Proxmox Token + ACL Setup](docs/PROXMOX_SETUP.md)
|
|
43
|
+
- [SSH Setup and Batch Validation](docs/SSH_SETUP.md)
|
|
44
|
+
- [VS Code MCP Setup](docs/VSCODE_SETUP.md)
|
|
45
|
+
- [Marketplace Go-Live](docs/MARKETPLACE_GO_LIVE.md)
|
|
46
|
+
- [Security Guide](docs/SECURITY.md)
|
|
47
|
+
- [Troubleshooting](docs/TROUBLESHOOTING.md)
|
|
48
|
+
- [FAQ](docs/FAQ.md)
|
|
49
|
+
- [CI Secrets Policy](docs/CI_SECRETS.md)
|
|
50
|
+
|
|
51
|
+
## Development
|
|
52
|
+
- `npm ci`
|
|
53
|
+
- `npm run lint`
|
|
54
|
+
- `npm run typecheck`
|
|
55
|
+
- `npm test`
|
|
56
|
+
- `npm run build`
|
|
57
|
+
|
|
58
|
+
## License
|
|
59
|
+
MIT. See LICENSE.
|
|
60
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/doctor.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,SAAS,GAAU,YAAY,MAAM,KAAG,OAAO,CAAC,IAAI,CA4HhE,CAAC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { loadFileConfig } from "../config/fileConfig.js";
|
|
4
|
+
import { ProxmoxClient } from "../proxmox/client.js";
|
|
5
|
+
import { printReport } from "./report.js";
|
|
6
|
+
import { runSshBatch } from "../ssh/sshClient.js";
|
|
7
|
+
import { pctExec } from "../ssh/pctExec.js";
|
|
8
|
+
import { normalizeMcpConfigDocument, validateMcpConfig, validateMcpManifest } from "../config/installDescriptor.js";
|
|
9
|
+
const parseRequestedChecks = (value) => {
|
|
10
|
+
if (!value) {
|
|
11
|
+
return new Set(["mcp-config", "nodes", "vms", "cts", "node-status", "remote-op"]);
|
|
12
|
+
}
|
|
13
|
+
return new Set(value.split(",").map((segment) => segment.trim()).filter(Boolean));
|
|
14
|
+
};
|
|
15
|
+
export const runDoctor = async (checksArg) => {
|
|
16
|
+
const checks = parseRequestedChecks(checksArg);
|
|
17
|
+
const report = [];
|
|
18
|
+
const config = await loadFileConfig();
|
|
19
|
+
const client = new ProxmoxClient(config);
|
|
20
|
+
let firstNode = "";
|
|
21
|
+
if (checks.has("mcp-config")) {
|
|
22
|
+
try {
|
|
23
|
+
const mcpPath = resolve(process.cwd(), ".vscode", "mcp.json");
|
|
24
|
+
const manifestPath = resolve(process.cwd(), "mcp-manifest.json");
|
|
25
|
+
const mcpRaw = await readFile(mcpPath, "utf8");
|
|
26
|
+
const normalized = normalizeMcpConfigDocument(mcpRaw);
|
|
27
|
+
const configValidation = validateMcpConfig(normalized.normalized);
|
|
28
|
+
if (!configValidation.ok) {
|
|
29
|
+
throw new Error(configValidation.errors.join(" | "));
|
|
30
|
+
}
|
|
31
|
+
const manifestRaw = await readFile(manifestPath, "utf8");
|
|
32
|
+
const manifestValidation = validateMcpManifest(JSON.parse(manifestRaw));
|
|
33
|
+
if (!manifestValidation.ok) {
|
|
34
|
+
throw new Error(`Manifest invalid: ${manifestValidation.errors.join(" | ")}`);
|
|
35
|
+
}
|
|
36
|
+
report.push({ check: "mcpConfig", ok: true, detail: "MCP config and manifest are valid" });
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
report.push({ check: "mcpConfig", ok: false, detail: error instanceof Error ? error.message : "Unknown error" });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (checks.has("nodes")) {
|
|
43
|
+
try {
|
|
44
|
+
const nodes = await client.listNodes();
|
|
45
|
+
firstNode = nodes[0]?.node ?? "";
|
|
46
|
+
report.push({ check: "listNodes", ok: true, detail: `Found ${nodes.length} nodes` });
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
report.push({
|
|
50
|
+
check: "listNodes",
|
|
51
|
+
ok: false,
|
|
52
|
+
detail: error instanceof Error ? error.message : "Unknown error"
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (checks.has("vms") && firstNode) {
|
|
57
|
+
try {
|
|
58
|
+
const vms = await client.listVms(firstNode);
|
|
59
|
+
report.push({ check: "listVMs", ok: true, detail: `Found ${vms.length} VMs on ${firstNode}` });
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
report.push({ check: "listVMs", ok: false, detail: error instanceof Error ? error.message : "Unknown error" });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (checks.has("cts") && firstNode) {
|
|
66
|
+
try {
|
|
67
|
+
const cts = await client.listContainers(firstNode);
|
|
68
|
+
report.push({ check: "listContainers", ok: true, detail: `Found ${cts.length} CTs on ${firstNode}` });
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
report.push({ check: "listContainers", ok: false, detail: error instanceof Error ? error.message : "Unknown error" });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (checks.has("node-status") && firstNode) {
|
|
75
|
+
try {
|
|
76
|
+
const status = await client.getNodeStatus(firstNode);
|
|
77
|
+
const keyCount = Object.keys(status).length;
|
|
78
|
+
report.push({ check: "getNodeStatus", ok: true, detail: `Status keys: ${keyCount}` });
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
report.push({ check: "getNodeStatus", ok: false, detail: error instanceof Error ? error.message : "Unknown error" });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (checks.has("remote-op")) {
|
|
85
|
+
try {
|
|
86
|
+
const sshRes = await runSshBatch({
|
|
87
|
+
host: config.sshHost,
|
|
88
|
+
port: config.sshPort,
|
|
89
|
+
user: config.sshUser,
|
|
90
|
+
keyPath: config.sshKeyPath,
|
|
91
|
+
timeoutMs: 15_000
|
|
92
|
+
}, "echo ssh-batch-ok");
|
|
93
|
+
if (sshRes.exitCode !== 0) {
|
|
94
|
+
throw new Error(`SSH batch failed. Interactive may still work. stderr=${sshRes.stderr.trim()}`);
|
|
95
|
+
}
|
|
96
|
+
report.push({ check: "sshBatch", ok: true, detail: "Batch SSH succeeded" });
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
report.push({ check: "sshBatch", ok: false, detail: error instanceof Error ? error.message : "Unknown error" });
|
|
100
|
+
}
|
|
101
|
+
const ctid = Number.parseInt(process.env.NANDI_DOCTOR_CTID ?? "0", 10);
|
|
102
|
+
if (Number.isFinite(ctid) && ctid > 0) {
|
|
103
|
+
try {
|
|
104
|
+
await pctExec({
|
|
105
|
+
host: config.sshHost,
|
|
106
|
+
port: config.sshPort,
|
|
107
|
+
user: config.sshUser,
|
|
108
|
+
keyPath: config.sshKeyPath,
|
|
109
|
+
timeoutMs: 20_000
|
|
110
|
+
}, ctid, "echo ct-remote-ok");
|
|
111
|
+
report.push({ check: "pctExec", ok: true, detail: `pct exec succeeded for CT ${ctid}` });
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
report.push({ check: "pctExec", ok: false, detail: error instanceof Error ? error.message : "Unknown error" });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
report.push({
|
|
119
|
+
check: "pctExec",
|
|
120
|
+
ok: false,
|
|
121
|
+
detail: "Set NANDI_DOCTOR_CTID environment variable to validate CT remote operation"
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
printReport("Doctor report", report);
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/cli/main.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { runSetup } from "./setup.js";
|
|
4
|
+
import { runDoctor } from "./doctor.js";
|
|
5
|
+
import { loadFileConfig } from "../config/fileConfig.js";
|
|
6
|
+
import { startMcpServer } from "../server/mcpServer.js";
|
|
7
|
+
const program = new Command();
|
|
8
|
+
program.name("nandi-proxmox-mcp").description("Proxmox MCP server - open source, powered by NANDI Services").version("0.1.0");
|
|
9
|
+
program
|
|
10
|
+
.command("setup")
|
|
11
|
+
.description("Run interactive Windows-first setup")
|
|
12
|
+
.action(async () => {
|
|
13
|
+
await runSetup();
|
|
14
|
+
});
|
|
15
|
+
program
|
|
16
|
+
.command("doctor")
|
|
17
|
+
.description("Run post-install checks")
|
|
18
|
+
.option("--check <checks>", "Comma-separated checks: mcp-config,nodes,vms,cts,node-status,remote-op")
|
|
19
|
+
.action(async (options) => {
|
|
20
|
+
await runDoctor(options.check);
|
|
21
|
+
});
|
|
22
|
+
program
|
|
23
|
+
.command("run")
|
|
24
|
+
.description("Run MCP server over stdio")
|
|
25
|
+
.action(async () => {
|
|
26
|
+
const config = await loadFileConfig();
|
|
27
|
+
await startMcpServer(config);
|
|
28
|
+
});
|
|
29
|
+
void program.parseAsync(process.argv);
|
|
30
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/cli/main.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,WAAW,CAAC,6DAA6D,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAE9H,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,QAAQ,EAAE,CAAC;AACnB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,kBAAkB,EAAE,wEAAwE,CAAC;KACpG,MAAM,CAAC,KAAK,EAAE,OAA2B,EAAE,EAAE;IAC5C,MAAM,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,2BAA2B,CAAC;KACxC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEL,KAAK,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/cli/report.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,EAAE,OAAO,UAAU,EAAE,KAAG,IAQhE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const printReport = (title, items) => {
|
|
2
|
+
process.stdout.write(`\n${title}\n`);
|
|
3
|
+
process.stdout.write(`${"-".repeat(title.length)}\n`);
|
|
4
|
+
for (const item of items) {
|
|
5
|
+
const light = item.ok ? "GREEN" : "RED";
|
|
6
|
+
process.stdout.write(`[${light}] ${item.check}: ${item.detail}\n`);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/cli/report.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAa,EAAE,KAAmB,EAAQ,EAAE;IACtE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAEtD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;QACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IACrE,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/setup.ts"],"names":[],"mappings":"AA+JA,eAAO,MAAM,QAAQ,QAAa,OAAO,CAAC,IAAI,CAsB7C,CAAC"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { createInterface } from "node:readline/promises";
|
|
4
|
+
import { stdin as input, stdout as output } from "node:process";
|
|
5
|
+
import { ProxmoxClient } from "../proxmox/client.js";
|
|
6
|
+
import { runtimeConfigSchema } from "../config/validate.js";
|
|
7
|
+
import { printReport } from "./report.js";
|
|
8
|
+
import { runSshBatch } from "../ssh/sshClient.js";
|
|
9
|
+
import { buildWorkspaceMcpConfig, normalizeMcpConfigDocument, validateMcpConfig } from "../config/installDescriptor.js";
|
|
10
|
+
const defaultConfigDir = resolve(process.cwd(), ".nandi-proxmox-mcp");
|
|
11
|
+
const defaultConfigPath = resolve(defaultConfigDir, "config.json");
|
|
12
|
+
const ask = async () => {
|
|
13
|
+
const rl = createInterface({ input, output });
|
|
14
|
+
const proxmoxHost = (await rl.question("Proxmox host (IP/FQDN): ")).trim();
|
|
15
|
+
const proxmoxPort = Number.parseInt((await rl.question("Proxmox port [8006]: ")).trim() || "8006", 10);
|
|
16
|
+
const proxmoxUser = (await rl.question("Proxmox user (without realm, e.g. svc_mcp): ")).trim();
|
|
17
|
+
const proxmoxRealm = (await rl.question("Proxmox realm [pve]: ")).trim() || "pve";
|
|
18
|
+
const tokenName = (await rl.question("API token name (e.g. nandi-mcp): ")).trim();
|
|
19
|
+
const tokenSecret = (await rl.question("API token secret: ")).trim();
|
|
20
|
+
const allowInsecureTls = ((await rl.question("Allow insecure TLS for self-signed cert? [no]: ")).trim() || "no")
|
|
21
|
+
.toLowerCase()
|
|
22
|
+
.startsWith("y");
|
|
23
|
+
const sshHost = (await rl.question("SSH host [same as Proxmox host]: ")).trim() || proxmoxHost;
|
|
24
|
+
const sshPort = Number.parseInt((await rl.question("SSH port [22]: ")).trim() || "22", 10);
|
|
25
|
+
const sshUser = (await rl.question("SSH user [root]: ")).trim() || "root";
|
|
26
|
+
const sshKeyPath = (await rl.question("SSH private key path [~/.ssh/id_ed25519]: ")).trim() ||
|
|
27
|
+
resolve(process.env.USERPROFILE ?? process.env.HOME ?? ".", ".ssh", "id_ed25519");
|
|
28
|
+
rl.close();
|
|
29
|
+
return runtimeConfigSchema.parse({
|
|
30
|
+
proxmoxHost,
|
|
31
|
+
proxmoxPort,
|
|
32
|
+
proxmoxUser,
|
|
33
|
+
proxmoxRealm,
|
|
34
|
+
tokenName,
|
|
35
|
+
tokenSecret,
|
|
36
|
+
allowInsecureTls,
|
|
37
|
+
sshHost,
|
|
38
|
+
sshPort,
|
|
39
|
+
sshUser,
|
|
40
|
+
sshKeyPath
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
const validatePrereqs = async () => {
|
|
44
|
+
const checks = [];
|
|
45
|
+
checks.push({
|
|
46
|
+
check: "Node.js",
|
|
47
|
+
ok: Number(process.versions.node.split(".")[0]) >= 20,
|
|
48
|
+
detail: `Detected ${process.versions.node}`
|
|
49
|
+
});
|
|
50
|
+
const npmUserAgent = process.env.npm_config_user_agent;
|
|
51
|
+
checks.push({
|
|
52
|
+
check: "npm",
|
|
53
|
+
ok: Boolean(npmUserAgent),
|
|
54
|
+
detail: npmUserAgent ?? "npm user agent not detected"
|
|
55
|
+
});
|
|
56
|
+
return checks;
|
|
57
|
+
};
|
|
58
|
+
const writeVscodeConfig = async () => {
|
|
59
|
+
const vscodeDir = resolve(process.cwd(), ".vscode");
|
|
60
|
+
await mkdir(vscodeDir, { recursive: true });
|
|
61
|
+
const mcpPath = resolve(vscodeDir, "mcp.json");
|
|
62
|
+
const resolvedConfigPath = resolve(process.cwd(), ".nandi-proxmox-mcp", "config.json");
|
|
63
|
+
let config = buildWorkspaceMcpConfig(resolvedConfigPath);
|
|
64
|
+
let migratedLegacy = false;
|
|
65
|
+
try {
|
|
66
|
+
const existing = await readFile(mcpPath, "utf8");
|
|
67
|
+
const normalized = normalizeMcpConfigDocument(existing);
|
|
68
|
+
config = normalized.normalized;
|
|
69
|
+
migratedLegacy = normalized.migratedLegacy;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// No previous config or invalid JSON, fall back to generated structure.
|
|
73
|
+
}
|
|
74
|
+
config.servers["nandi-proxmox-mcp"] = {
|
|
75
|
+
command: "npx",
|
|
76
|
+
args: ["nandi-proxmox-mcp", "run"],
|
|
77
|
+
env: {
|
|
78
|
+
NANDI_PROXMOX_CONFIG: resolvedConfigPath
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const validation = validateMcpConfig(config);
|
|
82
|
+
if (!validation.ok) {
|
|
83
|
+
throw new Error(`Generated MCP config failed validation: ${validation.errors.join(" | ")}`);
|
|
84
|
+
}
|
|
85
|
+
await writeFile(mcpPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
|
|
86
|
+
if (migratedLegacy) {
|
|
87
|
+
process.stdout.write("Migrated legacy `.vscode/mcp.json` format to root `servers` format.\n");
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const connectivityChecks = async (config) => {
|
|
91
|
+
const client = new ProxmoxClient(config);
|
|
92
|
+
const checks = [];
|
|
93
|
+
try {
|
|
94
|
+
const nodes = await client.listNodes();
|
|
95
|
+
checks.push({
|
|
96
|
+
check: "Proxmox API token connectivity",
|
|
97
|
+
ok: true,
|
|
98
|
+
detail: `Connected. Nodes discovered: ${nodes.length}`
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
checks.push({
|
|
103
|
+
check: "Proxmox API token connectivity",
|
|
104
|
+
ok: false,
|
|
105
|
+
detail: error instanceof Error ? error.message : "Unknown Proxmox connectivity error"
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
const ssh = await runSshBatch({
|
|
110
|
+
host: config.sshHost,
|
|
111
|
+
port: config.sshPort,
|
|
112
|
+
user: config.sshUser,
|
|
113
|
+
keyPath: config.sshKeyPath,
|
|
114
|
+
timeoutMs: 12_000
|
|
115
|
+
}, "echo ssh-batch-ok");
|
|
116
|
+
checks.push({
|
|
117
|
+
check: "SSH batch (non-interactive)",
|
|
118
|
+
ok: ssh.exitCode === 0 && ssh.stdout.includes("ssh-batch-ok"),
|
|
119
|
+
detail: ssh.exitCode === 0 ? "Batch SSH command succeeded" : ssh.stderr.trim()
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
checks.push({
|
|
124
|
+
check: "SSH batch (non-interactive)",
|
|
125
|
+
ok: false,
|
|
126
|
+
detail: error instanceof Error ? error.message : "Unknown SSH batch error"
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return checks;
|
|
130
|
+
};
|
|
131
|
+
export const runSetup = async () => {
|
|
132
|
+
process.stdout.write("nandi-proxmox-mcp setup wizard\n");
|
|
133
|
+
process.stdout.write("The API token is NOT provided by npm or MCP. You must create it in your own Proxmox server.\n\n");
|
|
134
|
+
const prereq = await validatePrereqs();
|
|
135
|
+
printReport("Prerequisites", prereq);
|
|
136
|
+
const config = await ask();
|
|
137
|
+
await mkdir(defaultConfigDir, { recursive: true });
|
|
138
|
+
await writeFile(defaultConfigPath, `${JSON.stringify(config, null, 2)}\n`, "utf8");
|
|
139
|
+
await writeVscodeConfig();
|
|
140
|
+
const connectivity = await connectivityChecks(config);
|
|
141
|
+
printReport("Connectivity", connectivity);
|
|
142
|
+
const allOk = [...prereq, ...connectivity].every((item) => item.ok);
|
|
143
|
+
process.stdout.write(`\nFinal status: ${allOk ? "GREEN" : "RED"}\n`);
|
|
144
|
+
process.stdout.write(`Local config created at: ${defaultConfigPath}\n`);
|
|
145
|
+
process.stdout.write("\nNext steps for VS Code/Codex:\n");
|
|
146
|
+
process.stdout.write("1. Open MCP settings and verify `nandi-proxmox-mcp` appears.\n");
|
|
147
|
+
process.stdout.write("2. If needed, use `.vscode/mcp.json` generated by setup as your custom server source.\n");
|
|
148
|
+
process.stdout.write("3. Run `nandi-proxmox-mcp doctor --check mcp-config,nodes,vms,cts,node-status,remote-op`.\n");
|
|
149
|
+
};
|
|
150
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../../src/cli/setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAGxE,eAAO,MAAM,aAAa,QAAO,aAgBhC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { runtimeConfigSchema } from "./validate.js";
|
|
2
|
+
import { parseBool, parseInteger } from "../utils/parsing.js";
|
|
3
|
+
export const loadEnvConfig = () => {
|
|
4
|
+
const candidate = {
|
|
5
|
+
proxmoxHost: process.env.PROXMOX_HOST,
|
|
6
|
+
proxmoxPort: parseInteger(process.env.PROXMOX_PORT, 8006),
|
|
7
|
+
proxmoxUser: process.env.PROXMOX_USER,
|
|
8
|
+
proxmoxRealm: process.env.PROXMOX_REALM,
|
|
9
|
+
tokenName: process.env.PROXMOX_TOKEN_NAME,
|
|
10
|
+
tokenSecret: process.env.PROXMOX_TOKEN_SECRET,
|
|
11
|
+
allowInsecureTls: parseBool(process.env.PROXMOX_ALLOW_INSECURE_TLS, false),
|
|
12
|
+
sshHost: process.env.PROXMOX_SSH_HOST ?? process.env.PROXMOX_HOST,
|
|
13
|
+
sshPort: parseInteger(process.env.PROXMOX_SSH_PORT, 22),
|
|
14
|
+
sshUser: process.env.PROXMOX_SSH_USER ?? "root",
|
|
15
|
+
sshKeyPath: process.env.PROXMOX_SSH_KEY_PATH ?? ""
|
|
16
|
+
};
|
|
17
|
+
return runtimeConfigSchema.parse(candidate);
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../../src/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAsB,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE9D,MAAM,CAAC,MAAM,aAAa,GAAG,GAAkB,EAAE;IAC/C,MAAM,SAAS,GAAG;QAChB,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,WAAW,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC;QACzD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,aAAa;QACvC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;QACzC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAC7C,gBAAgB,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC;QAC1E,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QACjE,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,EAAE,CAAC;QACvD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM;QAC/C,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE;KACnD,CAAC;IAEF,OAAO,mBAAmB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AAC9C,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileConfig.d.ts","sourceRoot":"","sources":["../../../src/config/fileConfig.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAExE,eAAO,MAAM,iBAAiB,QAAO,MAEpC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,eAAe,MAAM,KAAG,OAAO,CAAC,aAAa,CAKjF,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { runtimeConfigSchema } from "./validate.js";
|
|
4
|
+
export const defaultConfigPath = () => {
|
|
5
|
+
return resolve(process.cwd(), ".nandi-proxmox-mcp", "config.json");
|
|
6
|
+
};
|
|
7
|
+
export const loadFileConfig = async (explicitPath) => {
|
|
8
|
+
const path = explicitPath ?? process.env.NANDI_PROXMOX_CONFIG ?? defaultConfigPath();
|
|
9
|
+
const raw = await readFile(path, "utf8");
|
|
10
|
+
const parsed = JSON.parse(raw);
|
|
11
|
+
return runtimeConfigSchema.parse(parsed);
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=fileConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileConfig.js","sourceRoot":"","sources":["../../../src/config/fileConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAsB,MAAM,eAAe,CAAC;AAExE,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAW,EAAE;IAC5C,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,EAAE,aAAa,CAAC,CAAC;AACrE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,YAAqB,EAA0B,EAAE;IACpF,MAAM,IAAI,GAAG,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,iBAAiB,EAAE,CAAC;IACrF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;IAC1C,OAAO,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC3C,CAAC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type McpServerEntry = {
|
|
2
|
+
command: string;
|
|
3
|
+
args: string[];
|
|
4
|
+
env?: Record<string, string>;
|
|
5
|
+
};
|
|
6
|
+
export type McpConfigFile = {
|
|
7
|
+
servers: Record<string, McpServerEntry>;
|
|
8
|
+
};
|
|
9
|
+
export type McpManifest = {
|
|
10
|
+
schema_version: string;
|
|
11
|
+
id: string;
|
|
12
|
+
display_name: string;
|
|
13
|
+
description: string;
|
|
14
|
+
transport: "stdio";
|
|
15
|
+
runtime: McpServerEntry;
|
|
16
|
+
docs: {
|
|
17
|
+
quickstart: string;
|
|
18
|
+
security: string;
|
|
19
|
+
troubleshooting: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export declare const serverId = "nandi-proxmox-mcp";
|
|
23
|
+
export declare const buildWorkspaceMcpConfig: (configPath: string) => McpConfigFile;
|
|
24
|
+
export declare const normalizeMcpConfigDocument: (raw: string) => {
|
|
25
|
+
normalized: McpConfigFile;
|
|
26
|
+
migratedLegacy: boolean;
|
|
27
|
+
};
|
|
28
|
+
export declare const validateMcpConfig: (value: unknown) => {
|
|
29
|
+
ok: boolean;
|
|
30
|
+
errors: string[];
|
|
31
|
+
};
|
|
32
|
+
export declare const validateMcpManifest: (value: unknown) => {
|
|
33
|
+
ok: boolean;
|
|
34
|
+
errors: string[];
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=installDescriptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installDescriptor.d.ts","sourceRoot":"","sources":["../../../src/config/installDescriptor.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE;QACJ,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH,CAAC;AAEF,eAAO,MAAM,QAAQ,sBAAsB,CAAC;AAE5C,eAAO,MAAM,uBAAuB,GAAI,YAAY,MAAM,KAAG,aAU3D,CAAC;AAEH,eAAO,MAAM,0BAA0B,GAAI,KAAK,MAAM,KAAG;IACvD,UAAU,EAAE,aAAa,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;CAiCzB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAkCjF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,OAAO,OAAO,KAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAmBnF,CAAC"}
|