@wrongstack/mcp 0.318.0 → 0.319.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/dist/index.js +38 -5
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -817,10 +817,11 @@ function boundedServerName(value) {
|
|
|
817
817
|
|
|
818
818
|
// src/client.ts
|
|
819
819
|
import { spawn as spawn2 } from "node:child_process";
|
|
820
|
-
import { buildChildEnv, buildWin32CmdShimInvocation, toErrorMessage } from "@wrongstack/core/utils";
|
|
820
|
+
import { buildChildEnv as buildChildEnv2, buildWin32CmdShimInvocation, toErrorMessage } from "@wrongstack/core/utils";
|
|
821
821
|
|
|
822
822
|
// src/client-process.ts
|
|
823
823
|
import { spawn } from "node:child_process";
|
|
824
|
+
import { buildChildEnv } from "@wrongstack/core/utils";
|
|
824
825
|
function forceKillTree(child) {
|
|
825
826
|
if (child.pid === void 0) {
|
|
826
827
|
try {
|
|
@@ -832,6 +833,9 @@ function forceKillTree(child) {
|
|
|
832
833
|
if (process.platform === "win32") {
|
|
833
834
|
const killer = spawn("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
|
|
834
835
|
stdio: "ignore",
|
|
836
|
+
// H-8 convention (spawn-convention test): taskkill needs PATH only —
|
|
837
|
+
// do not hand it the credential-bearing parent environment.
|
|
838
|
+
env: buildChildEnv(),
|
|
835
839
|
windowsHide: true
|
|
836
840
|
});
|
|
837
841
|
killer.once("error", () => {
|
|
@@ -2284,7 +2288,7 @@ var MCPClient = class _MCPClient {
|
|
|
2284
2288
|
}
|
|
2285
2289
|
const isWin = process.platform === "win32";
|
|
2286
2290
|
const rawArgs = this.opts.args ?? [];
|
|
2287
|
-
const spawnEnv =
|
|
2291
|
+
const spawnEnv = buildChildEnv2({ extra: extraEnv });
|
|
2288
2292
|
const stdio = ["pipe", "pipe", "pipe"];
|
|
2289
2293
|
const child = isWin ? (() => {
|
|
2290
2294
|
const shim = buildWin32CmdShimInvocation(this.opts.command, rawArgs);
|
|
@@ -3036,6 +3040,11 @@ async function persist(configPath, full, servers) {
|
|
|
3036
3040
|
full.mcpServers = servers;
|
|
3037
3041
|
await writeConfig(configPath, full);
|
|
3038
3042
|
}
|
|
3043
|
+
var UNSAFE_SERVER_NAMES = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
3044
|
+
function unsafeServerNameResult(name) {
|
|
3045
|
+
if (!UNSAFE_SERVER_NAMES.has(name)) return void 0;
|
|
3046
|
+
return { ok: false, message: `Invalid server name "${name}"` };
|
|
3047
|
+
}
|
|
3039
3048
|
function normalizeTransport(t) {
|
|
3040
3049
|
if (t === "sse") return "sse";
|
|
3041
3050
|
if (t === "http" || t === "streamable-http") return "streamable-http";
|
|
@@ -3124,11 +3133,13 @@ async function listMcp(deps) {
|
|
|
3124
3133
|
}
|
|
3125
3134
|
async function addMcp(input, deps) {
|
|
3126
3135
|
if (!input.name) return { ok: false, message: "Server name is required" };
|
|
3136
|
+
const unsafe = unsafeServerNameResult(input.name);
|
|
3137
|
+
if (unsafe) return unsafe;
|
|
3127
3138
|
const { full, servers } = await readServers(deps.configPath);
|
|
3128
|
-
if (servers
|
|
3139
|
+
if (Object.hasOwn(servers, input.name)) {
|
|
3129
3140
|
return { ok: false, message: `Server "${input.name}" already exists` };
|
|
3130
3141
|
}
|
|
3131
|
-
const preset = deps.presets
|
|
3142
|
+
const preset = deps.presets && Object.hasOwn(deps.presets, input.name) ? deps.presets[input.name] : void 0;
|
|
3132
3143
|
const hasExplicitConfig = !!(input.transport || input.command || input.url);
|
|
3133
3144
|
const cfg = hasExplicitConfig ? buildConfig(input, preset) : preset ? buildConfig({ ...input, name: input.name }, preset) : buildConfig(input);
|
|
3134
3145
|
if (!hasExplicitConfig && !preset) {
|
|
@@ -3153,7 +3164,12 @@ async function addMcp(input, deps) {
|
|
|
3153
3164
|
}
|
|
3154
3165
|
async function updateMcp(input, deps) {
|
|
3155
3166
|
if (!input.name) return { ok: false, message: "Server name is required" };
|
|
3167
|
+
const unsafe = unsafeServerNameResult(input.name);
|
|
3168
|
+
if (unsafe) return unsafe;
|
|
3156
3169
|
const { full, servers } = await readServers(deps.configPath);
|
|
3170
|
+
if (!Object.hasOwn(servers, input.name)) {
|
|
3171
|
+
return { ok: false, message: `Server "${input.name}" not found` };
|
|
3172
|
+
}
|
|
3157
3173
|
const existing = servers[input.name];
|
|
3158
3174
|
if (!existing) return { ok: false, message: `Server "${input.name}" not found` };
|
|
3159
3175
|
const cfg = buildConfig(input, { ...existing, name: input.name });
|
|
@@ -3172,8 +3188,10 @@ async function updateMcp(input, deps) {
|
|
|
3172
3188
|
}
|
|
3173
3189
|
async function removeMcp(name, deps) {
|
|
3174
3190
|
if (!name) return { ok: false, message: "Server name is required" };
|
|
3191
|
+
const unsafe = unsafeServerNameResult(name);
|
|
3192
|
+
if (unsafe) return unsafe;
|
|
3175
3193
|
const { full, servers } = await readServers(deps.configPath);
|
|
3176
|
-
if (!servers
|
|
3194
|
+
if (!Object.hasOwn(servers, name)) return { ok: false, message: `Server "${name}" not found` };
|
|
3177
3195
|
await safeStop(name, deps);
|
|
3178
3196
|
forgetRegistryState(deps.registry, name);
|
|
3179
3197
|
delete servers[name];
|
|
@@ -3182,7 +3200,12 @@ async function removeMcp(name, deps) {
|
|
|
3182
3200
|
}
|
|
3183
3201
|
async function enableMcp(name, deps) {
|
|
3184
3202
|
if (!name) return { ok: false, message: "Server name is required" };
|
|
3203
|
+
const unsafe = unsafeServerNameResult(name);
|
|
3204
|
+
if (unsafe) return unsafe;
|
|
3185
3205
|
const { full, servers } = await readServers(deps.configPath);
|
|
3206
|
+
if (!Object.hasOwn(servers, name)) {
|
|
3207
|
+
return { ok: false, message: `Server "${name}" is not in config. Add it first.` };
|
|
3208
|
+
}
|
|
3186
3209
|
const cfg = servers[name];
|
|
3187
3210
|
if (!cfg) {
|
|
3188
3211
|
return { ok: false, message: `Server "${name}" is not in config. Add it first.` };
|
|
@@ -3194,7 +3217,12 @@ async function enableMcp(name, deps) {
|
|
|
3194
3217
|
}
|
|
3195
3218
|
async function disableMcp(name, deps) {
|
|
3196
3219
|
if (!name) return { ok: false, message: "Server name is required" };
|
|
3220
|
+
const unsafe = unsafeServerNameResult(name);
|
|
3221
|
+
if (unsafe) return unsafe;
|
|
3197
3222
|
const { full, servers } = await readServers(deps.configPath);
|
|
3223
|
+
if (!Object.hasOwn(servers, name)) {
|
|
3224
|
+
return { ok: false, message: `Server "${name}" is not in config.` };
|
|
3225
|
+
}
|
|
3198
3226
|
const cfg = servers[name];
|
|
3199
3227
|
if (!cfg) return { ok: false, message: `Server "${name}" is not in config.` };
|
|
3200
3228
|
await safeStop(name, deps);
|
|
@@ -3210,6 +3238,8 @@ async function disableMcp(name, deps) {
|
|
|
3210
3238
|
}
|
|
3211
3239
|
async function restartMcp(name, deps) {
|
|
3212
3240
|
if (!name) return { ok: false, message: "Server name is required" };
|
|
3241
|
+
const unsafe = unsafeServerNameResult(name);
|
|
3242
|
+
if (unsafe) return unsafe;
|
|
3213
3243
|
const registered = deps.registry.list().some((s) => s.name === name);
|
|
3214
3244
|
if (registered) {
|
|
3215
3245
|
try {
|
|
@@ -3221,6 +3251,9 @@ async function restartMcp(name, deps) {
|
|
|
3221
3251
|
}
|
|
3222
3252
|
}
|
|
3223
3253
|
const { servers } = await readServers(deps.configPath);
|
|
3254
|
+
if (!Object.hasOwn(servers, name)) {
|
|
3255
|
+
return { ok: false, message: `Server "${name}" is not in config.` };
|
|
3256
|
+
}
|
|
3224
3257
|
const cfg = servers[name];
|
|
3225
3258
|
if (!cfg) return { ok: false, message: `Server "${name}" is not in config.` };
|
|
3226
3259
|
return startServer(name, { ...cfg, name }, deps, `Server "${name}" started`, { restart: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.319.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack Model Context Protocol client and registry: stdio, SSE, and streamable HTTP transports.",
|
|
6
6
|
"repository": {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"!dist/**/*.map"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@wrongstack/core": "0.
|
|
29
|
+
"@wrongstack/core": "0.319.1"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/node": "^26.2.0",
|