@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.js CHANGED
@@ -5509,7 +5509,7 @@ program.command("dev").description("Run development server with auto-reload and
5509
5509
  "--host <host>",
5510
5510
  "Server host (use 0.0.0.0 to listen on all interfaces)",
5511
5511
  "0.0.0.0"
5512
- ).option("--no-open", "Do not auto-open inspector").option("--no-hmr", "Disable hot module reloading (use tsx watch instead)").action(async (options) => {
5512
+ ).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) => {
5513
5513
  try {
5514
5514
  const projectPath = path7.resolve(options.path);
5515
5515
  let port = parseInt(options.port, 10);
@@ -5523,11 +5523,64 @@ program.command("dev").description("Run development server with auto-reload and
5523
5523
  port = availablePort;
5524
5524
  }
5525
5525
  const serverFile = await findServerFile(projectPath);
5526
+ let tunnelProcess = void 0;
5527
+ let tunnelSubdomain = void 0;
5528
+ let tunnelUrl = void 0;
5529
+ if (options.tunnel) {
5530
+ try {
5531
+ const manifestPath = path7.join(projectPath, "dist", "mcp-use.json");
5532
+ let existingSubdomain;
5533
+ try {
5534
+ const manifestContent = await readFile3(manifestPath, "utf-8");
5535
+ const manifest = JSON.parse(manifestContent);
5536
+ existingSubdomain = manifest.tunnel?.subdomain;
5537
+ if (existingSubdomain) {
5538
+ console.log(
5539
+ source_default.gray(`Found existing subdomain: ${existingSubdomain}`)
5540
+ );
5541
+ }
5542
+ } catch {
5543
+ }
5544
+ const tunnelInfo = await startTunnel(port, existingSubdomain);
5545
+ tunnelUrl = tunnelInfo.url;
5546
+ tunnelProcess = tunnelInfo.process;
5547
+ tunnelSubdomain = tunnelInfo.subdomain;
5548
+ try {
5549
+ let manifest = {};
5550
+ try {
5551
+ const manifestContent = await readFile3(manifestPath, "utf-8");
5552
+ manifest = JSON.parse(manifestContent);
5553
+ } catch {
5554
+ }
5555
+ if (!manifest.tunnel) {
5556
+ manifest.tunnel = {};
5557
+ }
5558
+ manifest.tunnel.subdomain = tunnelSubdomain;
5559
+ await mkdir3(path7.dirname(manifestPath), { recursive: true });
5560
+ await writeFile3(
5561
+ manifestPath,
5562
+ JSON.stringify(manifest, null, 2),
5563
+ "utf-8"
5564
+ );
5565
+ } catch (error) {
5566
+ console.warn(
5567
+ source_default.yellow(
5568
+ `\u26A0\uFE0F Failed to save subdomain to mcp-use.json: ${error instanceof Error ? error.message : "Unknown error"}`
5569
+ )
5570
+ );
5571
+ }
5572
+ } catch (error) {
5573
+ console.error(source_default.red("Failed to start tunnel:"), error);
5574
+ process.exit(1);
5575
+ }
5576
+ }
5526
5577
  const mcpUrl = `http://${host}:${port}`;
5527
5578
  process.env.PORT = String(port);
5528
5579
  process.env.HOST = host;
5529
5580
  process.env.NODE_ENV = "development";
5530
- if (!process.env.MCP_URL) {
5581
+ if (tunnelUrl) {
5582
+ process.env.MCP_URL = tunnelUrl;
5583
+ } else if (!process.env.MCP_URL) {
5531
5584
  process.env.MCP_URL = mcpUrl;
5532
5585
  }
5533
5586
  if (!useHmr) {
@@ -5585,19 +5638,40 @@ program.command("dev").description("Run development server with auto-reload and
5585
5638
  );
5586
5639
  console.log(source_default.whiteBright(`Network: http://${host}:${port}`));
5587
5640
  console.log(source_default.whiteBright(`MCP: ${mcpEndpoint}`));
5641
+ if (tunnelUrl) {
5642
+ console.log(source_default.whiteBright(`Tunnel: ${tunnelUrl}/mcp`));
5643
+ }
5588
5644
  console.log(source_default.whiteBright(`Inspector: ${inspectorUrl}
5589
5645
  `));
5590
5646
  await open_default(inspectorUrl);
5591
5647
  }
5592
5648
  }
5593
- const cleanup2 = () => {
5649
+ let noHmrCleanupInProgress = false;
5650
+ const cleanup2 = async () => {
5651
+ if (noHmrCleanupInProgress) return;
5652
+ noHmrCleanupInProgress = true;
5594
5653
  console.log(source_default.gray("\n\nShutting down..."));
5654
+ if (tunnelProcess && typeof tunnelProcess.markShutdown === "function") {
5655
+ tunnelProcess.markShutdown();
5656
+ }
5657
+ if (tunnelSubdomain) {
5658
+ try {
5659
+ const apiBase = process.env.MCP_USE_API || "https://local.mcp-use.run";
5660
+ await fetch(`${apiBase}/api/tunnels/${tunnelSubdomain}`, {
5661
+ method: "DELETE"
5662
+ });
5663
+ } catch {
5664
+ }
5665
+ }
5595
5666
  processes.forEach((proc) => {
5596
5667
  if (proc && typeof proc.kill === "function") {
5597
5668
  proc.kill("SIGINT");
5598
5669
  }
5599
5670
  });
5600
- setTimeout(() => process.exit(0), 1e3);
5671
+ if (tunnelProcess && typeof tunnelProcess.kill === "function") {
5672
+ tunnelProcess.kill("SIGINT");
5673
+ }
5674
+ setTimeout(() => process.exit(0), 2e3);
5601
5675
  };
5602
5676
  process.on("SIGINT", cleanup2);
5603
5677
  process.on("SIGTERM", cleanup2);
@@ -5703,6 +5777,9 @@ program.command("dev").description("Run development server with auto-reload and
5703
5777
  );
5704
5778
  console.log(source_default.whiteBright(`Network: http://${host}:${port}`));
5705
5779
  console.log(source_default.whiteBright(`MCP: ${mcpEndpoint}`));
5780
+ if (tunnelUrl) {
5781
+ console.log(source_default.whiteBright(`Tunnel: ${tunnelUrl}/mcp`));
5782
+ }
5706
5783
  console.log(source_default.whiteBright(`Inspector: ${inspectorUrl}`));
5707
5784
  console.log(source_default.gray(`Watching for changes...
5708
5785
  `));
@@ -5724,6 +5801,9 @@ program.command("dev").description("Run development server with auto-reload and
5724
5801
  console.log(source_default.green.bold(`\u2713 Server ready`));
5725
5802
  console.log(source_default.whiteBright(`Local: http://${host}:${port}`));
5726
5803
  console.log(source_default.whiteBright(`MCP: ${mcpEndpoint}`));
5804
+ if (tunnelUrl) {
5805
+ console.log(source_default.whiteBright(`Tunnel: ${tunnelUrl}/mcp`));
5806
+ }
5727
5807
  console.log(source_default.gray(`Watching for changes...
5728
5808
  `));
5729
5809
  }
@@ -5847,10 +5927,30 @@ program.command("dev").description("Run development server with auto-reload and
5847
5927
  isReloading = false;
5848
5928
  }, 100);
5849
5929
  });
