@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.
@@ -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
- return await formatOutput(platform2, result, json);
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: isKernel(platform2) ? expandHeaders(merged, platform2.env, warn) : merged,
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 platform2.write(
20742
- 2,
20743
- sanitizeTerminal(`mcpcat: connection to ${name} failed: ${err.message}
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
- const config = await MergedConfigSource.load(platform2);
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
- let serverNames;
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] : config.list().filter((e) => e.config.enabled !== false).map((e) => e.name);
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 configHeaders = expandHeaders(resolved.headers, platform2.env, (msg) => {
21375
- platform2.write(2, `mcpcat: warning: ${msg}
21376
- `).catch(() => {
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
- const e = classifyError(err);
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.10", args);
22219
+ var code = await run(platform, "0.31.11", args);
22172
22220
  process.exit(code);
@@ -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
- return await formatOutput(platform2, result, json);
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: isKernel(platform2) ? expandHeaders(merged, platform2.env, warn) : merged,
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 platform2.write(
20259
- 2,
20260
- sanitizeTerminal(`mcpcat: connection to ${name} failed: ${err.message}
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
- const config = await MergedConfigSource.load(platform2);
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
- let serverNames;
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] : config.list().filter((e) => e.config.enabled !== false).map((e) => e.name);
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 configHeaders = expandHeaders(resolved.headers, platform2.env, (msg) => {
20892
- platform2.write(2, `mcpcat: warning: ${msg}
20893
- `).catch(() => {
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
- const e = classifyError(err);
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.10", args);
21572
+ return run(platform2, "0.31.11", args);
21525
21573
  }
21526
21574
  export {
21527
21575
  main as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/mcpcat",
3
- "version": "0.31.10",
3
+ "version": "0.31.11",
4
4
  "description": "A curl for the Model Context Protocol",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",