@cloudgrid-io/mcp 0.5.0 → 0.5.1
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/package.json +1 -1
- package/src/tools.js +60 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudgrid-io/mcp",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "MCP server for CloudGrid. Three editions: a local stdio server (full toolset), a hosted web server (light, CLI-free toolset), and a public docs server (search_cloudgrid_documentation) over MCP Streamable HTTP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/tools.js
CHANGED
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
// The difference is injected as a `ctx` object, so the tool logic is written once.
|
|
10
10
|
|
|
11
11
|
import { execFile } from "node:child_process";
|
|
12
|
-
import { createRequire } from "node:module";
|
|
13
12
|
import { promisify } from "node:util";
|
|
14
13
|
import { readFile } from "node:fs/promises";
|
|
15
14
|
import { readFileSync, existsSync, statSync } from "node:fs";
|
|
@@ -75,24 +74,42 @@ function resolveCwd(cwd) {
|
|
|
75
74
|
return abs;
|
|
76
75
|
}
|
|
77
76
|
|
|
78
|
-
//
|
|
79
|
-
|
|
77
|
+
// Pin the CLI version for the lazy npx fallback so behaviour is reproducible.
|
|
78
|
+
const CLI_NPX_PKG = "@cloudgrid-io/cli@^0.9.20";
|
|
79
|
+
|
|
80
|
+
// Minimum CLI version that supports the flags the MCP passes (--auto etc.).
|
|
81
|
+
const MIN_CLI_VERSION = "0.9.20";
|
|
82
|
+
|
|
83
|
+
// Simple semver comparison: true when `version` >= MIN_CLI_VERSION.
|
|
84
|
+
function meetsMinVersion(version) {
|
|
85
|
+
if (!version) return false;
|
|
86
|
+
const parse = (s) => s.replace(/^v/, "").split(".").map((p) => parseInt(p, 10) || 0);
|
|
87
|
+
const v = parse(version);
|
|
88
|
+
const m = parse(MIN_CLI_VERSION);
|
|
89
|
+
for (let i = 0; i < 3; i++) {
|
|
90
|
+
if ((v[i] || 0) > (m[i] || 0)) return true;
|
|
91
|
+
if ((v[i] || 0) < (m[i] || 0)) return false;
|
|
92
|
+
}
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Resolve the bundled CLI from this package's OWN node_modules only — never
|
|
97
|
+
// walk up to parent directories (which may contain stale CLI versions).
|
|
98
|
+
// Returns { entry, version } or null.
|
|
80
99
|
function resolveBundledCli() {
|
|
81
100
|
try {
|
|
82
|
-
const
|
|
83
|
-
const pkgPath =
|
|
101
|
+
const srcDir = dirname(new URL(import.meta.url).pathname);
|
|
102
|
+
const pkgPath = join(srcDir, "..", "node_modules", "@cloudgrid-io", "cli", "package.json");
|
|
103
|
+
if (!existsSync(pkgPath)) return null;
|
|
84
104
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
85
105
|
const bin = pkg.bin && pkg.bin.cloudgrid;
|
|
86
106
|
if (!bin) return null;
|
|
87
|
-
return join(dirname(pkgPath), bin);
|
|
107
|
+
return { entry: join(dirname(pkgPath), bin), version: pkg.version || null };
|
|
88
108
|
} catch {
|
|
89
109
|
return null;
|
|
90
110
|
}
|
|
91
111
|
}
|
|
92
112
|
|
|
93
|
-
// Pin the CLI version for the lazy npx fallback so behaviour is reproducible.
|
|
94
|
-
const CLI_NPX_PKG = "@cloudgrid-io/cli@^0.9.20";
|
|
95
|
-
|
|
96
113
|
async function runCloudgrid(args, opts = {}) {
|
|
97
114
|
const cwd = resolveCwd(opts.cwd);
|
|
98
115
|
const execOpts = {
|
|
@@ -110,28 +127,52 @@ async function runCloudgrid(args, opts = {}) {
|
|
|
110
127
|
return new Error(detail || "cloudgrid command failed");
|
|
111
128
|
};
|
|
112
129
|
|
|
113
|
-
// 1. Bundled CLI
|
|
130
|
+
// 1. Bundled CLI — own node_modules only, version-gated
|
|
114
131
|
const bundled = resolveBundledCli();
|
|
115
|
-
if (bundled) {
|
|
132
|
+
if (bundled && meetsMinVersion(bundled.version)) {
|
|
116
133
|
try {
|
|
117
134
|
const { stdout, stderr } = await execFileAsync(
|
|
118
135
|
process.execPath,
|
|
119
|
-
[bundled, ...args],
|
|
136
|
+
[bundled.entry, ...args],
|
|
120
137
|
execOpts,
|
|
121
138
|
);
|
|
122
139
|
return (stdout || stderr || "").trim() || "Done.";
|
|
123
140
|
} catch (err) {
|
|
124
141
|
throw extract(err);
|
|
125
142
|
}
|
|
143
|
+
} else if (bundled) {
|
|
144
|
+
console.error(
|
|
145
|
+
`cloudgrid-mcp: bundled CLI ${bundled.version} < ${MIN_CLI_VERSION}, skipping`,
|
|
146
|
+
);
|
|
126
147
|
}
|
|
127
148
|
|
|
128
|
-
// 2. Global `cloudgrid` on PATH
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
149
|
+
// 2. Global `cloudgrid` on PATH — version-gated
|
|
150
|
+
{
|
|
151
|
+
let useGlobal = false;
|
|
152
|
+
try {
|
|
153
|
+
const { stdout: vOut } = await execFileAsync("cloudgrid", ["--version"], {
|
|
154
|
+
timeout: 5_000,
|
|
155
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
156
|
+
});
|
|
157
|
+
const ver = vOut.trim().match(/(\d+\.\d+\.\d+)/)?.[1];
|
|
158
|
+
if (meetsMinVersion(ver)) {
|
|
159
|
+
useGlobal = true;
|
|
160
|
+
} else {
|
|
161
|
+
console.error(
|
|
162
|
+
`cloudgrid-mcp: global CLI ${ver || vOut.trim()} < ${MIN_CLI_VERSION}, skipping`,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
} catch {
|
|
166
|
+
// Not on PATH or --version failed — skip
|
|
167
|
+
}
|
|
168
|
+
if (useGlobal) {
|
|
169
|
+
try {
|
|
170
|
+
const { stdout, stderr } = await execFileAsync("cloudgrid", args, execOpts);
|
|
171
|
+
return (stdout || stderr || "").trim() || "Done.";
|
|
172
|
+
} catch (err) {
|
|
173
|
+
throw extract(err);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
135
176
|
}
|
|
136
177
|
|
|
137
178
|
// 3. Lazy fetch: npx -y @cloudgrid-io/cli@<pinned> <args>
|