@ai-ecoverse/mcpcat 0.15.6 → 0.15.7

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.
@@ -1854,6 +1854,16 @@ var init_version = __esm({
1854
1854
  });
1855
1855
 
1856
1856
  // node_modules/quickjs-wasi/dist/index.js
1857
+ var dist_exports = {};
1858
+ __export(dist_exports, {
1859
+ CompileFlags: () => CompileFlags,
1860
+ EvalFlags: () => EvalFlags,
1861
+ Intrinsics: () => Intrinsics,
1862
+ JSException: () => JSException,
1863
+ JSValueHandle: () => JSValueHandle,
1864
+ MAX_STACK_SIZE: () => MAX_STACK_SIZE,
1865
+ QuickJS: () => QuickJS
1866
+ });
1857
1867
  function stringKeyNeedsValuePath(key) {
1858
1868
  return key.includes("\0") || LONE_SURROGATE_RE.test(key);
1859
1869
  }
@@ -5365,8 +5375,8 @@ SOURCE: /[\s\S]+/
5365
5375
  });
5366
5376
 
5367
5377
  // node_modules/@earendil-works/pi-codemode/dist/index.js
5368
- var dist_exports = {};
5369
- __export(dist_exports, {
5378
+ var dist_exports2 = {};
5379
+ __export(dist_exports2, {
5370
5380
  CODEMODE_OPTIONS_PREFIX: () => CODEMODE_OPTIONS_PREFIX,
5371
5381
  CODEMODE_SOURCE_GRAMMAR: () => CODEMODE_SOURCE_GRAMMAR,
5372
5382
  CodemodeSandbox: () => CodemodeSandbox,
@@ -9367,7 +9377,7 @@ function toolDeclaration(tool) {
9367
9377
  };
9368
9378
  }
9369
9379
  async function runDescribeTs(platform2, targets, budget) {
9370
- const { renderDeclarations: renderDeclarations2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
9380
+ const { renderDeclarations: renderDeclarations2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports2));
9371
9381
  const allTools = [];
9372
9382
  for (const target of targets) {
9373
9383
  const tools = await target.conn.listTools();
@@ -9438,6 +9448,39 @@ async function runGrep(platform2, pattern, targets, options) {
9438
9448
  // src/codemode/run.ts
9439
9449
  init_dist2();
9440
9450
  init_source();
9451
+
9452
+ // src/codemode/deadline.ts
9453
+ var expiries = /* @__PURE__ */ new WeakMap();
9454
+ var hooked = /* @__PURE__ */ new WeakSet();
9455
+ function hookDeadlines(quickjs) {
9456
+ if (hooked.has(quickjs)) return;
9457
+ hooked.add(quickjs);
9458
+ const create = quickjs.create.bind(quickjs);
9459
+ quickjs.create = (options) => {
9460
+ const expired = options.wasm ? expiries.get(options.wasm) : void 0;
9461
+ const inner = options.interruptHandler;
9462
+ if (!expired || !inner) return create(options);
9463
+ return create({ ...options, interruptHandler: () => expired() || inner() });
9464
+ };
9465
+ }
9466
+ function bindDeadline(wasm, timeoutMs, now = Date.now) {
9467
+ let endsAt = Number.POSITIVE_INFINITY;
9468
+ let tripped = false;
9469
+ expiries.set(wasm, () => {
9470
+ if (!tripped && now() >= endsAt) tripped = true;
9471
+ return tripped;
9472
+ });
9473
+ return {
9474
+ start() {
9475
+ endsAt = now() + timeoutMs;
9476
+ },
9477
+ get tripped() {
9478
+ return tripped;
9479
+ }
9480
+ };
9481
+ }
9482
+
9483
+ // src/codemode/run.ts
9441
9484
  async function loadStore(platform2, stateDir2) {
9442
9485
  const storePath = `${stateDir2}/codemode-store.json`;
9443
9486
  try {
@@ -9623,9 +9666,23 @@ async function runCode(targets, source, options) {
9623
9666
  ...buildDiscoveryGlobals(allDeclaredTools, namespaces, searchDocs),
9624
9667
  ...options.allowShell ? [buildShellGlobal(platform2)] : []
9625
9668
  ];
9626
- const sandbox = await createSandbox(platform2, toolImpls, globals, timeoutMs, memoryLimitBytes);
9669
+ const { sandbox, deadline } = await createSandbox(
9670
+ platform2,
9671
+ toolImpls,
9672
+ globals,
9673
+ timeoutMs,
9674
+ memoryLimitBytes
9675
+ );
9627
9676
  try {
9628
- const result = await sandbox.execute(code2, { store });
9677
+ deadline?.start();
9678
+ const executed = await sandbox.execute(code2, { store });
9679
+ const result = deadline?.tripped && !executed.ok ? {
9680
+ ...executed,
9681
+ error: {
9682
+ kind: "timeout",
9683
+ message: `Execution timed out after ${timeoutMs} ms`
9684
+ }
9685
+ } : executed;
9629
9686
  if (result.ok) {
9630
9687
  const writes = result.storeWrites;
9631
9688
  if (Object.keys(writes.set).length > 0 || writes.delete.length > 0) {
@@ -9671,12 +9728,23 @@ async function createSandbox(platform2, tools, globals, timeoutMs, memoryLimitBy
9671
9728
  const isKernel2 = platform2.packageDir !== void 0;
9672
9729
  if (isKernel2) {
9673
9730
  const { InlineCodemodeSandbox: InlineCodemodeSandbox2 } = await Promise.resolve().then(() => (init_portable(), portable_exports));
9731
+ const { QuickJS: QuickJS2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
9732
+ hookDeadlines(QuickJS2);
9674
9733
  const wasm = await loadWasmKernel(platform2);
9675
- return new InlineCodemodeSandbox2({ tools, globals, timeoutMs, wasm, memoryLimitBytes });
9734
+ const deadline = bindDeadline(wasm, timeoutMs);
9735
+ const sandbox2 = new InlineCodemodeSandbox2({
9736
+ tools,
9737
+ globals,
9738
+ timeoutMs,
9739
+ wasm,
9740
+ memoryLimitBytes,
9741
+ interruptBudget: Number.POSITIVE_INFINITY
9742
+ });
9743
+ return { sandbox: sandbox2, deadline };
9676
9744
  }
9677
- const { CodemodeSandbox: CodemodeSandbox2, loadQuickJSWasm: loadQuickJSWasm2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
9745
+ const { CodemodeSandbox: CodemodeSandbox2, loadQuickJSWasm: loadQuickJSWasm2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports2));
9678
9746
  const wasmPath = await resolveWasmPath(platform2);
9679
- return new CodemodeSandbox2({
9747
+ const sandbox = new CodemodeSandbox2({
9680
9748
  tools,
9681
9749
  globals,
9682
9750
  timeoutMs,
@@ -9684,6 +9752,7 @@ async function createSandbox(platform2, tools, globals, timeoutMs, memoryLimitBy
9684
9752
  wasm: loadQuickJSWasm2(wasmPath),
9685
9753
  workerUrl: new URL("./codemode-worker.mjs", import.meta.url)
9686
9754
  });
9755
+ return { sandbox };
9687
9756
  }
9688
9757
  async function resolveWasmPath(platform2) {
9689
9758
  const candidates = [
@@ -12970,6 +13039,7 @@ async function discoverWithSignal(platform2, commands, childEnv, cwd) {
12970
13039
  };
12971
13040
  platform2.onSignal?.("SIGTERM", onShutdown);
12972
13041
  platform2.onSignal?.("SIGINT", onShutdown);
13042
+ platform2.onSignal?.("SIGHUP", onShutdown);
12973
13043
  for (const cmd of commands) {
12974
13044
  try {
12975
13045
  const cli = await discoverCli(platform2, cmd.path, cmd.name, childEnv, cwd, earlyAbort.signal);
@@ -13300,6 +13370,21 @@ async function runWebMcpHttp(platform2, options, getTools, callTool, serverName,
13300
13370
  const address = serveAddress(platform2, options.host, actualPort);
13301
13371
  const listenUrl = address.url;
13302
13372
  let tokenFilePath;
13373
+ let shutdownRequested = false;
13374
+ const shutdown = () => {
13375
+ if (shutdownRequested) return;
13376
+ shutdownRequested = true;
13377
+ listener.close();
13378
+ if (tokenFilePath) {
13379
+ platform2.fs.unlink?.(tokenFilePath).catch(() => {
13380
+ });
13381
+ }
13382
+ };
13383
+ if (platform2.onSignal) {
13384
+ platform2.onSignal("SIGINT", shutdown);
13385
+ platform2.onSignal("SIGTERM", shutdown);
13386
+ platform2.onSignal("SIGHUP", shutdown);
13387
+ }
13303
13388
  if (generatedBearer && resolvedBearer) {
13304
13389
  tokenFilePath = await publishBearer(
13305
13390
  platform2,
@@ -13308,31 +13393,22 @@ async function runWebMcpHttp(platform2, options, getTools, callTool, serverName,
13308
13393
  address,
13309
13394
  options.json
13310
13395
  );
13396
+ if (shutdownRequested && tokenFilePath) {
13397
+ await platform2.fs.unlink?.(tokenFilePath).catch(() => {
13398
+ });
13399
+ }
13311
13400
  } else {
13312
13401
  if (options.json) {
13313
13402
  await platform2.write(1, `${JSON.stringify(address)}
13314
13403
  `);
13315
13404
  }
13316
13405
  }
13317
- await platform2.write(2, `mcpcat serve --webmcp: listening on ${listenUrl}
13406
+ if (!shutdownRequested) {
13407
+ await platform2.write(2, `mcpcat serve --webmcp: listening on ${listenUrl}
13318
13408
  `);
13319
- if (options.onListening) {
13320
- await options.onListening(actualPort);
13321
- }
13322
- let shutdownRequested = false;
13323
- const shutdown = () => {
13324
- if (shutdownRequested) return;
13325
- shutdownRequested = true;
13326
- listener.close();
13327
- if (tokenFilePath) {
13328
- platform2.fs.unlink?.(tokenFilePath).catch(() => {
13329
- });
13409
+ if (options.onListening) {
13410
+ await options.onListening(actualPort);
13330
13411
  }
13331
- };
13332
- if (platform2.onSignal) {
13333
- platform2.onSignal("SIGINT", shutdown);
13334
- platform2.onSignal("SIGTERM", shutdown);
13335
- platform2.onSignal("SIGHUP", shutdown);
13336
13412
  }
13337
13413
  const handler = async (request) => {
13338
13414
  if (request.target !== "/mcp") {
@@ -13496,6 +13572,23 @@ async function runProxyHttp(platform2, options, proxy, resolvedBearer, generated
13496
13572
  const address = serveAddress(platform2, options.host, actualPort);
13497
13573
  const listenUrl = address.url;
13498
13574
  let tokenFilePath;
13575
+ let shutdownRequested = false;
13576
+ let proxyDone;
13577
+ const shutdown = () => {
13578
+ if (shutdownRequested) return;
13579
+ shutdownRequested = true;
13580
+ listener.close();
13581
+ proxyDone = proxy.shutdown();
13582
+ if (tokenFilePath) {
13583
+ platform2.fs.unlink?.(tokenFilePath).catch(() => {
13584
+ });
13585
+ }
13586
+ };
13587
+ if (platform2.onSignal) {
13588
+ platform2.onSignal("SIGINT", shutdown);
13589
+ platform2.onSignal("SIGTERM", shutdown);
13590
+ platform2.onSignal("SIGHUP", shutdown);
13591
+ }
13499
13592
  if (generatedBearer && resolvedBearer) {
13500
13593
  tokenFilePath = await publishBearer(
13501
13594
  platform2,
@@ -13504,32 +13597,22 @@ async function runProxyHttp(platform2, options, proxy, resolvedBearer, generated
13504
13597
  address,
13505
13598
  options.json
13506
13599
  );
13600
+ if (shutdownRequested && tokenFilePath) {
13601
+ await platform2.fs.unlink?.(tokenFilePath).catch(() => {
13602
+ });
13603
+ }
13507
13604
  } else {
13508
13605
  if (options.json) {
13509
13606
  await platform2.write(1, `${JSON.stringify(address)}
13510
13607
  `);
13511
13608
  }
13512
13609
  }
13513
- await platform2.write(2, `mcpcat serve --proxy: listening on ${listenUrl}
13610
+ if (!shutdownRequested) {
13611
+ await platform2.write(2, `mcpcat serve --proxy: listening on ${listenUrl}
13514
13612
  `);
13515
- if (options.onListening) {
13516
- await options.onListening(actualPort);
13517
- }
13518
- let shutdownRequested = false;
13519
- const shutdown = () => {
13520
- if (shutdownRequested) return;
13521
- shutdownRequested = true;
13522
- listener.close();
13523
- void proxy.shutdown();
13524
- if (tokenFilePath) {
13525
- platform2.fs.unlink?.(tokenFilePath).catch(() => {
13526
- });
13613
+ if (options.onListening) {
13614
+ await options.onListening(actualPort);
13527
13615
  }
13528
- };
13529
- if (platform2.onSignal) {
13530
- platform2.onSignal("SIGINT", shutdown);
13531
- platform2.onSignal("SIGTERM", shutdown);
13532
- platform2.onSignal("SIGHUP", shutdown);
13533
13616
  }
13534
13617
  const handler = (request) => handleProxyMcpRequest(
13535
13618
  request,
@@ -13554,6 +13637,7 @@ async function runProxyHttp(platform2, options, proxy, resolvedBearer, generated
13554
13637
  } catch {
13555
13638
  if (!shutdownRequested) throw new Error("listener closed unexpectedly");
13556
13639
  }
13640
+ await proxyDone;
13557
13641
  return 0;
13558
13642
  }
13559
13643
  async function handleProxyMcpRequest(request, proxy, serverOrigins, allowedOrigins, allowedHosts, resolvedBearer) {
@@ -13673,22 +13757,6 @@ async function runHttpServer(platform2, options, tools, call, serverName, versio
13673
13757
  const address = serveAddress(platform2, options.host, actualPort);
13674
13758
  const listenUrl = address.url;
13675
13759
  let tokenFilePath;
13676
- if (generatedBearer && resolvedBearer) {
13677
- tokenFilePath = await publishBearer(
13678
- platform2,
13679
- resolvedBearer,
13680
- actualPort,
13681
- address,
13682
- options.json
13683
- );
13684
- } else {
13685
- if (options.json) {
13686
- await platform2.write(1, `${JSON.stringify(address)}
13687
- `);
13688
- }
13689
- }
13690
- await platform2.write(2, `mcpcat serve: listening on ${listenUrl}
13691
- `);
13692
13760
  let shutdownRequested = false;
13693
13761
  let inflightDone;
13694
13762
  const shutdown = () => {
@@ -13706,6 +13774,28 @@ async function runHttpServer(platform2, options, tools, call, serverName, versio
13706
13774
  platform2.onSignal("SIGTERM", shutdown);
13707
13775
  platform2.onSignal("SIGHUP", shutdown);
13708
13776
  }
13777
+ if (generatedBearer && resolvedBearer) {
13778
+ tokenFilePath = await publishBearer(
13779
+ platform2,
13780
+ resolvedBearer,
13781
+ actualPort,
13782
+ address,
13783
+ options.json
13784
+ );
13785
+ if (shutdownRequested && tokenFilePath) {
13786
+ await platform2.fs.unlink?.(tokenFilePath).catch(() => {
13787
+ });
13788
+ }
13789
+ } else {
13790
+ if (options.json) {
13791
+ await platform2.write(1, `${JSON.stringify(address)}
13792
+ `);
13793
+ }
13794
+ }
13795
+ if (!shutdownRequested) {
13796
+ await platform2.write(2, `mcpcat serve: listening on ${listenUrl}
13797
+ `);
13798
+ }
13709
13799
  const handler = (request) => handleMcpRequest(
13710
13800
  request,
13711
13801
  tools,
@@ -16856,5 +16946,5 @@ try {
16856
16946
  });
16857
16947
  } catch {
16858
16948
  }
16859
- var code = await run(platform, "0.15.6", args);
16949
+ var code = await run(platform, "0.15.7", args);
16860
16950
  process.exit(code);
@@ -1475,6 +1475,16 @@ var init_version = __esm({
1475
1475
  });
1476
1476
 
1477
1477
  // node_modules/quickjs-wasi/dist/index.js
1478
+ var dist_exports = {};
1479
+ __export(dist_exports, {
1480
+ CompileFlags: () => CompileFlags,
1481
+ EvalFlags: () => EvalFlags,
1482
+ Intrinsics: () => Intrinsics,
1483
+ JSException: () => JSException,
1484
+ JSValueHandle: () => JSValueHandle,
1485
+ MAX_STACK_SIZE: () => MAX_STACK_SIZE,
1486
+ QuickJS: () => QuickJS
1487
+ });
1478
1488
  function stringKeyNeedsValuePath(key) {
1479
1489
  return key.includes("\0") || LONE_SURROGATE_RE.test(key);
1480
1490
  }
@@ -4986,8 +4996,8 @@ SOURCE: /[\s\S]+/
4986
4996
  });
4987
4997
 
4988
4998
  // node_modules/@earendil-works/pi-codemode/dist/index.js
4989
- var dist_exports = {};
4990
- __export(dist_exports, {
4999
+ var dist_exports2 = {};
5000
+ __export(dist_exports2, {
4991
5001
  CODEMODE_OPTIONS_PREFIX: () => CODEMODE_OPTIONS_PREFIX,
4992
5002
  CODEMODE_SOURCE_GRAMMAR: () => CODEMODE_SOURCE_GRAMMAR,
4993
5003
  CodemodeSandbox: () => CodemodeSandbox,
@@ -8988,7 +8998,7 @@ function toolDeclaration(tool) {
8988
8998
  };
8989
8999
  }
8990
9000
  async function runDescribeTs(platform2, targets, budget) {
8991
- const { renderDeclarations: renderDeclarations2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
9001
+ const { renderDeclarations: renderDeclarations2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports2));
8992
9002
  const allTools = [];
8993
9003
  for (const target of targets) {
8994
9004
  const tools = await target.conn.listTools();
@@ -9059,6 +9069,39 @@ async function runGrep(platform2, pattern, targets, options) {
9059
9069
  // src/codemode/run.ts
9060
9070
  init_dist2();
9061
9071
  init_source();
9072
+
9073
+ // src/codemode/deadline.ts
9074
+ var expiries = /* @__PURE__ */ new WeakMap();
9075
+ var hooked = /* @__PURE__ */ new WeakSet();
9076
+ function hookDeadlines(quickjs) {
9077
+ if (hooked.has(quickjs)) return;
9078
+ hooked.add(quickjs);
9079
+ const create = quickjs.create.bind(quickjs);
9080
+ quickjs.create = (options) => {
9081
+ const expired = options.wasm ? expiries.get(options.wasm) : void 0;
9082
+ const inner = options.interruptHandler;
9083
+ if (!expired || !inner) return create(options);
9084
+ return create({ ...options, interruptHandler: () => expired() || inner() });
9085
+ };
9086
+ }
9087
+ function bindDeadline(wasm, timeoutMs, now = Date.now) {
9088
+ let endsAt = Number.POSITIVE_INFINITY;
9089
+ let tripped = false;
9090
+ expiries.set(wasm, () => {
9091
+ if (!tripped && now() >= endsAt) tripped = true;
9092
+ return tripped;
9093
+ });
9094
+ return {
9095
+ start() {
9096
+ endsAt = now() + timeoutMs;
9097
+ },
9098
+ get tripped() {
9099
+ return tripped;
9100
+ }
9101
+ };
9102
+ }
9103
+
9104
+ // src/codemode/run.ts
9062
9105
  async function loadStore(platform2, stateDir2) {
9063
9106
  const storePath = `${stateDir2}/codemode-store.json`;
9064
9107
  try {
@@ -9244,9 +9287,23 @@ async function runCode(targets, source, options) {
9244
9287
  ...buildDiscoveryGlobals(allDeclaredTools, namespaces, searchDocs),
9245
9288
  ...options.allowShell ? [buildShellGlobal(platform2)] : []
9246
9289
  ];
9247
- const sandbox = await createSandbox(platform2, toolImpls, globals, timeoutMs, memoryLimitBytes);
9290
+ const { sandbox, deadline } = await createSandbox(
9291
+ platform2,
9292
+ toolImpls,
9293
+ globals,
9294
+ timeoutMs,
9295
+ memoryLimitBytes
9296
+ );
9248
9297
  try {
9249
- const result = await sandbox.execute(code, { store });
9298
+ deadline?.start();
9299
+ const executed = await sandbox.execute(code, { store });
9300
+ const result = deadline?.tripped && !executed.ok ? {
9301
+ ...executed,
9302
+ error: {
9303
+ kind: "timeout",
9304
+ message: `Execution timed out after ${timeoutMs} ms`
9305
+ }
9306
+ } : executed;
9250
9307
  if (result.ok) {
9251
9308
  const writes = result.storeWrites;
9252
9309
  if (Object.keys(writes.set).length > 0 || writes.delete.length > 0) {
@@ -9292,12 +9349,23 @@ async function createSandbox(platform2, tools, globals, timeoutMs, memoryLimitBy
9292
9349
  const isKernel2 = platform2.packageDir !== void 0;
9293
9350
  if (isKernel2) {
9294
9351
  const { InlineCodemodeSandbox: InlineCodemodeSandbox2 } = await Promise.resolve().then(() => (init_portable(), portable_exports));
9352
+ const { QuickJS: QuickJS2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
9353
+ hookDeadlines(QuickJS2);
9295
9354
  const wasm = await loadWasmKernel(platform2);
9296
- return new InlineCodemodeSandbox2({ tools, globals, timeoutMs, wasm, memoryLimitBytes });
9355
+ const deadline = bindDeadline(wasm, timeoutMs);
9356
+ const sandbox2 = new InlineCodemodeSandbox2({
9357
+ tools,
9358
+ globals,
9359
+ timeoutMs,
9360
+ wasm,
9361
+ memoryLimitBytes,
9362
+ interruptBudget: Number.POSITIVE_INFINITY
9363
+ });
9364
+ return { sandbox: sandbox2, deadline };
9297
9365
  }
9298
- const { CodemodeSandbox: CodemodeSandbox2, loadQuickJSWasm: loadQuickJSWasm2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
9366
+ const { CodemodeSandbox: CodemodeSandbox2, loadQuickJSWasm: loadQuickJSWasm2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports2));
9299
9367
  const wasmPath = await resolveWasmPath(platform2);
9300
- return new CodemodeSandbox2({
9368
+ const sandbox = new CodemodeSandbox2({
9301
9369
  tools,
9302
9370
  globals,
9303
9371
  timeoutMs,
@@ -9305,6 +9373,7 @@ async function createSandbox(platform2, tools, globals, timeoutMs, memoryLimitBy
9305
9373
  wasm: loadQuickJSWasm2(wasmPath),
9306
9374
  workerUrl: new URL("./codemode-worker.mjs", import.meta.url)
9307
9375
  });
9376
+ return { sandbox };
9308
9377
  }
9309
9378
  async function resolveWasmPath(platform2) {
9310
9379
  const candidates = [
@@ -12591,6 +12660,7 @@ async function discoverWithSignal(platform2, commands, childEnv, cwd) {
12591
12660
  };
12592
12661
  platform2.onSignal?.("SIGTERM", onShutdown);
12593
12662
  platform2.onSignal?.("SIGINT", onShutdown);
12663
+ platform2.onSignal?.("SIGHUP", onShutdown);
12594
12664
  for (const cmd of commands) {
12595
12665
  try {
12596
12666
  const cli = await discoverCli(platform2, cmd.path, cmd.name, childEnv, cwd, earlyAbort.signal);
@@ -12921,6 +12991,21 @@ async function runWebMcpHttp(platform2, options, getTools, callTool, serverName,
12921
12991
  const address = serveAddress(platform2, options.host, actualPort);
12922
12992
  const listenUrl = address.url;
12923
12993
  let tokenFilePath;
12994
+ let shutdownRequested = false;
12995
+ const shutdown = () => {
12996
+ if (shutdownRequested) return;
12997
+ shutdownRequested = true;
12998
+ listener.close();
12999
+ if (tokenFilePath) {
13000
+ platform2.fs.unlink?.(tokenFilePath).catch(() => {
13001
+ });
13002
+ }
13003
+ };
13004
+ if (platform2.onSignal) {
13005
+ platform2.onSignal("SIGINT", shutdown);
13006
+ platform2.onSignal("SIGTERM", shutdown);
13007
+ platform2.onSignal("SIGHUP", shutdown);
13008
+ }
12924
13009
  if (generatedBearer && resolvedBearer) {
12925
13010
  tokenFilePath = await publishBearer(
12926
13011
  platform2,
@@ -12929,31 +13014,22 @@ async function runWebMcpHttp(platform2, options, getTools, callTool, serverName,
12929
13014
  address,
12930
13015
  options.json
12931
13016
  );
13017
+ if (shutdownRequested && tokenFilePath) {
13018
+ await platform2.fs.unlink?.(tokenFilePath).catch(() => {
13019
+ });
13020
+ }
12932
13021
  } else {
12933
13022
  if (options.json) {
12934
13023
  await platform2.write(1, `${JSON.stringify(address)}
12935
13024
  `);
12936
13025
  }
12937
13026
  }
12938
- await platform2.write(2, `mcpcat serve --webmcp: listening on ${listenUrl}
13027
+ if (!shutdownRequested) {
13028
+ await platform2.write(2, `mcpcat serve --webmcp: listening on ${listenUrl}
12939
13029
  `);
12940
- if (options.onListening) {
12941
- await options.onListening(actualPort);
12942
- }
12943
- let shutdownRequested = false;
12944
- const shutdown = () => {
12945
- if (shutdownRequested) return;
12946
- shutdownRequested = true;
12947
- listener.close();
12948
- if (tokenFilePath) {
12949
- platform2.fs.unlink?.(tokenFilePath).catch(() => {
12950
- });
13030
+ if (options.onListening) {
13031
+ await options.onListening(actualPort);
12951
13032
  }
12952
- };
12953
- if (platform2.onSignal) {
12954
- platform2.onSignal("SIGINT", shutdown);
12955
- platform2.onSignal("SIGTERM", shutdown);
12956
- platform2.onSignal("SIGHUP", shutdown);
12957
13033
  }
12958
13034
  const handler = async (request) => {
12959
13035
  if (request.target !== "/mcp") {
@@ -13117,6 +13193,23 @@ async function runProxyHttp(platform2, options, proxy, resolvedBearer, generated
13117
13193
  const address = serveAddress(platform2, options.host, actualPort);
13118
13194
  const listenUrl = address.url;
13119
13195
  let tokenFilePath;
13196
+ let shutdownRequested = false;
13197
+ let proxyDone;
13198
+ const shutdown = () => {
13199
+ if (shutdownRequested) return;
13200
+ shutdownRequested = true;
13201
+ listener.close();
13202
+ proxyDone = proxy.shutdown();
13203
+ if (tokenFilePath) {
13204
+ platform2.fs.unlink?.(tokenFilePath).catch(() => {
13205
+ });
13206
+ }
13207
+ };
13208
+ if (platform2.onSignal) {
13209
+ platform2.onSignal("SIGINT", shutdown);
13210
+ platform2.onSignal("SIGTERM", shutdown);
13211
+ platform2.onSignal("SIGHUP", shutdown);
13212
+ }
13120
13213
  if (generatedBearer && resolvedBearer) {
13121
13214
  tokenFilePath = await publishBearer(
13122
13215
  platform2,
@@ -13125,32 +13218,22 @@ async function runProxyHttp(platform2, options, proxy, resolvedBearer, generated
13125
13218
  address,
13126
13219
  options.json
13127
13220
  );
13221
+ if (shutdownRequested && tokenFilePath) {
13222
+ await platform2.fs.unlink?.(tokenFilePath).catch(() => {
13223
+ });
13224
+ }
13128
13225
  } else {
13129
13226
  if (options.json) {
13130
13227
  await platform2.write(1, `${JSON.stringify(address)}
13131
13228
  `);
13132
13229
  }
13133
13230
  }
13134
- await platform2.write(2, `mcpcat serve --proxy: listening on ${listenUrl}
13231
+ if (!shutdownRequested) {
13232
+ await platform2.write(2, `mcpcat serve --proxy: listening on ${listenUrl}
13135
13233
  `);
13136
- if (options.onListening) {
13137
- await options.onListening(actualPort);
13138
- }
13139
- let shutdownRequested = false;
13140
- const shutdown = () => {
13141
- if (shutdownRequested) return;
13142
- shutdownRequested = true;
13143
- listener.close();
13144
- void proxy.shutdown();
13145
- if (tokenFilePath) {
13146
- platform2.fs.unlink?.(tokenFilePath).catch(() => {
13147
- });
13234
+ if (options.onListening) {
13235
+ await options.onListening(actualPort);
13148
13236
  }
13149
- };
13150
- if (platform2.onSignal) {
13151
- platform2.onSignal("SIGINT", shutdown);
13152
- platform2.onSignal("SIGTERM", shutdown);
13153
- platform2.onSignal("SIGHUP", shutdown);
13154
13237
  }
13155
13238
  const handler = (request) => handleProxyMcpRequest(
13156
13239
  request,
@@ -13175,6 +13258,7 @@ async function runProxyHttp(platform2, options, proxy, resolvedBearer, generated
13175
13258
  } catch {
13176
13259
  if (!shutdownRequested) throw new Error("listener closed unexpectedly");
13177
13260
  }
13261
+ await proxyDone;
13178
13262
  return 0;
13179
13263
  }
13180
13264
  async function handleProxyMcpRequest(request, proxy, serverOrigins, allowedOrigins, allowedHosts, resolvedBearer) {
@@ -13294,22 +13378,6 @@ async function runHttpServer(platform2, options, tools, call, serverName, versio
13294
13378
  const address = serveAddress(platform2, options.host, actualPort);
13295
13379
  const listenUrl = address.url;
13296
13380
  let tokenFilePath;
13297
- if (generatedBearer && resolvedBearer) {
13298
- tokenFilePath = await publishBearer(
13299
- platform2,
13300
- resolvedBearer,
13301
- actualPort,
13302
- address,
13303
- options.json
13304
- );
13305
- } else {
13306
- if (options.json) {
13307
- await platform2.write(1, `${JSON.stringify(address)}
13308
- `);
13309
- }
13310
- }
13311
- await platform2.write(2, `mcpcat serve: listening on ${listenUrl}
13312
- `);
13313
13381
  let shutdownRequested = false;
13314
13382
  let inflightDone;
13315
13383
  const shutdown = () => {
@@ -13327,6 +13395,28 @@ async function runHttpServer(platform2, options, tools, call, serverName, versio
13327
13395
  platform2.onSignal("SIGTERM", shutdown);
13328
13396
  platform2.onSignal("SIGHUP", shutdown);
13329
13397
  }
13398
+ if (generatedBearer && resolvedBearer) {
13399
+ tokenFilePath = await publishBearer(
13400
+ platform2,
13401
+ resolvedBearer,
13402
+ actualPort,
13403
+ address,
13404
+ options.json
13405
+ );
13406
+ if (shutdownRequested && tokenFilePath) {
13407
+ await platform2.fs.unlink?.(tokenFilePath).catch(() => {
13408
+ });
13409
+ }
13410
+ } else {
13411
+ if (options.json) {
13412
+ await platform2.write(1, `${JSON.stringify(address)}
13413
+ `);
13414
+ }
13415
+ }
13416
+ if (!shutdownRequested) {
13417
+ await platform2.write(2, `mcpcat serve: listening on ${listenUrl}
13418
+ `);
13419
+ }
13330
13420
  const handler = (request) => handleMcpRequest(
13331
13421
  request,
13332
13422
  tools,
@@ -16577,7 +16667,7 @@ async function main(ctx) {
16577
16667
  packageDir: "/node_modules/@ai-ecoverse/mcpcat"
16578
16668
  });
16579
16669
  const args = ctx.argv.slice(1);
16580
- return run(platform2, "0.15.6", args);
16670
+ return run(platform2, "0.15.7", args);
16581
16671
  }
16582
16672
  export {
16583
16673
  main as default
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/mcpcat",
3
- "version": "0.15.6",
3
+ "version": "0.15.7",
4
4
  "description": "A curl for the Model Context Protocol",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -56,8 +56,9 @@
56
56
  "trust:dry": "npx fledgling sync --dry-run -y --skip-publish"
57
57
  },
58
58
  "devDependencies": {
59
+ "@ai-ecoverse/slicc-bios": "1.0.1",
59
60
  "@ai-ecoverse/slicc-kernel": "1.94.1",
60
- "@ai-ecoverse/slicc-shared-web": "1.17.0",
61
+ "@ai-ecoverse/slicc-shared-web": "1.19.0",
61
62
  "@biomejs/biome": "2.5.15",
62
63
  "@earendil-works/pi-codemode": "1.2.0",
63
64
  "@earendil-works/pi-mcp": "1.2.0",