@ai-ecoverse/mcpcat 0.31.10 → 0.31.11
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 +134 -86
- package/dist/kernel/mcpcat.mjs +134 -86
- package/package.json +1 -1
package/dist/host/mcpcat.mjs
CHANGED
|
@@ -10007,6 +10007,67 @@ function configToTarget(entry) {
|
|
|
10007
10007
|
throw new Error("config entry has neither url nor command");
|
|
10008
10008
|
}
|
|
10009
10009
|
|
|
10010
|
+
// src/render/redact.ts
|
|
10011
|
+
var ENCODING_DEPTH = 3;
|
|
10012
|
+
var NON_ASCII = /[\u007f-\uffff]/g;
|
|
10013
|
+
function jsonForms(text) {
|
|
10014
|
+
const json = JSON.stringify(text).slice(1, -1);
|
|
10015
|
+
const ascii = json.replace(
|
|
10016
|
+
NON_ASCII,
|
|
10017
|
+
(c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`
|
|
10018
|
+
);
|
|
10019
|
+
return [json, sanitizeJson(json), ascii].flatMap((form) => [form, form.replaceAll("/", "\\/")]);
|
|
10020
|
+
}
|
|
10021
|
+
function encodedForms(secret) {
|
|
10022
|
+
const forms = /* @__PURE__ */ new Set([secret, sanitizeTerminal(secret)]);
|
|
10023
|
+
let level = [secret];
|
|
10024
|
+
for (let depth = 0; depth < ENCODING_DEPTH; depth++) {
|
|
10025
|
+
level = [...new Set(level.flatMap(jsonForms))];
|
|
10026
|
+
for (const form of level) forms.add(form);
|
|
10027
|
+
}
|
|
10028
|
+
return [...forms];
|
|
10029
|
+
}
|
|
10030
|
+
function redactDeep(value, redact2) {
|
|
10031
|
+
if (typeof value === "string") return redact2(value);
|
|
10032
|
+
if (Array.isArray(value)) return value.map((v) => redactDeep(v, redact2));
|
|
10033
|
+
if (value && typeof value === "object") {
|
|
10034
|
+
return Object.fromEntries(
|
|
10035
|
+
Object.entries(value).map(([k, v]) => [redact2(k), redactDeep(v, redact2)])
|
|
10036
|
+
);
|
|
10037
|
+
}
|
|
10038
|
+
return value;
|
|
10039
|
+
}
|
|
10040
|
+
function redactWrites(platform2, redact2) {
|
|
10041
|
+
return Object.assign(Object.create(platform2), {
|
|
10042
|
+
write: (fd, data) => platform2.write(fd, typeof data === "string" ? redact2(data) : data)
|
|
10043
|
+
});
|
|
10044
|
+
}
|
|
10045
|
+
function secretMasker(secrets, mask) {
|
|
10046
|
+
const ordered = [...new Set(secrets)].filter((s) => s.length > 0).flatMap(encodedForms);
|
|
10047
|
+
if (ordered.length === 0) return (text) => text;
|
|
10048
|
+
return (text) => {
|
|
10049
|
+
const hidden = new Uint8Array(text.length);
|
|
10050
|
+
for (const secret of ordered) {
|
|
10051
|
+
for (let at = text.indexOf(secret); at >= 0; at = text.indexOf(secret, at + 1)) {
|
|
10052
|
+
hidden.fill(1, at, at + secret.length);
|
|
10053
|
+
}
|
|
10054
|
+
}
|
|
10055
|
+
let out = "";
|
|
10056
|
+
let start = 0;
|
|
10057
|
+
while (start < text.length) {
|
|
10058
|
+
let end = start;
|
|
10059
|
+
const masked = hidden[start] === 1;
|
|
10060
|
+
while (end < text.length && hidden[end] === 1 === masked) end++;
|
|
10061
|
+
out += masked ? mask : text.slice(start, end);
|
|
10062
|
+
start = end;
|
|
10063
|
+
}
|
|
10064
|
+
return out;
|
|
10065
|
+
};
|
|
10066
|
+
}
|
|
10067
|
+
function redactSecrets(text, secrets) {
|
|
10068
|
+
return secretMasker(secrets, "[REDACTED]")(text);
|
|
10069
|
+
}
|
|
10070
|
+
|
|
10010
10071
|
// src/codemode/search.ts
|
|
10011
10072
|
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
10012
10073
|
"a",
|
|
@@ -10087,7 +10148,7 @@ function toolDeclaration(tool) {
|
|
|
10087
10148
|
outputSchema: outputSchema ?? { type: "string" }
|
|
10088
10149
|
};
|
|
10089
10150
|
}
|
|
10090
|
-
async function runDescribeTs(platform2, targets, budget) {
|
|
10151
|
+
async function runDescribeTs(platform2, targets, budget, redact2 = (text) => text) {
|
|
10091
10152
|
const { renderDeclarations: renderDeclarations2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports2));
|
|
10092
10153
|
const allTools = [];
|
|
10093
10154
|
for (const target of targets) {
|
|
@@ -10105,7 +10166,7 @@ async function runDescribeTs(platform2, targets, budget) {
|
|
|
10105
10166
|
return 0;
|
|
10106
10167
|
}
|
|
10107
10168
|
const output = renderDeclarations2({
|
|
10108
|
-
tools: allTools
|
|
10169
|
+
tools: redactDeep(allTools, redact2)
|
|
10109
10170
|
});
|
|
10110
10171
|
await platform2.write(1, `${output}
|
|
10111
10172
|
`);
|
|
@@ -10400,7 +10461,8 @@ async function runCode(targets, source, options) {
|
|
|
10400
10461
|
await saveStore(platform2, stateDir2, store, writes);
|
|
10401
10462
|
}
|
|
10402
10463
|
}
|
|
10403
|
-
|
|
10464
|
+
const shown = options.redact ? redactDeep(result, options.redact) : result;
|
|
10465
|
+
return await formatOutput(platform2, shown, json);
|
|
10404
10466
|
} finally {
|
|
10405
10467
|
await sandbox.close();
|
|
10406
10468
|
}
|
|
@@ -12003,48 +12065,6 @@ async function runDiscover(platform2, args2) {
|
|
|
12003
12065
|
return 0;
|
|
12004
12066
|
}
|
|
12005
12067
|
|
|
12006
|
-
// src/render/redact.ts
|
|
12007
|
-
function redactDeep(value, redact2) {
|
|
12008
|
-
if (typeof value === "string") return redact2(value);
|
|
12009
|
-
if (Array.isArray(value)) return value.map((v) => redactDeep(v, redact2));
|
|
12010
|
-
if (value && typeof value === "object") {
|
|
12011
|
-
return Object.fromEntries(
|
|
12012
|
-
Object.entries(value).map(([k, v]) => [redact2(k), redactDeep(v, redact2)])
|
|
12013
|
-
);
|
|
12014
|
-
}
|
|
12015
|
-
return value;
|
|
12016
|
-
}
|
|
12017
|
-
function redactWrites(platform2, redact2) {
|
|
12018
|
-
return Object.assign(Object.create(platform2), {
|
|
12019
|
-
write: (fd, data) => platform2.write(fd, typeof data === "string" ? redact2(data) : data)
|
|
12020
|
-
});
|
|
12021
|
-
}
|
|
12022
|
-
function secretMasker(secrets, mask) {
|
|
12023
|
-
const ordered = [...new Set(secrets)].filter((s) => s.length > 0);
|
|
12024
|
-
if (ordered.length === 0) return (text) => text;
|
|
12025
|
-
return (text) => {
|
|
12026
|
-
const hidden = new Uint8Array(text.length);
|
|
12027
|
-
for (const secret of ordered) {
|
|
12028
|
-
for (let at = text.indexOf(secret); at >= 0; at = text.indexOf(secret, at + 1)) {
|
|
12029
|
-
hidden.fill(1, at, at + secret.length);
|
|
12030
|
-
}
|
|
12031
|
-
}
|
|
12032
|
-
let out = "";
|
|
12033
|
-
let start = 0;
|
|
12034
|
-
while (start < text.length) {
|
|
12035
|
-
let end = start;
|
|
12036
|
-
const masked = hidden[start] === 1;
|
|
12037
|
-
while (end < text.length && hidden[end] === 1 === masked) end++;
|
|
12038
|
-
out += masked ? mask : text.slice(start, end);
|
|
12039
|
-
start = end;
|
|
12040
|
-
}
|
|
12041
|
-
return out;
|
|
12042
|
-
};
|
|
12043
|
-
}
|
|
12044
|
-
function redactSecrets(text, secrets) {
|
|
12045
|
-
return secretMasker(secrets, "[REDACTED]")(text);
|
|
12046
|
-
}
|
|
12047
|
-
|
|
12048
12068
|
// src/render/result.ts
|
|
12049
12069
|
function formatBytes(n) {
|
|
12050
12070
|
if (n < 1024) return `${n} bytes`;
|
|
@@ -20704,12 +20724,9 @@ async function dispatchServeVerb(platform2, args2, version, features) {
|
|
|
20704
20724
|
}
|
|
20705
20725
|
return runServe(platform2, serveOptions, version);
|
|
20706
20726
|
}
|
|
20707
|
-
async function connectTargets(platform2, names, config, parsed, version) {
|
|
20727
|
+
async function connectTargets(platform2, names, config, parsed, version, hidden, redact2) {
|
|
20708
20728
|
const conns = [];
|
|
20709
20729
|
const targets = [];
|
|
20710
|
-
const warn = (msg) => void platform2.write(2, `mcpcat: warning: ${msg}
|
|
20711
|
-
`).catch(() => {
|
|
20712
|
-
});
|
|
20713
20730
|
for (const name of names) {
|
|
20714
20731
|
let resolved;
|
|
20715
20732
|
try {
|
|
@@ -20721,9 +20738,11 @@ async function connectTargets(platform2, names, config, parsed, version) {
|
|
|
20721
20738
|
}
|
|
20722
20739
|
try {
|
|
20723
20740
|
const merged = { ...resolved.headers, ...parsed.headers };
|
|
20741
|
+
const { headers, secrets } = expandConfigHeaders(platform2, merged);
|
|
20742
|
+
for (const s of secrets) hidden.add(s);
|
|
20724
20743
|
const conn = await connect(platform2, {
|
|
20725
20744
|
...resolved,
|
|
20726
|
-
headers
|
|
20745
|
+
headers,
|
|
20727
20746
|
authProvider: await placeholderAuthProvider({
|
|
20728
20747
|
platform: platform2,
|
|
20729
20748
|
name: config.entry(name) ? name : void 0,
|
|
@@ -20732,16 +20751,19 @@ async function connectTargets(platform2, names, config, parsed, version) {
|
|
|
20732
20751
|
timeoutMs: parsed.timeoutMs
|
|
20733
20752
|
}),
|
|
20734
20753
|
protocolVersion: parsed.protocolVersion,
|
|
20735
|
-
version
|
|
20754
|
+
version,
|
|
20755
|
+
redact: redact2
|
|
20736
20756
|
});
|
|
20737
20757
|
conns.push(conn);
|
|
20738
20758
|
const info = await conn.info();
|
|
20739
20759
|
targets.push({ name, conn, instructions: info.instructions });
|
|
20740
20760
|
} catch (err) {
|
|
20741
|
-
await
|
|
20742
|
-
|
|
20743
|
-
|
|
20744
|
-
|
|
20761
|
+
await writeErrRedacted(
|
|
20762
|
+
platform2,
|
|
20763
|
+
false,
|
|
20764
|
+
"connection",
|
|
20765
|
+
`connection to ${name} failed: ${err.message}`,
|
|
20766
|
+
redact2
|
|
20745
20767
|
);
|
|
20746
20768
|
}
|
|
20747
20769
|
}
|
|
@@ -20764,10 +20786,19 @@ async function resolveTargetNames(platform2, parsed) {
|
|
|
20764
20786
|
const positionalExtra = parsed.toolName;
|
|
20765
20787
|
if (positionalExtra && parsed.verb !== "call") targets.push(positionalExtra);
|
|
20766
20788
|
if (targets.length > 0) return targets;
|
|
20767
|
-
|
|
20789
|
+
return enabledNames(await MergedConfigSource.load(platform2));
|
|
20790
|
+
}
|
|
20791
|
+
function enabledNames(config) {
|
|
20768
20792
|
return config.list().filter((e) => e.config.enabled !== false).map((e) => e.name);
|
|
20769
20793
|
}
|
|
20770
20794
|
async function dispatchMultiTarget(platform2, parsed, version) {
|
|
20795
|
+
const { secrets, unset } = expandAndCollect(parsed.headers, platform2.env, parsed.extra);
|
|
20796
|
+
if (unset.length > 0 && !isKernel(platform2)) return refuseUnsetHeaders(platform2, unset);
|
|
20797
|
+
const hidden = new Set(secrets);
|
|
20798
|
+
const redact2 = (text) => redactSecrets(text, hidden);
|
|
20799
|
+
return runMultiTarget(redactWrites(platform2, redact2), parsed, version, hidden, redact2);
|
|
20800
|
+
}
|
|
20801
|
+
async function runMultiTarget(platform2, parsed, version, hidden, redact2) {
|
|
20771
20802
|
let activeCleanup;
|
|
20772
20803
|
async function killTreeAndExit(exitCode) {
|
|
20773
20804
|
if (activeCleanup) {
|
|
@@ -20806,18 +20837,15 @@ async function dispatchMultiTarget(platform2, parsed, version) {
|
|
|
20806
20837
|
await platform2.write(2, "mcpcat: code requires -e <source> or a file\n");
|
|
20807
20838
|
return 2;
|
|
20808
20839
|
}
|
|
20809
|
-
|
|
20810
|
-
if (parsed.serverTargets.length > 0) {
|
|
20811
|
-
serverNames = parsed.serverTargets;
|
|
20812
|
-
} else {
|
|
20813
|
-
serverNames = config.list().filter((e) => e.config.enabled !== false).map((e) => e.name);
|
|
20814
|
-
}
|
|
20840
|
+
const serverNames = parsed.serverTargets.length > 0 ? parsed.serverTargets : enabledNames(config);
|
|
20815
20841
|
const { targets, cleanup } = await connectTargets(
|
|
20816
20842
|
platform2,
|
|
20817
20843
|
serverNames,
|
|
20818
20844
|
config,
|
|
20819
20845
|
parsed,
|
|
20820
|
-
version
|
|
20846
|
+
version,
|
|
20847
|
+
hidden,
|
|
20848
|
+
redact2
|
|
20821
20849
|
);
|
|
20822
20850
|
activeCleanup = cleanup;
|
|
20823
20851
|
try {
|
|
@@ -20826,7 +20854,8 @@ async function dispatchMultiTarget(platform2, parsed, version) {
|
|
|
20826
20854
|
timeoutMs: parsed.timeoutMs,
|
|
20827
20855
|
memoryLimitMiB: parsed.memoryLimitMiB,
|
|
20828
20856
|
allowShell: parsed.allowShell,
|
|
20829
|
-
platform: platform2
|
|
20857
|
+
platform: platform2,
|
|
20858
|
+
redact: redact2
|
|
20830
20859
|
});
|
|
20831
20860
|
} catch (err) {
|
|
20832
20861
|
await platform2.write(2, `mcpcat: ${err.message}
|
|
@@ -20844,13 +20873,15 @@ async function dispatchMultiTarget(platform2, parsed, version) {
|
|
|
20844
20873
|
await platform2.write(2, "mcpcat: grep requires a pattern\n");
|
|
20845
20874
|
return 2;
|
|
20846
20875
|
}
|
|
20847
|
-
const serverNames = parsed.toolName ? [parsed.toolName] :
|
|
20876
|
+
const serverNames = parsed.toolName ? [parsed.toolName] : enabledNames(config);
|
|
20848
20877
|
const { targets, cleanup } = await connectTargets(
|
|
20849
20878
|
platform2,
|
|
20850
20879
|
serverNames,
|
|
20851
20880
|
config,
|
|
20852
20881
|
parsed,
|
|
20853
|
-
version
|
|
20882
|
+
version,
|
|
20883
|
+
hidden,
|
|
20884
|
+
redact2
|
|
20854
20885
|
);
|
|
20855
20886
|
activeCleanup = cleanup;
|
|
20856
20887
|
try {
|
|
@@ -20858,6 +20889,8 @@ async function dispatchMultiTarget(platform2, parsed, version) {
|
|
|
20858
20889
|
rank: parsed.rank,
|
|
20859
20890
|
extended: parsed.extendedRegex
|
|
20860
20891
|
});
|
|
20892
|
+
} catch (err) {
|
|
20893
|
+
return await reportError(platform2, parsed.jsonOutput, err, redact2);
|
|
20861
20894
|
} finally {
|
|
20862
20895
|
await cleanup();
|
|
20863
20896
|
await killAllStdio().catch(() => {
|
|
@@ -20871,11 +20904,15 @@ async function dispatchMultiTarget(platform2, parsed, version) {
|
|
|
20871
20904
|
serverNames,
|
|
20872
20905
|
config,
|
|
20873
20906
|
parsed,
|
|
20874
|
-
version
|
|
20907
|
+
version,
|
|
20908
|
+
hidden,
|
|
20909
|
+
redact2
|
|
20875
20910
|
);
|
|
20876
20911
|
activeCleanup = cleanup;
|
|
20877
20912
|
try {
|
|
20878
|
-
return await runDescribeTs(platform2, targets, parsed.tsBudget);
|
|
20913
|
+
return await runDescribeTs(platform2, targets, parsed.tsBudget, redact2);
|
|
20914
|
+
} catch (err) {
|
|
20915
|
+
return await reportError(platform2, parsed.jsonOutput, err, redact2);
|
|
20879
20916
|
} finally {
|
|
20880
20917
|
await cleanup();
|
|
20881
20918
|
await killAllStdio().catch(() => {
|
|
@@ -21312,14 +21349,7 @@ async function handleInputRequired(platform2, conn, err, respondData, json, reda
|
|
|
21312
21349
|
}
|
|
21313
21350
|
async function runClientVerb(platform2, version, parsed) {
|
|
21314
21351
|
const { expanded, secrets, unset } = expandAndCollect(parsed.headers, platform2.env, parsed.extra);
|
|
21315
|
-
if (unset.length > 0)
|
|
21316
|
-
await platform2.write(
|
|
21317
|
-
2,
|
|
21318
|
-
`mcpcat: unset variable${unset.length > 1 ? "s" : ""} in -H: ${unset.join(", ")}
|
|
21319
|
-
`
|
|
21320
|
-
);
|
|
21321
|
-
return EXIT_USAGE;
|
|
21322
|
-
}
|
|
21352
|
+
if (unset.length > 0) return refuseUnsetHeaders(platform2, unset);
|
|
21323
21353
|
const verbose = createVerboseLogger(platform2, parsed.verbose);
|
|
21324
21354
|
for (const s of secrets) verbose.secrets.add(s);
|
|
21325
21355
|
const timeoutMs = parsed.timeoutMs;
|
|
@@ -21371,12 +21401,10 @@ async function runClientVerb(platform2, version, parsed) {
|
|
|
21371
21401
|
await writeErr(platform2, parsed.jsonOutput, "usage", err.message);
|
|
21372
21402
|
return EXIT_USAGE;
|
|
21373
21403
|
}
|
|
21374
|
-
const
|
|
21375
|
-
platform2
|
|
21376
|
-
|
|
21377
|
-
|
|
21378
|
-
});
|
|
21379
|
-
const configSecrets = collectConfigSecrets(resolved.headers, platform2.env);
|
|
21404
|
+
const { headers: configHeaders, secrets: configSecrets } = expandConfigHeaders(
|
|
21405
|
+
platform2,
|
|
21406
|
+
resolved.headers
|
|
21407
|
+
);
|
|
21380
21408
|
for (const s of configSecrets) verbose.secrets.add(s);
|
|
21381
21409
|
const allSecrets = /* @__PURE__ */ new Set([...secrets, ...configSecrets]);
|
|
21382
21410
|
const redact2 = (text) => redactSecrets(text, allSecrets);
|
|
@@ -21476,9 +21504,7 @@ async function runClientVerb(platform2, version, parsed) {
|
|
|
21476
21504
|
`);
|
|
21477
21505
|
return EXIT_INPUT_REQUIRED;
|
|
21478
21506
|
}
|
|
21479
|
-
|
|
21480
|
-
await writeErrRedacted(platform2, parsed.jsonOutput, e.kind, e.msg, redact2);
|
|
21481
|
-
return e.code;
|
|
21507
|
+
return await reportError(platform2, parsed.jsonOutput, err, redact2);
|
|
21482
21508
|
} finally {
|
|
21483
21509
|
await closeAndKillStdio(conn);
|
|
21484
21510
|
}
|
|
@@ -21505,6 +21531,28 @@ async function writeErrRedacted(p, json, kind, msg, redact2) {
|
|
|
21505
21531
|
else await p.write(2, sanitizeTerminal(`mcpcat: ${redact2(msg)}
|
|
21506
21532
|
`));
|
|
21507
21533
|
}
|
|
21534
|
+
async function reportError(platform2, json, err, redact2) {
|
|
21535
|
+
const e = classifyError(err);
|
|
21536
|
+
await writeErrRedacted(platform2, json, e.kind, e.msg, redact2);
|
|
21537
|
+
return e.code;
|
|
21538
|
+
}
|
|
21539
|
+
async function refuseUnsetHeaders(platform2, unset) {
|
|
21540
|
+
await platform2.write(
|
|
21541
|
+
2,
|
|
21542
|
+
`mcpcat: unset variable${unset.length > 1 ? "s" : ""} in -H: ${unset.join(", ")}
|
|
21543
|
+
`
|
|
21544
|
+
);
|
|
21545
|
+
return EXIT_USAGE;
|
|
21546
|
+
}
|
|
21547
|
+
function expandConfigHeaders(platform2, headers) {
|
|
21548
|
+
const warn = (msg) => void platform2.write(2, `mcpcat: warning: ${msg}
|
|
21549
|
+
`).catch(() => {
|
|
21550
|
+
});
|
|
21551
|
+
return {
|
|
21552
|
+
headers: expandHeaders(headers, platform2.env, warn),
|
|
21553
|
+
secrets: collectConfigSecrets(headers, platform2.env)
|
|
21554
|
+
};
|
|
21555
|
+
}
|
|
21508
21556
|
function collectConfigSecrets(headers, env) {
|
|
21509
21557
|
if (!headers) return [];
|
|
21510
21558
|
const secrets = [];
|
|
@@ -22168,5 +22216,5 @@ try {
|
|
|
22168
22216
|
});
|
|
22169
22217
|
} catch {
|
|
22170
22218
|
}
|
|
22171
|
-
var code = await run(platform, "0.31.
|
|
22219
|
+
var code = await run(platform, "0.31.11", args);
|
|
22172
22220
|
process.exit(code);
|
package/dist/kernel/mcpcat.mjs
CHANGED
|
@@ -9628,6 +9628,67 @@ function configToTarget(entry) {
|
|
|
9628
9628
|
throw new Error("config entry has neither url nor command");
|
|
9629
9629
|
}
|
|
9630
9630
|
|
|
9631
|
+
// src/render/redact.ts
|
|
9632
|
+
var ENCODING_DEPTH = 3;
|
|
9633
|
+
var NON_ASCII = /[\u007f-\uffff]/g;
|
|
9634
|
+
function jsonForms(text) {
|
|
9635
|
+
const json = JSON.stringify(text).slice(1, -1);
|
|
9636
|
+
const ascii = json.replace(
|
|
9637
|
+
NON_ASCII,
|
|
9638
|
+
(c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, "0")}`
|
|
9639
|
+
);
|
|
9640
|
+
return [json, sanitizeJson(json), ascii].flatMap((form) => [form, form.replaceAll("/", "\\/")]);
|
|
9641
|
+
}
|
|
9642
|
+
function encodedForms(secret) {
|
|
9643
|
+
const forms = /* @__PURE__ */ new Set([secret, sanitizeTerminal(secret)]);
|
|
9644
|
+
let level = [secret];
|
|
9645
|
+
for (let depth = 0; depth < ENCODING_DEPTH; depth++) {
|
|
9646
|
+
level = [...new Set(level.flatMap(jsonForms))];
|
|
9647
|
+
for (const form of level) forms.add(form);
|
|
9648
|
+
}
|
|
9649
|
+
return [...forms];
|
|
9650
|
+
}
|
|
9651
|
+
function redactDeep(value, redact2) {
|
|
9652
|
+
if (typeof value === "string") return redact2(value);
|
|
9653
|
+
if (Array.isArray(value)) return value.map((v) => redactDeep(v, redact2));
|
|
9654
|
+
if (value && typeof value === "object") {
|
|
9655
|
+
return Object.fromEntries(
|
|
9656
|
+
Object.entries(value).map(([k, v]) => [redact2(k), redactDeep(v, redact2)])
|
|
9657
|
+
);
|
|
9658
|
+
}
|
|
9659
|
+
return value;
|
|
9660
|
+
}
|
|
9661
|
+
function redactWrites(platform2, redact2) {
|
|
9662
|
+
return Object.assign(Object.create(platform2), {
|
|
9663
|
+
write: (fd, data) => platform2.write(fd, typeof data === "string" ? redact2(data) : data)
|
|
9664
|
+
});
|
|
9665
|
+
}
|
|
9666
|
+
function secretMasker(secrets, mask) {
|
|
9667
|
+
const ordered = [...new Set(secrets)].filter((s) => s.length > 0).flatMap(encodedForms);
|
|
9668
|
+
if (ordered.length === 0) return (text) => text;
|
|
9669
|
+
return (text) => {
|
|
9670
|
+
const hidden = new Uint8Array(text.length);
|
|
9671
|
+
for (const secret of ordered) {
|
|
9672
|
+
for (let at = text.indexOf(secret); at >= 0; at = text.indexOf(secret, at + 1)) {
|
|
9673
|
+
hidden.fill(1, at, at + secret.length);
|
|
9674
|
+
}
|
|
9675
|
+
}
|
|
9676
|
+
let out = "";
|
|
9677
|
+
let start = 0;
|
|
9678
|
+
while (start < text.length) {
|
|
9679
|
+
let end = start;
|
|
9680
|
+
const masked = hidden[start] === 1;
|
|
9681
|
+
while (end < text.length && hidden[end] === 1 === masked) end++;
|
|
9682
|
+
out += masked ? mask : text.slice(start, end);
|
|
9683
|
+
start = end;
|
|
9684
|
+
}
|
|
9685
|
+
return out;
|
|
9686
|
+
};
|
|
9687
|
+
}
|
|
9688
|
+
function redactSecrets(text, secrets) {
|
|
9689
|
+
return secretMasker(secrets, "[REDACTED]")(text);
|
|
9690
|
+
}
|
|
9691
|
+
|
|
9631
9692
|
// src/codemode/search.ts
|
|
9632
9693
|
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
9633
9694
|
"a",
|
|
@@ -9708,7 +9769,7 @@ function toolDeclaration(tool) {
|
|
|
9708
9769
|
outputSchema: outputSchema ?? { type: "string" }
|
|
9709
9770
|
};
|
|
9710
9771
|
}
|
|
9711
|
-
async function runDescribeTs(platform2, targets, budget) {
|
|
9772
|
+
async function runDescribeTs(platform2, targets, budget, redact2 = (text) => text) {
|
|
9712
9773
|
const { renderDeclarations: renderDeclarations2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports2));
|
|
9713
9774
|
const allTools = [];
|
|
9714
9775
|
for (const target of targets) {
|
|
@@ -9726,7 +9787,7 @@ async function runDescribeTs(platform2, targets, budget) {
|
|
|
9726
9787
|
return 0;
|
|
9727
9788
|
}
|
|
9728
9789
|
const output = renderDeclarations2({
|
|
9729
|
-
tools: allTools
|
|
9790
|
+
tools: redactDeep(allTools, redact2)
|
|
9730
9791
|
});
|
|
9731
9792
|
await platform2.write(1, `${output}
|
|
9732
9793
|
`);
|
|
@@ -10021,7 +10082,8 @@ async function runCode(targets, source, options) {
|
|
|
10021
10082
|
await saveStore(platform2, stateDir2, store, writes);
|
|
10022
10083
|
}
|
|
10023
10084
|
}
|
|
10024
|
-
|
|
10085
|
+
const shown = options.redact ? redactDeep(result, options.redact) : result;
|
|
10086
|
+
return await formatOutput(platform2, shown, json);
|
|
10025
10087
|
} finally {
|
|
10026
10088
|
await sandbox.close();
|
|
10027
10089
|
}
|
|
@@ -11624,48 +11686,6 @@ async function runDiscover(platform2, args) {
|
|
|
11624
11686
|
return 0;
|
|
11625
11687
|
}
|
|
11626
11688
|
|
|
11627
|
-
// src/render/redact.ts
|
|
11628
|
-
function redactDeep(value, redact2) {
|
|
11629
|
-
if (typeof value === "string") return redact2(value);
|
|
11630
|
-
if (Array.isArray(value)) return value.map((v) => redactDeep(v, redact2));
|
|
11631
|
-
if (value && typeof value === "object") {
|
|
11632
|
-
return Object.fromEntries(
|
|
11633
|
-
Object.entries(value).map(([k, v]) => [redact2(k), redactDeep(v, redact2)])
|
|
11634
|
-
);
|
|
11635
|
-
}
|
|
11636
|
-
return value;
|
|
11637
|
-
}
|
|
11638
|
-
function redactWrites(platform2, redact2) {
|
|
11639
|
-
return Object.assign(Object.create(platform2), {
|
|
11640
|
-
write: (fd, data) => platform2.write(fd, typeof data === "string" ? redact2(data) : data)
|
|
11641
|
-
});
|
|
11642
|
-
}
|
|
11643
|
-
function secretMasker(secrets, mask) {
|
|
11644
|
-
const ordered = [...new Set(secrets)].filter((s) => s.length > 0);
|
|
11645
|
-
if (ordered.length === 0) return (text) => text;
|
|
11646
|
-
return (text) => {
|
|
11647
|
-
const hidden = new Uint8Array(text.length);
|
|
11648
|
-
for (const secret of ordered) {
|
|
11649
|
-
for (let at = text.indexOf(secret); at >= 0; at = text.indexOf(secret, at + 1)) {
|
|
11650
|
-
hidden.fill(1, at, at + secret.length);
|
|
11651
|
-
}
|
|
11652
|
-
}
|
|
11653
|
-
let out = "";
|
|
11654
|
-
let start = 0;
|
|
11655
|
-
while (start < text.length) {
|
|
11656
|
-
let end = start;
|
|
11657
|
-
const masked = hidden[start] === 1;
|
|
11658
|
-
while (end < text.length && hidden[end] === 1 === masked) end++;
|
|
11659
|
-
out += masked ? mask : text.slice(start, end);
|
|
11660
|
-
start = end;
|
|
11661
|
-
}
|
|
11662
|
-
return out;
|
|
11663
|
-
};
|
|
11664
|
-
}
|
|
11665
|
-
function redactSecrets(text, secrets) {
|
|
11666
|
-
return secretMasker(secrets, "[REDACTED]")(text);
|
|
11667
|
-
}
|
|
11668
|
-
|
|
11669
11689
|
// src/render/result.ts
|
|
11670
11690
|
function formatBytes(n) {
|
|
11671
11691
|
if (n < 1024) return `${n} bytes`;
|
|
@@ -20221,12 +20241,9 @@ async function dispatchServeVerb(platform2, args, version, features) {
|
|
|
20221
20241
|
}
|
|
20222
20242
|
return runServe(platform2, serveOptions, version);
|
|
20223
20243
|
}
|
|
20224
|
-
async function connectTargets(platform2, names, config, parsed, version) {
|
|
20244
|
+
async function connectTargets(platform2, names, config, parsed, version, hidden, redact2) {
|
|
20225
20245
|
const conns = [];
|
|
20226
20246
|
const targets = [];
|
|
20227
|
-
const warn = (msg) => void platform2.write(2, `mcpcat: warning: ${msg}
|
|
20228
|
-
`).catch(() => {
|
|
20229
|
-
});
|
|
20230
20247
|
for (const name of names) {
|
|
20231
20248
|
let resolved;
|
|
20232
20249
|
try {
|
|
@@ -20238,9 +20255,11 @@ async function connectTargets(platform2, names, config, parsed, version) {
|
|
|
20238
20255
|
}
|
|
20239
20256
|
try {
|
|
20240
20257
|
const merged = { ...resolved.headers, ...parsed.headers };
|
|
20258
|
+
const { headers, secrets } = expandConfigHeaders(platform2, merged);
|
|
20259
|
+
for (const s of secrets) hidden.add(s);
|
|
20241
20260
|
const conn = await connect(platform2, {
|
|
20242
20261
|
...resolved,
|
|
20243
|
-
headers
|
|
20262
|
+
headers,
|
|
20244
20263
|
authProvider: await placeholderAuthProvider({
|
|
20245
20264
|
platform: platform2,
|
|
20246
20265
|
name: config.entry(name) ? name : void 0,
|
|
@@ -20249,16 +20268,19 @@ async function connectTargets(platform2, names, config, parsed, version) {
|
|
|
20249
20268
|
timeoutMs: parsed.timeoutMs
|
|
20250
20269
|
}),
|
|
20251
20270
|
protocolVersion: parsed.protocolVersion,
|
|
20252
|
-
version
|
|
20271
|
+
version,
|
|
20272
|
+
redact: redact2
|
|
20253
20273
|
});
|
|
20254
20274
|
conns.push(conn);
|
|
20255
20275
|
const info = await conn.info();
|
|
20256
20276
|
targets.push({ name, conn, instructions: info.instructions });
|
|
20257
20277
|
} catch (err) {
|
|
20258
|
-
await
|
|
20259
|
-
|
|
20260
|
-
|
|
20261
|
-
|
|
20278
|
+
await writeErrRedacted(
|
|
20279
|
+
platform2,
|
|
20280
|
+
false,
|
|
20281
|
+
"connection",
|
|
20282
|
+
`connection to ${name} failed: ${err.message}`,
|
|
20283
|
+
redact2
|
|
20262
20284
|
);
|
|
20263
20285
|
}
|
|
20264
20286
|
}
|
|
@@ -20281,10 +20303,19 @@ async function resolveTargetNames(platform2, parsed) {
|
|
|
20281
20303
|
const positionalExtra = parsed.toolName;
|
|
20282
20304
|
if (positionalExtra && parsed.verb !== "call") targets.push(positionalExtra);
|
|
20283
20305
|
if (targets.length > 0) return targets;
|
|
20284
|
-
|
|
20306
|
+
return enabledNames(await MergedConfigSource.load(platform2));
|
|
20307
|
+
}
|
|
20308
|
+
function enabledNames(config) {
|
|
20285
20309
|
return config.list().filter((e) => e.config.enabled !== false).map((e) => e.name);
|
|
20286
20310
|
}
|
|
20287
20311
|
async function dispatchMultiTarget(platform2, parsed, version) {
|
|
20312
|
+
const { secrets, unset } = expandAndCollect(parsed.headers, platform2.env, parsed.extra);
|
|
20313
|
+
if (unset.length > 0 && !isKernel(platform2)) return refuseUnsetHeaders(platform2, unset);
|
|
20314
|
+
const hidden = new Set(secrets);
|
|
20315
|
+
const redact2 = (text) => redactSecrets(text, hidden);
|
|
20316
|
+
return runMultiTarget(redactWrites(platform2, redact2), parsed, version, hidden, redact2);
|
|
20317
|
+
}
|
|
20318
|
+
async function runMultiTarget(platform2, parsed, version, hidden, redact2) {
|
|
20288
20319
|
let activeCleanup;
|
|
20289
20320
|
async function killTreeAndExit(exitCode) {
|
|
20290
20321
|
if (activeCleanup) {
|
|
@@ -20323,18 +20354,15 @@ async function dispatchMultiTarget(platform2, parsed, version) {
|
|
|
20323
20354
|
await platform2.write(2, "mcpcat: code requires -e <source> or a file\n");
|
|
20324
20355
|
return 2;
|
|
20325
20356
|
}
|
|
20326
|
-
|
|
20327
|
-
if (parsed.serverTargets.length > 0) {
|
|
20328
|
-
serverNames = parsed.serverTargets;
|
|
20329
|
-
} else {
|
|
20330
|
-
serverNames = config.list().filter((e) => e.config.enabled !== false).map((e) => e.name);
|
|
20331
|
-
}
|
|
20357
|
+
const serverNames = parsed.serverTargets.length > 0 ? parsed.serverTargets : enabledNames(config);
|
|
20332
20358
|
const { targets, cleanup } = await connectTargets(
|
|
20333
20359
|
platform2,
|
|
20334
20360
|
serverNames,
|
|
20335
20361
|
config,
|
|
20336
20362
|
parsed,
|
|
20337
|
-
version
|
|
20363
|
+
version,
|
|
20364
|
+
hidden,
|
|
20365
|
+
redact2
|
|
20338
20366
|
);
|
|
20339
20367
|
activeCleanup = cleanup;
|
|
20340
20368
|
try {
|
|
@@ -20343,7 +20371,8 @@ async function dispatchMultiTarget(platform2, parsed, version) {
|
|
|
20343
20371
|
timeoutMs: parsed.timeoutMs,
|
|
20344
20372
|
memoryLimitMiB: parsed.memoryLimitMiB,
|
|
20345
20373
|
allowShell: parsed.allowShell,
|
|
20346
|
-
platform: platform2
|
|
20374
|
+
platform: platform2,
|
|
20375
|
+
redact: redact2
|
|
20347
20376
|
});
|
|
20348
20377
|
} catch (err) {
|
|
20349
20378
|
await platform2.write(2, `mcpcat: ${err.message}
|
|
@@ -20361,13 +20390,15 @@ async function dispatchMultiTarget(platform2, parsed, version) {
|
|
|
20361
20390
|
await platform2.write(2, "mcpcat: grep requires a pattern\n");
|
|
20362
20391
|
return 2;
|
|
20363
20392
|
}
|
|
20364
|
-
const serverNames = parsed.toolName ? [parsed.toolName] :
|
|
20393
|
+
const serverNames = parsed.toolName ? [parsed.toolName] : enabledNames(config);
|
|
20365
20394
|
const { targets, cleanup } = await connectTargets(
|
|
20366
20395
|
platform2,
|
|
20367
20396
|
serverNames,
|
|
20368
20397
|
config,
|
|
20369
20398
|
parsed,
|
|
20370
|
-
version
|
|
20399
|
+
version,
|
|
20400
|
+
hidden,
|
|
20401
|
+
redact2
|
|
20371
20402
|
);
|
|
20372
20403
|
activeCleanup = cleanup;
|
|
20373
20404
|
try {
|
|
@@ -20375,6 +20406,8 @@ async function dispatchMultiTarget(platform2, parsed, version) {
|
|
|
20375
20406
|
rank: parsed.rank,
|
|
20376
20407
|
extended: parsed.extendedRegex
|
|
20377
20408
|
});
|
|
20409
|
+
} catch (err) {
|
|
20410
|
+
return await reportError(platform2, parsed.jsonOutput, err, redact2);
|
|
20378
20411
|
} finally {
|
|
20379
20412
|
await cleanup();
|
|
20380
20413
|
await killAllStdio().catch(() => {
|
|
@@ -20388,11 +20421,15 @@ async function dispatchMultiTarget(platform2, parsed, version) {
|
|
|
20388
20421
|
serverNames,
|
|
20389
20422
|
config,
|
|
20390
20423
|
parsed,
|
|
20391
|
-
version
|
|
20424
|
+
version,
|
|
20425
|
+
hidden,
|
|
20426
|
+
redact2
|
|
20392
20427
|
);
|
|
20393
20428
|
activeCleanup = cleanup;
|
|
20394
20429
|
try {
|
|
20395
|
-
return await runDescribeTs(platform2, targets, parsed.tsBudget);
|
|
20430
|
+
return await runDescribeTs(platform2, targets, parsed.tsBudget, redact2);
|
|
20431
|
+
} catch (err) {
|
|
20432
|
+
return await reportError(platform2, parsed.jsonOutput, err, redact2);
|
|
20396
20433
|
} finally {
|
|
20397
20434
|
await cleanup();
|
|
20398
20435
|
await killAllStdio().catch(() => {
|
|
@@ -20829,14 +20866,7 @@ async function handleInputRequired(platform2, conn, err, respondData, json, reda
|
|
|
20829
20866
|
}
|
|
20830
20867
|
async function runClientVerb(platform2, version, parsed) {
|
|
20831
20868
|
const { expanded, secrets, unset } = expandAndCollect(parsed.headers, platform2.env, parsed.extra);
|
|
20832
|
-
if (unset.length > 0)
|
|
20833
|
-
await platform2.write(
|
|
20834
|
-
2,
|
|
20835
|
-
`mcpcat: unset variable${unset.length > 1 ? "s" : ""} in -H: ${unset.join(", ")}
|
|
20836
|
-
`
|
|
20837
|
-
);
|
|
20838
|
-
return EXIT_USAGE;
|
|
20839
|
-
}
|
|
20869
|
+
if (unset.length > 0) return refuseUnsetHeaders(platform2, unset);
|
|
20840
20870
|
const verbose = createVerboseLogger(platform2, parsed.verbose);
|
|
20841
20871
|
for (const s of secrets) verbose.secrets.add(s);
|
|
20842
20872
|
const timeoutMs = parsed.timeoutMs;
|
|
@@ -20888,12 +20918,10 @@ async function runClientVerb(platform2, version, parsed) {
|
|
|
20888
20918
|
await writeErr(platform2, parsed.jsonOutput, "usage", err.message);
|
|
20889
20919
|
return EXIT_USAGE;
|
|
20890
20920
|
}
|
|
20891
|
-
const
|
|
20892
|
-
platform2
|
|
20893
|
-
|
|
20894
|
-
|
|
20895
|
-
});
|
|
20896
|
-
const configSecrets = collectConfigSecrets(resolved.headers, platform2.env);
|
|
20921
|
+
const { headers: configHeaders, secrets: configSecrets } = expandConfigHeaders(
|
|
20922
|
+
platform2,
|
|
20923
|
+
resolved.headers
|
|
20924
|
+
);
|
|
20897
20925
|
for (const s of configSecrets) verbose.secrets.add(s);
|
|
20898
20926
|
const allSecrets = /* @__PURE__ */ new Set([...secrets, ...configSecrets]);
|
|
20899
20927
|
const redact2 = (text) => redactSecrets(text, allSecrets);
|
|
@@ -20993,9 +21021,7 @@ async function runClientVerb(platform2, version, parsed) {
|
|
|
20993
21021
|
`);
|
|
20994
21022
|
return EXIT_INPUT_REQUIRED;
|
|
20995
21023
|
}
|
|
20996
|
-
|
|
20997
|
-
await writeErrRedacted(platform2, parsed.jsonOutput, e.kind, e.msg, redact2);
|
|
20998
|
-
return e.code;
|
|
21024
|
+
return await reportError(platform2, parsed.jsonOutput, err, redact2);
|
|
20999
21025
|
} finally {
|
|
21000
21026
|
await closeAndKillStdio(conn);
|
|
21001
21027
|
}
|
|
@@ -21022,6 +21048,28 @@ async function writeErrRedacted(p, json, kind, msg, redact2) {
|
|
|
21022
21048
|
else await p.write(2, sanitizeTerminal(`mcpcat: ${redact2(msg)}
|
|
21023
21049
|
`));
|
|
21024
21050
|
}
|
|
21051
|
+
async function reportError(platform2, json, err, redact2) {
|
|
21052
|
+
const e = classifyError(err);
|
|
21053
|
+
await writeErrRedacted(platform2, json, e.kind, e.msg, redact2);
|
|
21054
|
+
return e.code;
|
|
21055
|
+
}
|
|
21056
|
+
async function refuseUnsetHeaders(platform2, unset) {
|
|
21057
|
+
await platform2.write(
|
|
21058
|
+
2,
|
|
21059
|
+
`mcpcat: unset variable${unset.length > 1 ? "s" : ""} in -H: ${unset.join(", ")}
|
|
21060
|
+
`
|
|
21061
|
+
);
|
|
21062
|
+
return EXIT_USAGE;
|
|
21063
|
+
}
|
|
21064
|
+
function expandConfigHeaders(platform2, headers) {
|
|
21065
|
+
const warn = (msg) => void platform2.write(2, `mcpcat: warning: ${msg}
|
|
21066
|
+
`).catch(() => {
|
|
21067
|
+
});
|
|
21068
|
+
return {
|
|
21069
|
+
headers: expandHeaders(headers, platform2.env, warn),
|
|
21070
|
+
secrets: collectConfigSecrets(headers, platform2.env)
|
|
21071
|
+
};
|
|
21072
|
+
}
|
|
21025
21073
|
function collectConfigSecrets(headers, env2) {
|
|
21026
21074
|
if (!headers) return [];
|
|
21027
21075
|
const secrets = [];
|
|
@@ -21521,7 +21569,7 @@ async function main(ctx) {
|
|
|
21521
21569
|
packageDir: "/node_modules/@ai-ecoverse/mcpcat"
|
|
21522
21570
|
});
|
|
21523
21571
|
const args = ctx.argv.slice(1);
|
|
21524
|
-
return run(platform2, "0.31.
|
|
21572
|
+
return run(platform2, "0.31.11", args);
|
|
21525
21573
|
}
|
|
21526
21574
|
export {
|
|
21527
21575
|
main as default
|