@ai-ecoverse/mcpcat 0.15.3 → 0.15.5

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.
@@ -6479,6 +6479,24 @@ var MIN_VERSION = [0, 14, 1];
6479
6479
  var VERSION_TIMEOUT_MS = 2e3;
6480
6480
  var JERK_TIMEOUT_MS = 15e3;
6481
6481
  var cachedAvailable;
6482
+ var cachedKnown;
6483
+ async function listMcpProviders(platform2) {
6484
+ const known = /* @__PURE__ */ new Set();
6485
+ try {
6486
+ const result = await runJerk(platform2, ["jerk", "list", "--json"], VERSION_TIMEOUT_MS);
6487
+ if (result.status !== 0) return known;
6488
+ const providers = JSON.parse(result.stdout);
6489
+ for (const p of providers) {
6490
+ if (p?.source === "mcp.json" && typeof p.provider === "string") known.add(p.provider);
6491
+ }
6492
+ } catch {
6493
+ }
6494
+ return known;
6495
+ }
6496
+ async function jerkKnows(platform2, id) {
6497
+ cachedKnown ??= listMcpProviders(platform2);
6498
+ return (await cachedKnown).has(id);
6499
+ }
6482
6500
  function parseVersion(raw) {
6483
6501
  const match = raw.trim().match(/(\d+)\.(\d+)\.(\d+)/);
6484
6502
  if (!match) return void 0;
@@ -12954,7 +12972,14 @@ async function runServe(platform2, options, version) {
12954
12972
  generatedBearer
12955
12973
  );
12956
12974
  }
