@ai-ecoverse/mcpcat 0.17.7 → 0.17.9
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/host/mcpcat.mjs +54 -32
- package/dist/kernel/mcpcat.mjs +54 -32
- package/package.json +5 -5
package/dist/host/mcpcat.mjs
CHANGED
|
@@ -11172,11 +11172,30 @@ function redactWrites(platform2, redact2) {
|
|
|
11172
11172
|
write: (fd, data) => platform2.write(fd, typeof data === "string" ? redact2(data) : data)
|
|
11173
11173
|
});
|
|
11174
11174
|
}
|
|
11175
|
+
function secretMasker(secrets, mask) {
|
|
11176
|
+
const ordered = [...new Set(secrets)].filter((s) => s.length > 0);
|
|
11177
|
+
if (ordered.length === 0) return (text) => text;
|
|
11178
|
+
return (text) => {
|
|
11179
|
+
const hidden = new Uint8Array(text.length);
|
|
11180
|
+
for (const secret of ordered) {
|
|
11181
|
+
for (let at = text.indexOf(secret); at >= 0; at = text.indexOf(secret, at + 1)) {
|
|
11182
|
+
hidden.fill(1, at, at + secret.length);
|
|
11183
|
+
}
|
|
11184
|
+
}
|
|
11185
|
+
let out = "";
|
|
11186
|
+
let start = 0;
|
|
11187
|
+
while (start < text.length) {
|
|
11188
|
+
let end = start;
|
|
11189
|
+
const masked = hidden[start] === 1;
|
|
11190
|
+
while (end < text.length && hidden[end] === 1 === masked) end++;
|
|
11191
|
+
out += masked ? mask : text.slice(start, end);
|
|
11192
|
+
start = end;
|
|
11193
|
+
}
|
|
11194
|
+
return out;
|
|
11195
|
+
};
|
|
11196
|
+
}
|
|
11175
11197
|
function redactSecrets(text, secrets) {
|
|
11176
|
-
|
|
11177
|
-
let result = text;
|
|
11178
|
-
for (const secret of ordered) result = result.replaceAll(secret, "[REDACTED]");
|
|
11179
|
-
return result;
|
|
11198
|
+
return secretMasker(secrets, "[REDACTED]")(text);
|
|
11180
11199
|
}
|
|
11181
11200
|
|
|
11182
11201
|
// src/render/result.ts
|
|
@@ -12153,27 +12172,18 @@ function rpcError2(id, code2, message) {
|
|
|
12153
12172
|
body: JSON.stringify({ jsonrpc: "2.0", id, error: { code: code2, message } })
|
|
12154
12173
|
};
|
|
12155
12174
|
}
|
|
12156
|
-
function scrubValue(value,
|
|
12157
|
-
if (typeof value === "string") return
|
|
12158
|
-
if (Array.isArray(value)) return value.map((v) => scrubValue(v,
|
|
12175
|
+
function scrubValue(value, scrub) {
|
|
12176
|
+
if (typeof value === "string") return scrub(value);
|
|
12177
|
+
if (Array.isArray(value)) return value.map((v) => scrubValue(v, scrub));
|
|
12159
12178
|
if (value && typeof value === "object") {
|
|
12160
12179
|
const out = {};
|
|
12161
12180
|
for (const [k, v] of Object.entries(value)) {
|
|
12162
|
-
out[k] = scrubValue(v,
|
|
12181
|
+
out[k] = scrubValue(v, scrub);
|
|
12163
12182
|
}
|
|
12164
12183
|
return out;
|
|
12165
12184
|
}
|
|
12166
12185
|
return value;
|
|
12167
12186
|
}
|
|
12168
|
-
function scrubString(s, secrets) {
|
|
12169
|
-
let result = s;
|
|
12170
|
-
for (const h of secrets) {
|
|
12171
|
-
if (result.includes(h)) {
|
|
12172
|
-
result = result.replaceAll(h, "***");
|
|
12173
|
-
}
|
|
12174
|
-
}
|
|
12175
|
-
return result;
|
|
12176
|
-
}
|
|
12177
12187
|
function translateCapabilities(info) {
|
|
12178
12188
|
const caps = {};
|
|
12179
12189
|
if (info.capabilities.tools) caps.tools = { listChanged: false };
|
|
@@ -12197,7 +12207,7 @@ function createProxyHandler(options) {
|
|
|
12197
12207
|
let conn = null;
|
|
12198
12208
|
let cachedInfo = null;
|
|
12199
12209
|
let connecting = null;
|
|
12200
|
-
const
|
|
12210
|
+
const scrub = secretMasker(options.hiddenHeaders, "***");
|
|
12201
12211
|
async function doConnect() {
|
|
12202
12212
|
const c = await connect(options.platform, options.connectOpts);
|
|
12203
12213
|
cachedInfo = await c.info();
|
|
@@ -12226,10 +12236,10 @@ function createProxyHandler(options) {
|
|
|
12226
12236
|
return getConnection();
|
|
12227
12237
|
}
|
|
12228
12238
|
function scrubOk(id, result) {
|
|
12229
|
-
return rpcOk2(id, scrubValue(result,
|
|
12239
|
+
return rpcOk2(id, scrubValue(result, scrub));
|
|
12230
12240
|
}
|
|
12231
12241
|
function scrubErr(id, code2, message) {
|
|
12232
|
-
return rpcError2(id, code2,
|
|
12242
|
+
return rpcError2(id, code2, scrub(message));
|
|
12233
12243
|
}
|
|
12234
12244
|
function handleInitialize(id, params) {
|
|
12235
12245
|
const requested = params && typeof params === "object" ? Object.getOwnPropertyDescriptor(params, "protocolVersion")?.value : void 0;
|
|
@@ -13276,9 +13286,17 @@ async function resolveProxyConfig(platform2, target, connectHeaders, hiddenValue
|
|
|
13276
13286
|
const entry = await config.get(target);
|
|
13277
13287
|
if (!entry) return `unknown target '${target}'`;
|
|
13278
13288
|
if ("url" in entry && entry.url) {
|
|
13279
|
-
const
|
|
13289
|
+
const expanded = expandHeaders(entry.headers, platform2.env, (msg) => {
|
|
13290
|
+
platform2.write(2, `mcpcat serve --proxy: warning: ${msg}
|
|
13291
|
+
`).catch(() => {
|
|
13292
|
+
});
|
|
13293
|
+
});
|
|
13294
|
+
const merged = { ...expanded, ...connectHeaders };
|
|
13280
13295
|
if (entry.headers) {
|
|
13281
|
-
for (const v of Object.values(entry.headers))
|
|
13296
|
+
for (const v of Object.values(entry.headers)) {
|
|
13297
|
+
hiddenValues.add(v);
|
|
13298
|
+
for (const p of placeholderValues(v, platform2.env)) hiddenValues.add(p);
|
|
13299
|
+
}
|
|
13282
13300
|
}
|
|
13283
13301
|
return { url: entry.url, headers: merged, version };
|
|
13284
13302
|
}
|
|
@@ -13303,6 +13321,7 @@ async function buildProxyConnectOpts(platform2, options, version) {
|
|
|
13303
13321
|
const key = k.toLowerCase() === "authorization" ? "Authorization" : k;
|
|
13304
13322
|
connectHeaders[key] = expanded;
|
|
13305
13323
|
hiddenValues.add(expanded);
|
|
13324
|
+
for (const p of placeholderValues(v, platform2.env)) hiddenValues.add(p);
|
|
13306
13325
|
}
|
|
13307
13326
|
const isUrl = target.startsWith("http://") || target.startsWith("https://") || target.includes(".");
|
|
13308
13327
|
let connectOpts;
|
|
@@ -16100,13 +16119,15 @@ async function runVerb(platform2, parsed, conn, onProgress, respondData) {
|
|
|
16100
16119
|
}
|
|
16101
16120
|
}
|
|
16102
16121
|
async function probeServer(_name, config, platform2) {
|
|
16122
|
+
let secrets = [];
|
|
16103
16123
|
try {
|
|
16104
16124
|
const opts = { version: "probe" };
|
|
16105
16125
|
if ("url" in config && config.url) {
|
|
16106
16126
|
opts.url = config.url;
|
|
16107
|
-
if ("headers" in config) {
|
|
16108
|
-
const
|
|
16109
|
-
|
|
16127
|
+
if ("headers" in config && config.headers) {
|
|
16128
|
+
const collected = expandAndCollect(config.headers, platform2.env);
|
|
16129
|
+
secrets = collected.secrets;
|
|
16130
|
+
if (Object.keys(collected.expanded).length > 0) opts.headers = collected.expanded;
|
|
16110
16131
|
}
|
|
16111
16132
|
} else if ("command" in config && config.command) {
|
|
16112
16133
|
opts.command = config.command;
|
|
@@ -16127,7 +16148,7 @@ async function probeServer(_name, config, platform2) {
|
|
|
16127
16148
|
}
|
|
16128
16149
|
return void 0;
|
|
16129
16150
|
} catch (err) {
|
|
16130
|
-
return err.message;
|
|
16151
|
+
return redactSecrets(err.message, secrets);
|
|
16131
16152
|
}
|
|
16132
16153
|
}
|
|
16133
16154
|
async function dispatchConfigVerb(platform2, verb, args2, version) {
|
|
@@ -16588,10 +16609,11 @@ async function handleInputRequired(platform2, conn, err, respondData, json, reda
|
|
|
16588
16609
|
return EXIT_INPUT_REQUIRED;
|
|
16589
16610
|
}
|
|
16590
16611
|
try {
|
|
16591
|
-
const retryResult = await conn.callTool(
|
|
16592
|
-
|
|
16593
|
-
|
|
16594
|
-
|
|
16612
|
+
const retryResult = await conn.callTool(
|
|
16613
|
+
parsed2.name,
|
|
16614
|
+
parsed2.arguments,
|
|
16615
|
+
{ inputResponses: elicitResult.answers }
|
|
16616
|
+
);
|
|
16595
16617
|
return renderCallResult(platform2, retryResult, { json });
|
|
16596
16618
|
} catch (retryErr) {
|
|
16597
16619
|
const e2 = classifyError(retryErr);
|
|
@@ -16743,7 +16765,7 @@ async function runClientVerb(platform2, version, parsed) {
|
|
|
16743
16765
|
return termExitCode;
|
|
16744
16766
|
}
|
|
16745
16767
|
if (err instanceof InputRequiredError) {
|
|
16746
|
-
return handleInputRequired(platform2, conn, err, respondData, parsed.jsonOutput, redact2);
|
|
16768
|
+
return await handleInputRequired(platform2, conn, err, respondData, parsed.jsonOutput, redact2);
|
|
16747
16769
|
}
|
|
16748
16770
|
const e = classifyError(err);
|
|
16749
16771
|
await writeErrRedacted(platform2, parsed.jsonOutput, e.kind, e.msg, redact2);
|
|
@@ -17045,5 +17067,5 @@ try {
|
|
|
17045
17067
|
});
|
|
17046
17068
|
} catch {
|
|
17047
17069
|
}
|
|
17048
|
-
var code = await run(platform, "0.17.
|
|
17070
|
+
var code = await run(platform, "0.17.9", args);
|
|
17049
17071
|
process.exit(code);
|
package/dist/kernel/mcpcat.mjs
CHANGED
|
@@ -10793,11 +10793,30 @@ function redactWrites(platform2, redact2) {
|
|
|
10793
10793
|
write: (fd, data) => platform2.write(fd, typeof data === "string" ? redact2(data) : data)
|
|
10794
10794
|
});
|
|
10795
10795
|
}
|
|
10796
|
+
function secretMasker(secrets, mask) {
|
|
10797
|
+
const ordered = [...new Set(secrets)].filter((s) => s.length > 0);
|
|
10798
|
+
if (ordered.length === 0) return (text) => text;
|
|
10799
|
+
return (text) => {
|
|
10800
|
+
const hidden = new Uint8Array(text.length);
|
|
10801
|
+
for (const secret of ordered) {
|
|
10802
|
+
for (let at = text.indexOf(secret); at >= 0; at = text.indexOf(secret, at + 1)) {
|
|
10803
|
+
hidden.fill(1, at, at + secret.length);
|
|
10804
|
+
}
|
|
10805
|
+
}
|
|
10806
|
+
let out = "";
|
|
10807
|
+
let start = 0;
|
|
10808
|
+
while (start < text.length) {
|
|
10809
|
+
let end = start;
|
|
10810
|
+
const masked = hidden[start] === 1;
|
|
10811
|
+
while (end < text.length && hidden[end] === 1 === masked) end++;
|
|
10812
|
+
out += masked ? mask : text.slice(start, end);
|
|
10813
|
+
start = end;
|
|
10814
|
+
}
|
|
10815
|
+
return out;
|
|
10816
|
+
};
|
|
10817
|
+
}
|
|
10796
10818
|
function redactSecrets(text, secrets) {
|
|
10797
|
-
|
|
10798
|
-
let result = text;
|
|
10799
|
-
for (const secret of ordered) result = result.replaceAll(secret, "[REDACTED]");
|
|
10800
|
-
return result;
|
|
10819
|
+
return secretMasker(secrets, "[REDACTED]")(text);
|
|
10801
10820
|
}
|
|
10802
10821
|
|
|
10803
10822
|
// src/render/result.ts
|
|
@@ -11774,27 +11793,18 @@ function rpcError2(id, code, message) {
|
|
|
11774
11793
|
body: JSON.stringify({ jsonrpc: "2.0", id, error: { code, message } })
|
|
11775
11794
|
};
|
|
11776
11795
|
}
|
|
11777
|
-
function scrubValue(value,
|
|
11778
|
-
if (typeof value === "string") return
|
|
11779
|
-
if (Array.isArray(value)) return value.map((v) => scrubValue(v,
|
|
11796
|
+
function scrubValue(value, scrub) {
|
|
11797
|
+
if (typeof value === "string") return scrub(value);
|
|
11798
|
+
if (Array.isArray(value)) return value.map((v) => scrubValue(v, scrub));
|
|
11780
11799
|
if (value && typeof value === "object") {
|
|
11781
11800
|
const out = {};
|
|
11782
11801
|
for (const [k, v] of Object.entries(value)) {
|
|
11783
|
-
out[k] = scrubValue(v,
|
|
11802
|
+
out[k] = scrubValue(v, scrub);
|
|
11784
11803
|
}
|
|
11785
11804
|
return out;
|
|
11786
11805
|
}
|
|
11787
11806
|
return value;
|
|
11788
11807
|
}
|
|
11789
|
-
function scrubString(s, secrets) {
|
|
11790
|
-
let result = s;
|
|
11791
|
-
for (const h of secrets) {
|
|
11792
|
-
if (result.includes(h)) {
|
|
11793
|
-
result = result.replaceAll(h, "***");
|
|
11794
|
-
}
|
|
11795
|
-
}
|
|
11796
|
-
return result;
|
|
11797
|
-
}
|
|
11798
11808
|
function translateCapabilities(info) {
|
|
11799
11809
|
const caps = {};
|
|
11800
11810
|
if (info.capabilities.tools) caps.tools = { listChanged: false };
|
|
@@ -11818,7 +11828,7 @@ function createProxyHandler(options) {
|
|
|
11818
11828
|
let conn = null;
|
|
11819
11829
|
let cachedInfo = null;
|
|
11820
11830
|
let connecting = null;
|
|
11821
|
-
const
|
|
11831
|
+
const scrub = secretMasker(options.hiddenHeaders, "***");
|
|
11822
11832
|
async function doConnect() {
|
|
11823
11833
|
const c = await connect(options.platform, options.connectOpts);
|
|
11824
11834
|
cachedInfo = await c.info();
|
|
@@ -11847,10 +11857,10 @@ function createProxyHandler(options) {
|
|
|
11847
11857
|
return getConnection();
|
|
11848
11858
|
}
|
|
11849
11859
|
function scrubOk(id, result) {
|
|
11850
|
-
return rpcOk2(id, scrubValue(result,
|
|
11860
|
+
return rpcOk2(id, scrubValue(result, scrub));
|
|
11851
11861
|
}
|
|
11852
11862
|
function scrubErr(id, code, message) {
|
|
11853
|
-
return rpcError2(id, code,
|
|
11863
|
+
return rpcError2(id, code, scrub(message));
|
|
11854
11864
|
}
|
|
11855
11865
|
function handleInitialize(id, params) {
|
|
11856
11866
|
const requested = params && typeof params === "object" ? Object.getOwnPropertyDescriptor(params, "protocolVersion")?.value : void 0;
|
|
@@ -12897,9 +12907,17 @@ async function resolveProxyConfig(platform2, target, connectHeaders, hiddenValue
|
|
|
12897
12907
|
const entry = await config.get(target);
|
|
12898
12908
|
if (!entry) return `unknown target '${target}'`;
|
|
12899
12909
|
if ("url" in entry && entry.url) {
|
|
12900
|
-
const
|
|
12910
|
+
const expanded = expandHeaders(entry.headers, platform2.env, (msg) => {
|
|
12911
|
+
platform2.write(2, `mcpcat serve --proxy: warning: ${msg}
|
|
12912
|
+
`).catch(() => {
|
|
12913
|
+
});
|
|
12914
|
+
});
|
|
12915
|
+
const merged = { ...expanded, ...connectHeaders };
|
|
12901
12916
|
if (entry.headers) {
|
|
12902
|
-
for (const v of Object.values(entry.headers))
|
|
12917
|
+
for (const v of Object.values(entry.headers)) {
|
|
12918
|
+
hiddenValues.add(v);
|
|
12919
|
+
for (const p of placeholderValues(v, platform2.env)) hiddenValues.add(p);
|
|
12920
|
+
}
|
|
12903
12921
|
}
|
|
12904
12922
|
return { url: entry.url, headers: merged, version };
|
|
12905
12923
|
}
|
|
@@ -12924,6 +12942,7 @@ async function buildProxyConnectOpts(platform2, options, version) {
|
|
|
12924
12942
|
const key = k.toLowerCase() === "authorization" ? "Authorization" : k;
|
|
12925
12943
|
connectHeaders[key] = expanded;
|
|
12926
12944
|
hiddenValues.add(expanded);
|
|
12945
|
+
for (const p of placeholderValues(v, platform2.env)) hiddenValues.add(p);
|
|
12927
12946
|
}
|
|
12928
12947
|
const isUrl = target.startsWith("http://") || target.startsWith("https://") || target.includes(".");
|
|
12929
12948
|
let connectOpts;
|
|
@@ -15721,13 +15740,15 @@ async function runVerb(platform2, parsed, conn, onProgress, respondData) {
|
|
|
15721
15740
|
}
|
|
15722
15741
|
}
|
|
15723
15742
|
async function probeServer(_name, config, platform2) {
|
|
15743
|
+
let secrets = [];
|
|
15724
15744
|
try {
|
|
15725
15745
|
const opts = { version: "probe" };
|
|
15726
15746
|
if ("url" in config && config.url) {
|
|
15727
15747
|
opts.url = config.url;
|
|
15728
|
-
if ("headers" in config) {
|
|
15729
|
-
const
|
|
15730
|
-
|
|
15748
|
+
if ("headers" in config && config.headers) {
|
|
15749
|
+
const collected = expandAndCollect(config.headers, platform2.env);
|
|
15750
|
+
secrets = collected.secrets;
|
|
15751
|
+
if (Object.keys(collected.expanded).length > 0) opts.headers = collected.expanded;
|
|
15731
15752
|
}
|
|
15732
15753
|
} else if ("command" in config && config.command) {
|
|
15733
15754
|
opts.command = config.command;
|
|
@@ -15748,7 +15769,7 @@ async function probeServer(_name, config, platform2) {
|
|
|
15748
15769
|
}
|
|
15749
15770
|
return void 0;
|
|
15750
15771
|
} catch (err) {
|
|
15751
|
-
return err.message;
|
|
15772
|
+
return redactSecrets(err.message, secrets);
|
|
15752
15773
|
}
|
|
15753
15774
|
}
|
|
15754
15775
|
async function dispatchConfigVerb(platform2, verb, args, version) {
|
|
@@ -16209,10 +16230,11 @@ async function handleInputRequired(platform2, conn, err, respondData, json, reda
|
|
|
16209
16230
|
return EXIT_INPUT_REQUIRED;
|
|
16210
16231
|
}
|
|
16211
16232
|
try {
|
|
16212
|
-
const retryResult = await conn.callTool(
|
|
16213
|
-
|
|
16214
|
-
|
|
16215
|
-
|
|
16233
|
+
const retryResult = await conn.callTool(
|
|
16234
|
+
parsed2.name,
|
|
16235
|
+
parsed2.arguments,
|
|
16236
|
+
{ inputResponses: elicitResult.answers }
|
|
16237
|
+
);
|
|
16216
16238
|
return renderCallResult(platform2, retryResult, { json });
|
|
16217
16239
|
} catch (retryErr) {
|
|
16218
16240
|
const e2 = classifyError(retryErr);
|
|
@@ -16364,7 +16386,7 @@ async function runClientVerb(platform2, version, parsed) {
|
|
|
16364
16386
|
return termExitCode;
|
|
16365
16387
|
}
|
|
16366
16388
|
if (err instanceof InputRequiredError) {
|
|
16367
|
-
return handleInputRequired(platform2, conn, err, respondData, parsed.jsonOutput, redact2);
|
|
16389
|
+
return await handleInputRequired(platform2, conn, err, respondData, parsed.jsonOutput, redact2);
|
|
16368
16390
|
}
|
|
16369
16391
|
const e = classifyError(err);
|
|
16370
16392
|
await writeErrRedacted(platform2, parsed.jsonOutput, e.kind, e.msg, redact2);
|
|
@@ -16767,7 +16789,7 @@ async function main(ctx) {
|
|
|
16767
16789
|
packageDir: "/node_modules/@ai-ecoverse/mcpcat"
|
|
16768
16790
|
});
|
|
16769
16791
|
const args = ctx.argv.slice(1);
|
|
16770
|
-
return run(platform2, "0.17.
|
|
16792
|
+
return run(platform2, "0.17.9", args);
|
|
16771
16793
|
}
|
|
16772
16794
|
export {
|
|
16773
16795
|
main as default
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-ecoverse/mcpcat",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.9",
|
|
4
4
|
"description": "A curl for the Model Context Protocol",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -61,15 +61,15 @@
|
|
|
61
61
|
"trust:dry": "npx fledgling sync --dry-run -y --skip-publish"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@ai-ecoverse/slicc-bios": "1.
|
|
65
|
-
"@ai-ecoverse/slicc-kernel": "1.
|
|
66
|
-
"@ai-ecoverse/slicc-shared-web": "1.29.
|
|
64
|
+
"@ai-ecoverse/slicc-bios": "1.37.3",
|
|
65
|
+
"@ai-ecoverse/slicc-kernel": "1.142.1",
|
|
66
|
+
"@ai-ecoverse/slicc-shared-web": "1.29.11",
|
|
67
67
|
"@biomejs/biome": "2.5.15",
|
|
68
68
|
"@earendil-works/pi-codemode": "1.2.0",
|
|
69
69
|
"@earendil-works/pi-mcp": "1.2.0",
|
|
70
70
|
"@types/node": "26.6.5",
|
|
71
71
|
"esbuild": "0.28.2",
|
|
72
|
-
"kernel-cert-new": "npm:@ai-ecoverse/slicc-kernel@1.
|
|
72
|
+
"kernel-cert-new": "npm:@ai-ecoverse/slicc-kernel@1.142.1",
|
|
73
73
|
"lefthook": "2.2.2",
|
|
74
74
|
"monocart-coverage-reports": "2.13.2",
|
|
75
75
|
"proper-lockfile": "4.1.2",
|