@mcp-use/cli 2.15.4 → 2.16.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -5527,7 +5527,7 @@ program.command("dev").description("Run development server with auto-reload and
5527
5527
  "--host <host>",
5528
5528
  "Server host (use 0.0.0.0 to listen on all interfaces)",
5529
5529
  "0.0.0.0"
5530
- ).option("--no-open", "Do not auto-open inspector").option("--no-hmr", "Disable hot module reloading (use tsx watch instead)").action(async (options) => {
5530
+ ).option("--no-open", "Do not auto-open inspector").option("--no-hmr", "Disable hot module reloading (use tsx watch instead)").option("--tunnel", "Expose server through a tunnel").action(async (options) => {
5531
5531
  try {
5532
5532
  const projectPath = import_node_path8.default.resolve(options.path);
5533
5533
  let port = parseInt(options.port, 10);
@@ -5541,11 +5541,64 @@ program.command("dev").description("Run development server with auto-reload and
5541
5541
  port = availablePort;
5542
5542
  }
5543
5543
  const serverFile = await findServerFile(projectPath);
5544
+ let tunnelProcess = void 0;
5545
+ let tunnelSubdomain = void 0;
5546
+ let tunnelUrl = void 0;
5547
+ if (options.tunnel) {
5548
+ try {
5549
+ const manifestPath = import_node_path8.default.join(projectPath, "dist", "mcp-use.json");
5550
+ let existingSubdomain;
5551
+ try {
5552
+ const manifestContent = await (0, import_promises7.readFile)(manifestPath, "utf-8");
5553
+ const manifest = JSON.parse(manifestContent);
5554
+ existingSubdomain = manifest.tunnel?.subdomain;
5555
+ if (existingSubdomain) {
5556
+ console.log(
5557
+ source_default.gray(`Found existing subdomain: ${existingSubdomain}`)
5558
+ );
5559
+ }
5560
+ } catch {
5561
+ }
5562
+ const tunnelInfo = await startTunnel(port, existingSubdomain);
5563
+ tunnelUrl = tunnelInfo.url;
5564
+ tunnelProcess = tunnelInfo.process;
5565
+ tunnelSubdomain = tunnelInfo.subdomain;
5566
+ try {
5567
+ let manifest = {};
5568
+ try {
5569
+ const manifestContent = await (0, import_promises7.readFile)(manifestPath, "utf-8");
5570
+ manifest = JSON.parse(manifestContent);
5571
+ } catch {
5572
+ }
5573
+ if (!manifest.tunnel) {
5574
+ manifest.tunnel = {};
5575
+ }
5576
+ manifest.tunnel.subdomain = tunnelSubdomain;
5577
+ await (0, import_promises7.mkdir)(import_node_path8.default.dirname(manifestPath), { recursive: true });
5578
+ await (0, import_promises7.writeFile)(
5579
+ manifestPath,
5580
+ JSON.stringify(manifest, null, 2),
5581
+ "utf-8"
5582
+ );
5583
+ } catch (error) {
5584
+ console.warn(
5585
+ source_default.yellow(
5586
+ `\u26A0\uFE0F Failed to save subdomain to mcp-use.json: ${error instanceof Error ? error.message : "Unknown error"}`
5587
+ )
5588
+ );
5589
+ }
5590
+ } catch (error) {
5591
+ console.error(source_default.red("Failed to start tunnel:"), error);
5592
+ process.exit(1);
5593
+ }
5594
+ }
5544
5595
  const mcpUrl = `http://${host}:${port}`;
5545
5596
  process.env.PORT = String(port);
5546
5597
  process.env.HOST = host;
5547
5598
  process.env.NODE_ENV = "development";
5548
- if (!process.env.MCP_URL) {
5599
+ if (tunnelUrl) {
5600
+ process.env.MCP_URL = tunnelUrl;
5601
+ } else if (!process.env.MCP_URL) {
5549
5602
  process.env.MCP_URL = mcpUrl;
5550
5603
  }
5551
5604
  if (!useHmr) {
@@ -5603,19 +5656,40 @@ program.command("dev").description("Run development server with auto-reload and
5603
5656
  );
5604
5657
  console.log(source_default.whiteBright(`Network: http://${host}:${port}`));
5605
5658
  console.log(source_default.whiteBright(`MCP: ${mcpEndpoint}`));
5659
+ if (tunnelUrl) {
5660
+ console.log(source_default.whiteBright(`Tunnel: ${tunnelUrl}/mcp`));
5661
+ }
5606
5662
  console.log(source_default.whiteBright(`Inspector: ${inspectorUrl}
5607
5663
  `));
5608
5664
  await open_default(inspectorUrl);
5609
5665
  }
5610
5666
  }
5611
- const cleanup2 = () => {
5667
+ let noHmrCleanupInProgress = false;
5668
+ const cleanup2 = async () => {
5669
+ if (noHmrCleanupInProgress) return;
5670
+ noHmrCleanupInProgress = true;
5612
5671
  console.log(source_default.gray("\n\nShutting down..."));
5672
+ if (tunnelProcess && typeof tunnelProcess.markShutdown === "function") {
5673
+ tunnelProcess.markShutdown();
5674
+ }
5675
+ if (tunnelSubdomain) {
5676
+ try {
5677
+ const apiBase = process.env.MCP_USE_API || "https://local.mcp-use.run";
5678
+ await fetch(`${apiBase}/api/tunnels/${tunnelSubdomain}`, {
5679
+ method: "DELETE"
5680
+ });
5681
+ } catch {
5682
+ }
5683
+ }
5613
5684
  processes.forEach((proc) => {
5614
5685
  if (proc && typeof proc.kill === "function") {
5615
5686
  proc.kill("SIGINT");
5616
5687
  }
5617
5688
  });
5618
- setTimeout(() => process.exit(0), 1e3);
5689
+ if (tunnelProcess && typeof tunnelProcess.kill === "function") {
5690
+ tunnelProcess.kill("SIGINT");
5691
+ }
5692
+ setTimeout(() => process.exit(0), 2e3);
5619
5693
  };
5620
5694
  process.on("SIGINT", cleanup2);
5621
5695
  process.on("SIGTERM", cleanup2);
@@ -5721,6 +5795,9 @@ program.command("dev").description("Run development server with auto-reload and
5721
5795
  );
5722
5796
  console.log(source_default.whiteBright(`Network: http://${host}:${port}`));
5723
5797
  console.log(source_default.whiteBright(`MCP: ${mcpEndpoint}`));
5798
+ if (tunnelUrl) {
5799
+ console.log(source_default.whiteBright(`Tunnel: ${tunnelUrl}/mcp`));
5800
+ }
5724
5801
  console.log(source_default.whiteBright(`Inspector: ${inspectorUrl}`));
5725
5802
  console.log(source_default.gray(`Watching for changes...
5726
5803
  `));
@@ -5742,6 +5819,9 @@ program.command("dev").description("Run development server with auto-reload and
5742
5819
  console.log(source_default.green.bold(`\u2713 Server ready`));
5743
5820
  console.log(source_default.whiteBright(`Local: http://${host}:${port}`));
5744
5821
  console.log(source_default.whiteBright(`MCP: ${mcpEndpoint}`));
5822
+ if (tunnelUrl) {
5823
+ console.log(source_default.whiteBright(`Tunnel: ${tunnelUrl}/mcp`));
5824
+ }
5745
5825
  console.log(source_default.gray(`Watching for changes...
5746
5826
  `));
5747
5827
  }
@@ -5865,10 +5945,30 @@ program.command("dev").description("Run development server with auto-reload and
5865
5945
  isReloading = false;
5866
5946
  }, 100);
5867
5947
  });
5868
- const cleanup = () => {
5948
+ let hmrCleanupInProgress = false;
5949
+ const cleanup = async () => {
5950
+ if (hmrCleanupInProgress) return;
5951
+ hmrCleanupInProgress = true;
5869
5952
  console.log(source_default.gray("\n\nShutting down..."));
5870
5953
  watcher.close();
5871
- process.exit(0);
5954
+ if (tunnelProcess && typeof tunnelProcess.markShutdown === "function") {
5955
+ tunnelProcess.markShutdown();
5956
+ }
5957
+ if (tunnelSubdomain) {
5958
+ try {
5959
+ const apiBase = process.env.MCP_USE_API || "https://local.mcp-use.run";
5960
+ await fetch(`${apiBase}/api/tunnels/${tunnelSubdomain}`, {
5961
+ method: "DELETE"
5962
+ });
5963
+ } catch {
5964
+ }
5965
+ }
5966
+ if (tunnelProcess && typeof tunnelProcess.kill === "function") {
5967
+ tunnelProcess.kill("SIGINT");
5968
+ setTimeout(() => process.exit(0), 2e3);
5969
+ } else {
5970
+ process.exit(0);
5971
+ }
5872
5972
  };
5873
5973
  process.on("SIGINT", cleanup);
5874
5974
  process.on("SIGTERM", cleanup);