5850
- const cleanup = () => {
5930
+ let hmrCleanupInProgress = false;
5931
+ const cleanup = async () => {
5932
+ if (hmrCleanupInProgress) return;
5933
+ hmrCleanupInProgress = true;
5851
5934
  console.log(source_default.gray("\n\nShutting down..."));
5852
5935
  watcher.close();
5853
- process.exit(0);
5936
+ if (tunnelProcess && typeof tunnelProcess.markShutdown === "function") {
5937
+ tunnelProcess.markShutdown();
5938
+ }
5939
+ if (tunnelSubdomain) {
5940
+ try {
5941
+ const apiBase = process.env.MCP_USE_API || "https://local.mcp-use.run";
5942
+ await fetch(`${apiBase}/api/tunnels/${tunnelSubdomain}`, {
5943
+ method: "DELETE"
5944
+ });
5945
+ } catch {
5946
+ }
5947
+ }
5948
+ if (tunnelProcess && typeof tunnelProcess.kill === "function") {
5949
+ tunnelProcess.kill("SIGINT");
5950
+ setTimeout(() => process.exit(0), 2e3);
5951
+ } else {
5952
+ process.exit(0);
5953
+ }
5854
5954
  };
5855
5955
  process.on("SIGINT", cleanup);
5856
5956
  process.on("SIGTERM", cleanup);