@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.
@@ -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
- const ordered = [...secrets].filter((s) => s.length > 0).sort((a, b) => b.length - a.length);
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, secrets) {
12157
- if (typeof value === "string") return scrubString(value, secrets);
12158
- if (Array.isArray(value)) return value.map((v) => scrubValue(v, secrets));
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, secrets);
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 secrets = options.hiddenHeaders;
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, secrets));
12239
+ return rpcOk2(id, scrubValue(result, scrub));
12230
12240
  }
12231
12241
  function scrubErr(id, code2, message) {
12232
- return rpcError2(id, code2, scrubString(message, secrets));
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 merged = { ...entry.headers, ...connectHeaders };
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)) hiddenValues.add(v);
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 expanded = expandHeaders(config.headers, platform2.env);
16109
- if (expanded) opts.headers = expanded;
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(parsed2.name, {
16592
- ...parsed2.arguments,
16593
- _meta: { inputResponses: elicitResult.answers }
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.7", args);
17070
+ var code = await run(platform, "0.17.9", args);
17049
17071
  process.exit(code);
@@ -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
- const ordered = [...secrets].filter((s) => s.length > 0).sort((a, b) => b.length - a.length);
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, secrets) {
11778
- if (typeof value === "string") return scrubString(value, secrets);
11779
- if (Array.isArray(value)) return value.map((v) => scrubValue(v, secrets));
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, secrets);
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 secrets = options.hiddenHeaders;
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, secrets));
11860
+ return rpcOk2(id, scrubValue(result, scrub));
11851
11861
  }
11852
11862
  function scrubErr(id, code, message) {
11853
- return rpcError2(id, code, scrubString(message, secrets));
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 merged = { ...entry.headers, ...connectHeaders };
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)) hiddenValues.add(v);
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 expanded = expandHeaders(config.headers, platform2.env);
15730
- if (expanded) opts.headers = expanded;
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(parsed2.name, {
16213
- ...parsed2.arguments,
16214
- _meta: { inputResponses: elicitResult.answers }
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.7", args);
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.7",
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.36.1",
65
- "@ai-ecoverse/slicc-kernel": "1.141.3",
66
- "@ai-ecoverse/slicc-shared-web": "1.29.8",
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.141.3",
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",