12957
- async function publishBearer(platform2, token, port, listenUrl, json) {
12975
+ function serveAddress(platform2, host, port) {
12976
+ if (platform2.kind !== "kernel") return { url: `http://${host}:${port}/mcp` };
12977
+ return {
12978
+ url: `http://${port}.kernel.localhost/mcp`,
12979
+ loopbackUrl: `http://127.0.0.1:${port}/mcp`
12980
+ };
12981
+ }
12982
+ async function publishBearer(platform2, token, port, address, json) {
12958
12983
  if (!json && platform2.isatty(2)) {
12959
12984
  await platform2.write(2, `mcpcat serve: bearer ${token}
12960
12985
  `);
@@ -12971,7 +12996,7 @@ async function publishBearer(platform2, token, port, listenUrl, json) {
12971
12996
  await platform2.write(2, `mcpcat serve: bearer saved to ${tokenPath}
12972
12997
  `);
12973
12998
  if (json) {
12974
- await platform2.write(1, `${JSON.stringify({ url: listenUrl, bearerFile: tokenPath })}
12999
+ await platform2.write(1, `${JSON.stringify({ ...address, bearerFile: tokenPath })}
12975
13000
  `);
12976
13001
  }
12977
13002
  return tokenPath;
@@ -13150,19 +13175,20 @@ async function runWebMcpHttp(platform2, options, getTools, callTool, serverName,
13150
13175
  const actualPort = listener.port;
13151
13176
  const serverOrigins = buildServerOrigins(options.host, actualPort);
13152
13177
  const allowedHosts = buildAllowedHosts(options.host, actualPort, options.allowHosts);
13153
- const listenUrl = `http://${options.host}:${actualPort}/mcp`;
13178
+ const address = serveAddress(platform2, options.host, actualPort);
13179
+ const listenUrl = address.url;
13154
13180
  let tokenFilePath;
13155
13181
  if (generatedBearer && resolvedBearer) {
13156
13182
  tokenFilePath = await publishBearer(
13157
13183
  platform2,
13158
13184
  resolvedBearer,
13159
13185
  actualPort,
13160
- listenUrl,
13186
+ address,
13161
13187
  options.json
13162
13188
  );
13163
13189
  } else {
13164
13190
  if (options.json) {
13165
- await platform2.write(1, `${JSON.stringify({ url: listenUrl })}
13191
+ await platform2.write(1, `${JSON.stringify(address)}
13166
13192
  `);
13167
13193
  }
13168
13194
  }
@@ -13345,19 +13371,20 @@ async function runProxyHttp(platform2, options, proxy, resolvedBearer, generated
13345
13371
  const actualPort = listener.port;
13346
13372
  const serverOrigins = buildServerOrigins(options.host, actualPort);
13347
13373
  const allowedHosts = buildAllowedHosts(options.host, actualPort, options.allowHosts);
13348
- const listenUrl = `http://${options.host}:${actualPort}/mcp`;
13374
+ const address = serveAddress(platform2, options.host, actualPort);
13375
+ const listenUrl = address.url;
13349
13376
  let tokenFilePath;
13350
13377
  if (generatedBearer && resolvedBearer) {
13351
13378
  tokenFilePath = await publishBearer(
13352
13379
  platform2,
13353
13380
  resolvedBearer,
13354
13381
  actualPort,
13355
- listenUrl,
13382
+ address,
13356
13383
  options.json
13357
13384
  );
13358
13385
  } else {
13359
13386
  if (options.json) {
13360
- await platform2.write(1, `${JSON.stringify({ url: listenUrl })}
13387
+ await platform2.write(1, `${JSON.stringify(address)}
13361
13388
  `);
13362
13389
  }
13363
13390
  }
@@ -13521,19 +13548,20 @@ async function runHttpServer(platform2, options, tools, call, serverName, versio
13521
13548
  const actualPort = listener.port;
13522
13549
  const serverOrigins = buildServerOrigins(options.host, actualPort);
13523
13550
  const allowedHosts = buildAllowedHosts(options.host, actualPort, options.allowHosts);
13524
- const listenUrl = `http://${options.host}:${actualPort}/mcp`;
13551
+ const address = serveAddress(platform2, options.host, actualPort);
13552
+ const listenUrl = address.url;
13525
13553
  let tokenFilePath;
13526
13554
  if (generatedBearer && resolvedBearer) {
13527
13555
  tokenFilePath = await publishBearer(
13528
13556
  platform2,
13529
13557
  resolvedBearer,
13530
13558
  actualPort,
13531
- listenUrl,
13559
+ address,
13532
13560
  options.json
13533
13561
  );
13534
13562
  } else {
13535
13563
  if (options.json) {
13536
- await platform2.write(1, `${JSON.stringify({ url: listenUrl })}
13564
+ await platform2.write(1, `${JSON.stringify(address)}
13537
13565
  `);
13538
13566
  }
13539
13567
  }
@@ -13860,16 +13888,11 @@ async function signIn(options) {
13860
13888
  }
13861
13889
 
13862
13890
  // src/cli/auth-verbs.ts
13863
- var resolvedSource;
13864
- async function createTokenSource(platform2, timeoutMs = JERK_TIMEOUT_MS) {
13865
- if (isKernel(platform2)) return new PiFileTokenSource(platform2);
13866
- if (resolvedSource) return resolvedSource;
13867
- if (await jerkAvailable(platform2)) {
13868
- resolvedSource = new JerkTokenSource(platform2, timeoutMs);
13869
- } else {
13870
- resolvedSource = new PiFileTokenSource(platform2);
13891
+ async function createTokenSource(platform2, name, timeoutMs = JERK_TIMEOUT_MS) {
13892
+ if (!isKernel(platform2) && !name.startsWith("url:") && await jerkAvailable(platform2) && await jerkKnows(platform2, jerkMcpId(name))) {
13893
+ return new JerkTokenSource(platform2, timeoutMs);
13871
13894
  }
13872
- return resolvedSource;
13895
+ return new PiFileTokenSource(platform2);
13873
13896
  }
13874
13897
  var VALUE_FLAGS = /* @__PURE__ */ new Set(["--scope", "-m", "--timeout"]);
13875
13898
  function positionals(args2) {
@@ -13930,8 +13953,7 @@ async function readStream2(stream) {
13930
13953
  }
13931
13954
  return new TextDecoder().decode(buf);
13932
13955
  }
13933
- async function jerkLogin(platform2, target, args2) {
13934
- const resolved = await resolveLoginTarget(platform2, target);
13956
+ async function jerkLogin(platform2, target, resolved, args2) {
13935
13957
  const id = jerkMcpId(resolved.name);
13936
13958
  const argv = ["jerk", id, "create"];
13937
13959
  const scopeIdx = args2.indexOf("--scope");
@@ -13960,8 +13982,7 @@ async function jerkLogin(platform2, target, args2) {
13960
13982
  if (result.status === JERK_EXIT_SIGN_IN) return 4;
13961
13983
  return result.status;
13962
13984
  }
13963
- async function jerkLogout(platform2, target, source) {
13964
- const resolved = await resolveLoginTarget(platform2, target);
13985
+ async function jerkLogout(platform2, target, resolved, source) {
13965
13986
  const id = jerkMcpId(resolved.name);
13966
13987
  const result = await runJerk(platform2, ["jerk", id, "drop", "--yes"], source.timeoutMs);
13967
13988
  if (result.status === 0) {
@@ -13973,7 +13994,7 @@ async function jerkLogout(platform2, target, source) {
13973
13994
  }
13974
13995
  return 0;
13975
13996
  }
13976
- async function runLogin(platform2, args2, source) {
13997
+ async function runLogin(platform2, args2, timeoutMs) {
13977
13998
  if (isKernel(platform2)) {
13978
13999
  await platform2.write(
13979
14000
  2,
@@ -13987,9 +14008,18 @@ async function runLogin(platform2, args2, source) {
13987
14008
  return 2;
13988
14009
  }
13989
14010
  const target = positional[0];
14011
+ let resolved;
14012
+ try {
14013
+ resolved = await resolveLoginTarget(platform2, target);
14014
+ } catch (err) {
14015
+ await platform2.write(2, `mcpcat: ${err.message}
14016
+ `);
14017
+ return 2;
14018
+ }
14019
+ const source = await createTokenSource(platform2, resolved.name, timeoutMs);
13990
14020
  if (source instanceof JerkTokenSource) {
13991
14021
  try {
13992
- return await jerkLogin(platform2, target, args2);
14022
+ return await jerkLogin(platform2, target, resolved, args2);
13993
14023
  } catch (err) {
13994
14024
  await platform2.write(2, `mcpcat: login failed: ${err.message}
13995
14025
  `);
@@ -13997,14 +14027,6 @@ async function runLogin(platform2, args2, source) {
13997
14027
  }
13998
14028
  }
13999
14029
  const noBrowser = args2.includes("--no-browser");
14000
- let resolved;
14001
- try {
14002
- resolved = await resolveLoginTarget(platform2, target);
14003
- } catch (err) {
14004
- await platform2.write(2, `mcpcat: ${err.message}
14005
- `);
14006
- return 2;
14007
- }
14008
14030
  try {
14009
14031
  await signIn({
14010
14032
  name: resolved.name,
@@ -14067,7 +14089,7 @@ ${url.href}
14067
14089
  return 4;
14068
14090
  }
14069
14091
  }
14070
- async function runLogout(platform2, args2, source) {
14092
+ async function runLogout(platform2, args2, timeoutMs) {
14071
14093
  if (isKernel(platform2)) {
14072
14094
  await platform2.write(2, "mcpcat: logout is not available in seven.\n");
14073
14095
  return 4;
@@ -14078,9 +14100,18 @@ async function runLogout(platform2, args2, source) {
14078
14100
  return 2;
14079
14101
  }
14080
14102
  const target = positional[0];
14103
+ let resolved;
14104
+ try {
14105
+ resolved = await resolveLoginTarget(platform2, target);
14106
+ } catch (err) {
14107
+ await platform2.write(2, `mcpcat: ${err.message}
14108
+ `);
14109
+ return 2;
14110
+ }
14111
+ const source = await createTokenSource(platform2, resolved.name, timeoutMs);
14081
14112
  if (source instanceof JerkTokenSource) {
14082
14113
  try {
14083
- return await jerkLogout(platform2, target, source);
14114
+ return await jerkLogout(platform2, target, resolved, source);
14084
14115
  } catch (err) {
14085
14116
  if (err instanceof JerkTimeoutError) {
14086
14117
  await platform2.write(2, `mcpcat: ${err.message}
@@ -14092,14 +14123,6 @@ async function runLogout(platform2, args2, source) {
14092
14123
  return 1;
14093
14124
  }
14094
14125
  }
14095
- let resolved;
14096
- try {
14097
- resolved = await resolveLoginTarget(platform2, target);
14098
- } catch (err) {
14099
- await platform2.write(2, `mcpcat: ${err.message}
14100
- `);
14101
- return 2;
14102
- }
14103
14126
  const removed = await source.remove(resolved.name, resolved.serverUrl);
14104
14127
  if (removed) {
14105
14128
  await platform2.write(1, `Signed out of ${target}
@@ -16076,12 +16099,10 @@ async function runInner(platform2, version, args2) {
16076
16099
  const discResult = await dispatchDiscoveryVerb(platform2, parsed, args2);
16077
16100
  if (discResult !== void 0) return discResult;
16078
16101
  if (parsed.verb === "login") {
16079
- const source = await createTokenSource(platform2, parsed.timeoutMs);
16080
- return runLogin(platform2, withoutVerb(args2, "login"), source);
16102
+ return runLogin(platform2, withoutVerb(args2, "login"), parsed.timeoutMs);
16081
16103
  }
16082
16104
  if (parsed.verb === "logout") {
16083
- const source = await createTokenSource(platform2, parsed.timeoutMs);
16084
- return runLogout(platform2, withoutVerb(args2, "logout"), source);
16105
+ return runLogout(platform2, withoutVerb(args2, "logout"), parsed.timeoutMs);
16085
16106
  }
16086
16107
  if (UNIMPLEMENTED_VERBS.has(parsed.verb)) {
16087
16108
  await platform2.write(2, `mcpcat: '${parsed.verb}' is not implemented yet
@@ -16174,10 +16195,10 @@ function classifyError(err) {
16174
16195
  }
16175
16196
  async function resolveAuthProvider(platform2, hasAuthHeader, url, target, config, timeoutMs, onCredentialObtained) {
16176
16197
  if (hasAuthHeader || !url) return void 0;
16177
- const source = await createTokenSource(platform2, timeoutMs);
16178
16198
  const entry = config.entry(target);
16179
16199
  const oauth = entry && "url" in entry.config ? entry.config.oauth : void 0;
16180
16200
  const name = entry ? target : `url:${new URL(url).origin}${new URL(url).pathname}`;
16201
+ const source = await createTokenSource(platform2, name, timeoutMs);
16181
16202
  const provider = createMcpAuthProvider({
16182
16203
  name,
16183
16204
  serverUrl: url,
@@ -16713,5 +16734,5 @@ try {
16713
16734
  });
16714
16735
  } catch {
16715
16736
  }
16716
- var code = await run(platform, "0.15.3", args);
16737
+ var code = await run(platform, "0.15.5", args);
16717
16738
  process.exit(code);
@@ -6100,6 +6100,24 @@ var MIN_VERSION = [0, 14, 1];
6100
6100
  var VERSION_TIMEOUT_MS = 2e3;
6101
6101
  var JERK_TIMEOUT_MS = 15e3;
6102
6102
  var cachedAvailable;
6103
+ var cachedKnown;
6104
+ async function listMcpProviders(platform2) {
6105
+ const known = /* @__PURE__ */ new Set();
6106
+ try {
6107
+ const result = await runJerk(platform2, ["jerk", "list", "--json"], VERSION_TIMEOUT_MS);
6108
+ if (result.status !== 0) return known;
6109
+ const providers = JSON.parse(result.stdout);
6110
+ for (const p of providers) {
6111
+ if (p?.source === "mcp.json" && typeof p.provider === "string") known.add(p.provider);
6112
+ }
6113
+ } catch {
6114
+ }
6115
+ return known;
6116
+ }
6117
+ async function jerkKnows(platform2, id) {
6118
+ cachedKnown ??= listMcpProviders(platform2);
6119
+ return (await cachedKnown).has(id);
6120
+ }
6103
6121
  function parseVersion(raw) {
6104
6122
  const match = raw.trim().match(/(\d+)\.(\d+)\.(\d+)/);
6105
6123
  if (!match) return void 0;
@@ -12575,7 +12593,14 @@ async function runServe(platform2, options, version) {
12575
12593
  generatedBearer
12576
12594
  );
12577
12595
  }
12578
- async function publishBearer(platform2, token, port, listenUrl, json) {
12596
+ function serveAddress(platform2, host, port) {
12597
+ if (platform2.kind !== "kernel") return { url: `http://${host}:${port}/mcp` };
12598
+ return {
12599
+ url: `http://${port}.kernel.localhost/mcp`,
12600
+ loopbackUrl: `http://127.0.0.1:${port}/mcp`
12601
+ };
12602
+ }
12603
+ async function publishBearer(platform2, token, port, address, json) {
12579
12604
  if (!json && platform2.isatty(2)) {
12580
12605
  await platform2.write(2, `mcpcat serve: bearer ${token}
12581
12606
  `);
@@ -12592,7 +12617,7 @@ async function publishBearer(platform2, token, port, listenUrl, json) {
12592
12617
  await platform2.write(2, `mcpcat serve: bearer saved to ${tokenPath}
12593
12618
  `);
12594
12619
  if (json) {
12595
- await platform2.write(1, `${JSON.stringify({ url: listenUrl, bearerFile: tokenPath })}
12620
+ await platform2.write(1, `${JSON.stringify({ ...address, bearerFile: tokenPath })}
12596
12621
  `);
12597
12622
  }
12598
12623
  return tokenPath;
@@ -12771,19 +12796,20 @@ async function runWebMcpHttp(platform2, options, getTools, callTool, serverName,
12771
12796
  const actualPort = listener.port;
12772
12797
  const serverOrigins = buildServerOrigins(options.host, actualPort);
12773
12798
  const allowedHosts = buildAllowedHosts(options.host, actualPort, options.allowHosts);
12774
- const listenUrl = `http://${options.host}:${actualPort}/mcp`;
12799
+ const address = serveAddress(platform2, options.host, actualPort);
12800
+ const listenUrl = address.url;
12775
12801
  let tokenFilePath;
12776
12802
  if (generatedBearer && resolvedBearer) {
12777
12803
  tokenFilePath = await publishBearer(
12778
12804
  platform2,
12779
12805
  resolvedBearer,
12780
12806
  actualPort,
12781
- listenUrl,
12807
+ address,
12782
12808
  options.json
12783
12809
  );
12784
12810
  } else {
12785
12811
  if (options.json) {
12786
- await platform2.write(1, `${JSON.stringify({ url: listenUrl })}
12812
+ await platform2.write(1, `${JSON.stringify(address)}
12787
12813
  `);
12788
12814
  }
12789
12815
  }
@@ -12966,19 +12992,20 @@ async function runProxyHttp(platform2, options, proxy, resolvedBearer, generated
12966
12992
  const actualPort = listener.port;
12967
12993
  const serverOrigins = buildServerOrigins(options.host, actualPort);
12968
12994
  const allowedHosts = buildAllowedHosts(options.host, actualPort, options.allowHosts);
12969
- const listenUrl = `http://${options.host}:${actualPort}/mcp`;
12995
+ const address = serveAddress(platform2, options.host, actualPort);
12996
+ const listenUrl = address.url;
12970
12997
  let tokenFilePath;
12971
12998
  if (generatedBearer && resolvedBearer) {
12972
12999
  tokenFilePath = await publishBearer(
12973
13000
  platform2,
12974
13001
  resolvedBearer,
12975
13002
  actualPort,
12976
- listenUrl,
13003
+ address,
12977
13004
  options.json
12978
13005
  );
12979
13006
  } else {
12980
13007
  if (options.json) {
12981
- await platform2.write(1, `${JSON.stringify({ url: listenUrl })}
13008
+ await platform2.write(1, `${JSON.stringify(address)}
12982
13009
  `);
12983
13010
  }
12984
13011
  }
@@ -13142,19 +13169,20 @@ async function runHttpServer(platform2, options, tools, call, serverName, versio
13142
13169
  const actualPort = listener.port;
13143
13170
  const serverOrigins = buildServerOrigins(options.host, actualPort);
13144
13171
  const allowedHosts = buildAllowedHosts(options.host, actualPort, options.allowHosts);
13145
- const listenUrl = `http://${options.host}:${actualPort}/mcp`;
13172
+ const address = serveAddress(platform2, options.host, actualPort);
13173
+ const listenUrl = address.url;
13146
13174
  let tokenFilePath;
13147
13175
  if (generatedBearer && resolvedBearer) {
13148
13176
  tokenFilePath = await publishBearer(
13149
13177
  platform2,
13150
13178
  resolvedBearer,
13151
13179
  actualPort,
13152
- listenUrl,
13180
+ address,
13153
13181
  options.json
13154
13182
  );
13155
13183
  } else {
13156
13184
  if (options.json) {
13157
- await platform2.write(1, `${JSON.stringify({ url: listenUrl })}
13185
+ await platform2.write(1, `${JSON.stringify(address)}
13158
13186
  `);
13159
13187
  }
13160
13188
  }
@@ -13481,16 +13509,11 @@ async function signIn(options) {
13481
13509
  }
13482
13510
 
13483
13511
  // src/cli/auth-verbs.ts
13484
- var resolvedSource;
13485
- async function createTokenSource(platform2, timeoutMs = JERK_TIMEOUT_MS) {
13486
- if (isKernel(platform2)) return new PiFileTokenSource(platform2);
13487
- if (resolvedSource) return resolvedSource;
13488
- if (await jerkAvailable(platform2)) {
13489
- resolvedSource = new JerkTokenSource(platform2, timeoutMs);
13490
- } else {
13491
- resolvedSource = new PiFileTokenSource(platform2);
13512
+ async function createTokenSource(platform2, name, timeoutMs = JERK_TIMEOUT_MS) {
13513
+ if (!isKernel(platform2) && !name.startsWith("url:") && await jerkAvailable(platform2) && await jerkKnows(platform2, jerkMcpId(name))) {
13514
+ return new JerkTokenSource(platform2, timeoutMs);
13492
13515
  }
13493
- return resolvedSource;
13516
+ return new PiFileTokenSource(platform2);
13494
13517
  }
13495
13518
  var VALUE_FLAGS = /* @__PURE__ */ new Set(["--scope", "-m", "--timeout"]);
13496
13519
  function positionals(args) {
@@ -13551,8 +13574,7 @@ async function readStream2(stream) {
13551
13574
  }
13552
13575
  return new TextDecoder().decode(buf);
13553
13576
  }
13554
- async function jerkLogin(platform2, target, args) {
13555
- const resolved = await resolveLoginTarget(platform2, target);
13577
+ async function jerkLogin(platform2, target, resolved, args) {
13556
13578
  const id = jerkMcpId(resolved.name);
13557
13579
  const argv = ["jerk", id, "create"];
13558
13580
  const scopeIdx = args.indexOf("--scope");
@@ -13581,8 +13603,7 @@ async function jerkLogin(platform2, target, args) {
13581
13603
  if (result.status === JERK_EXIT_SIGN_IN) return 4;
13582
13604
  return result.status;
13583
13605
  }
13584
- async function jerkLogout(platform2, target, source) {
13585
- const resolved = await resolveLoginTarget(platform2, target);
13606
+ async function jerkLogout(platform2, target, resolved, source) {
13586
13607
  const id = jerkMcpId(resolved.name);
13587
13608
  const result = await runJerk(platform2, ["jerk", id, "drop", "--yes"], source.timeoutMs);
13588
13609
  if (result.status === 0) {
@@ -13594,7 +13615,7 @@ async function jerkLogout(platform2, target, source) {
13594
13615
  }
13595
13616
  return 0;
13596
13617
  }
13597
- async function runLogin(platform2, args, source) {
13618
+ async function runLogin(platform2, args, timeoutMs) {
13598
13619
  if (isKernel(platform2)) {
13599
13620
  await platform2.write(
13600
13621
  2,
@@ -13608,9 +13629,18 @@ async function runLogin(platform2, args, source) {
13608
13629
  return 2;
13609
13630
  }
13610
13631
  const target = positional[0];
13632
+ let resolved;
13633
+ try {
13634
+ resolved = await resolveLoginTarget(platform2, target);
13635
+ } catch (err) {
13636
+ await platform2.write(2, `mcpcat: ${err.message}
13637
+ `);
13638
+ return 2;
13639
+ }
13640
+ const source = await createTokenSource(platform2, resolved.name, timeoutMs);
13611
13641
  if (source instanceof JerkTokenSource) {
13612
13642
  try {
13613
- return await jerkLogin(platform2, target, args);
13643
+ return await jerkLogin(platform2, target, resolved, args);
13614
13644
  } catch (err) {
13615
13645
  await platform2.write(2, `mcpcat: login failed: ${err.message}
13616
13646
  `);
@@ -13618,14 +13648,6 @@ async function runLogin(platform2, args, source) {
13618
13648
  }
13619
13649
  }
13620
13650
  const noBrowser = args.includes("--no-browser");
13621
- let resolved;
13622
- try {
13623
- resolved = await resolveLoginTarget(platform2, target);
13624
- } catch (err) {
13625
- await platform2.write(2, `mcpcat: ${err.message}
13626
- `);
13627
- return 2;
13628
- }
13629
13651
  try {
13630
13652
  await signIn({
13631
13653
  name: resolved.name,
@@ -13688,7 +13710,7 @@ ${url.href}
13688
13710
  return 4;
13689
13711
  }
13690
13712
  }
13691
- async function runLogout(platform2, args, source) {
13713
+ async function runLogout(platform2, args, timeoutMs) {
13692
13714
  if (isKernel(platform2)) {
13693
13715
  await platform2.write(2, "mcpcat: logout is not available in seven.\n");
13694
13716
  return 4;
@@ -13699,9 +13721,18 @@ async function runLogout(platform2, args, source) {
13699
13721
  return 2;
13700
13722
  }
13701
13723
  const target = positional[0];
13724
+ let resolved;
13725
+ try {
13726
+ resolved = await resolveLoginTarget(platform2, target);
13727
+ } catch (err) {
13728
+ await platform2.write(2, `mcpcat: ${err.message}
13729
+ `);
13730
+ return 2;
13731
+ }
13732
+ const source = await createTokenSource(platform2, resolved.name, timeoutMs);
13702
13733
  if (source instanceof JerkTokenSource) {
13703
13734
  try {
13704
- return await jerkLogout(platform2, target, source);
13735
+ return await jerkLogout(platform2, target, resolved, source);
13705
13736
  } catch (err) {
13706
13737
  if (err instanceof JerkTimeoutError) {
13707
13738
  await platform2.write(2, `mcpcat: ${err.message}
@@ -13713,14 +13744,6 @@ async function runLogout(platform2, args, source) {
13713
13744
  return 1;
13714
13745
  }
13715
13746
  }
13716
- let resolved;
13717
- try {
13718
- resolved = await resolveLoginTarget(platform2, target);
13719
- } catch (err) {
13720
- await platform2.write(2, `mcpcat: ${err.message}
13721
- `);
13722
- return 2;
13723
- }
13724
13747
  const removed = await source.remove(resolved.name, resolved.serverUrl);
13725
13748
  if (removed) {
13726
13749
  await platform2.write(1, `Signed out of ${target}
@@ -15697,12 +15720,10 @@ async function runInner(platform2, version, args) {
15697
15720
  const discResult = await dispatchDiscoveryVerb(platform2, parsed, args);
15698
15721
  if (discResult !== void 0) return discResult;
15699
15722
  if (parsed.verb === "login") {
15700
- const source = await createTokenSource(platform2, parsed.timeoutMs);
15701
- return runLogin(platform2, withoutVerb(args, "login"), source);
15723
+ return runLogin(platform2, withoutVerb(args, "login"), parsed.timeoutMs);
15702
15724
  }
15703
15725
  if (parsed.verb === "logout") {
15704
- const source = await createTokenSource(platform2, parsed.timeoutMs);
15705
- return runLogout(platform2, withoutVerb(args, "logout"), source);
15726
+ return runLogout(platform2, withoutVerb(args, "logout"), parsed.timeoutMs);
15706
15727
  }
15707
15728
  if (UNIMPLEMENTED_VERBS.has(parsed.verb)) {
15708
15729
  await platform2.write(2, `mcpcat: '${parsed.verb}' is not implemented yet
@@ -15795,10 +15816,10 @@ function classifyError(err) {
15795
15816
  }
15796
15817
  async function resolveAuthProvider(platform2, hasAuthHeader, url, target, config, timeoutMs, onCredentialObtained) {
15797
15818
  if (hasAuthHeader || !url) return void 0;
15798
- const source = await createTokenSource(platform2, timeoutMs);
15799
15819
  const entry = config.entry(target);
15800
15820
  const oauth = entry && "url" in entry.config ? entry.config.oauth : void 0;
15801
15821
  const name = entry ? target : `url:${new URL(url).origin}${new URL(url).pathname}`;
15822
+ const source = await createTokenSource(platform2, name, timeoutMs);
15802
15823
  const provider = createMcpAuthProvider({
15803
15824
  name,
15804
15825
  serverUrl: url,
@@ -16215,11 +16236,30 @@ async function kernelListen(ctx, options) {
16215
16236
  };
16216
16237
  }
16217
16238
  var KERNEL_LOCALHOST_RE = /^(\d+)\.kernel\.localhost$/;
16239
+ var LOOPBACK_HOSTNAMES = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "[::1]"]);
16218
16240
  function extractLoopbackPort(url) {
16219
16241
  const m = KERNEL_LOCALHOST_RE.exec(url.hostname);
16220
16242
  if (m) return Number(m[1]);
16221
16243
  return null;
16222
16244
  }
16245
+ function extractPlainLoopbackPort(url) {
16246
+ if (url.protocol !== "http:" || !LOOPBACK_HOSTNAMES.has(url.hostname)) return null;
16247
+ return url.port ? Number(url.port) : 80;
16248
+ }
16249
+ function isConnectionRefused(err) {
16250
+ const e = err;
16251
+ if (e?.code === "ECONNREFUSED") return true;
16252
+ return typeof e?.message === "string" && e.message.includes("ECONNREFUSED");
16253
+ }
16254
+ function isFetchRefused(err) {
16255
+ return err instanceof TypeError && isConnectionRefused(err.cause);
16256
+ }
16257
+ function loopbackRefused(url, port, err) {
16258
+ return new TypeError(
16259
+ `nothing listens on ${url.hostname}:${port} for a kernel program, whose loopback is the kernel's; reach a host server via http://host.slicc.internal:${port}`,
16260
+ { cause: err.cause }
16261
+ );
16262
+ }
16223
16263
  function collectHeaders(init) {
16224
16264
  const entries = [];
16225
16265
  if (!init?.headers) return entries;
@@ -16274,7 +16314,7 @@ function parseHttpResponse(buf, headerPos, bufLen) {
16274
16314
  const responseBody = dec.decode(buf.slice(headerEndByte, headerEndByte + contentLength));
16275
16315
  return { status, statusText, headers: respHeaders, body: responseBody };
16276
16316
  }
16277
- async function kernelLoopbackFetch(ctx, url, port, init) {
16317
+ async function kernelLoopbackFetch(ctx, url, port, init, onRefused) {
16278
16318
  const method = (init?.method ?? "GET").toUpperCase();
16279
16319
  const enc = new TextEncoder();
16280
16320
  const dec = new TextDecoder();
@@ -16285,7 +16325,13 @@ async function kernelLoopbackFetch(ctx, url, port, init) {
16285
16325
  const bodyBytes = enc.encode(bodyStr);
16286
16326
  const headerEntries = collectHeaders(init);
16287
16327
  const reqBytes = buildHttpRequest(method, url, headerEntries, bodyBytes);
16288
- const conn = await ctx.net.connect({ host: "127.0.0.1", port });
16328
+ let conn;
16329
+ try {
16330
+ conn = await ctx.net.connect({ host: "127.0.0.1", port });
16331
+ } catch (err) {
16332
+ if (onRefused && isConnectionRefused(err)) return onRefused();
16333
+ throw err;
16334
+ }
16289
16335
  const writer = conn.writable.getWriter();
16290
16336
  await writer.write(reqBytes);
16291
16337
  const reader = conn.readable.getReader();
@@ -16338,6 +16384,18 @@ function createKernelFetch(ctx) {
16338
16384
  }
16339
16385
  const port = extractLoopbackPort(url);
16340
16386
  if (port !== null) return kernelLoopbackFetch(ctx, url, port, init);
16387
+ const plainPort = extractPlainLoopbackPort(url);
16388
+ if (plainPort !== null) {
16389
+ return kernelLoopbackFetch(
16390
+ ctx,
16391
+ url,
16392
+ plainPort,
16393
+ init,
16394
+ () => ctx.fetch(input, init).catch((err) => {
16395
+ throw isFetchRefused(err) ? loopbackRefused(url, plainPort, err) : err;
16396
+ })
16397
+ );
16398
+ }
16341
16399
  return ctx.fetch(input, init);
16342
16400
  };
16343
16401
  }
@@ -16394,7 +16452,7 @@ async function main(ctx) {
16394
16452
  packageDir: "/node_modules/@ai-ecoverse/mcpcat"
16395
16453
  });
16396
16454
  const args = ctx.argv.slice(1);
16397
- return run(platform2, "0.15.3", args);
16455
+ return run(platform2, "0.15.5", args);
16398
16456
  }
16399
16457
  export {
16400
16458
  main as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/mcpcat",
3
- "version": "0.15.3",
3
+ "version": "0.15.5",
4
4
  "description": "A curl for the Model Context Protocol",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -56,8 +56,8 @@
56
56
  "trust:dry": "npx fledgling sync --dry-run -y --skip-publish"
57
57
  },
58
58
  "devDependencies": {
59
- "@ai-ecoverse/slicc-kernel": "1.88.1",
60
- "@ai-ecoverse/slicc-shared-web": "1.13.1",
59
+ "@ai-ecoverse/slicc-kernel": "1.91.0",
60
+ "@ai-ecoverse/slicc-shared-web": "1.14.0",
61
61
  "@biomejs/biome": "2.5.15",
62
62
  "@earendil-works/pi-codemode": "1.2.0",
63
63
  "@earendil-works/pi-mcp": "1.2.0",