mcp-proxy 6.2.0 → 6.3.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/README.md CHANGED
@@ -60,6 +60,31 @@ options:
60
60
  - `--sslCa`: Filename to override the trusted CA certificates
61
61
  - `--sslCert`: Cert chains filename in PEM format
62
62
  - `--sslKey`: Private keys filename in PEM format
63
+ - `--tunnel`: Expose the proxy via a public tunnel (see [Public Tunnel](#public-tunnel))
64
+ - `--tunnelSubdomain`: Request a specific subdomain for the tunnel (availability not guaranteed)
65
+
66
+ ### Public Tunnel
67
+
68
+ MCP Proxy can expose your local server to the public internet using a tunnel service. This is useful for testing webhooks, sharing your development server, or accessing your MCP server from anywhere.
69
+
70
+ ```bash
71
+ # Expose your MCP server via a public tunnel
72
+ npx mcp-proxy --port 8080 --tunnel -- tsx server.js
73
+
74
+ # Request a specific subdomain
75
+ npx mcp-proxy --port 8080 --tunnel --tunnelSubdomain myapp -- tsx server.js
76
+ ```
77
+
78
+ When the tunnel is established, you'll see a message like:
79
+
80
+ ```
81
+ tunnel established at https://abcdefghij.tunnel.gla.ma
82
+ ```
83
+
84
+ > [!NOTE]
85
+ > The requested subdomain may not be available. The actual URL will be displayed when the tunnel is established.
86
+
87
+ This feature is powered by [pipenet](https://github.com/AugmentHQ/pipenet) and sponsored by [glama.ai](https://glama.ai). For more information, see the [pipenet announcement](https://glama.ai/blog/2026-01-19-pipenet).
63
88
 
64
89
  ### Stateless Mode
65
90
 
@@ -6,6 +6,7 @@ import { format, inspect } from "util";
6
6
  import { readFileSync, readdirSync, statSync, writeFile } from "fs";
7
7
  import { setTimeout as setTimeout$1 } from "node:timers";
8
8
  import util from "node:util";
9
+ import { pipenet } from "pipenet";
9
10
  import { notStrictEqual, strictEqual } from "assert";
10
11
  import { fileURLToPath } from "url";
11
12
  import { readFileSync as readFileSync$1, readdirSync as readdirSync$1 } from "node:fs";
@@ -5095,6 +5096,15 @@ const argv = await yargs_default(hideBin(process.argv)).scriptName("mcp-proxy").
5095
5096
  default: "/mcp",
5096
5097
  describe: "The stream endpoint to listen on",
5097
5098
  type: "string"
5099
+ },
5100
+ tunnel: {
5101
+ default: false,
5102
+ describe: "Expose the proxy via a public tunnel using tunnel.gla.ma",
5103
+ type: "boolean"
5104
+ },
5105
+ tunnelSubdomain: {
5106
+ describe: "Request a specific subdomain for the tunnel (availability not guaranteed)",
5107
+ type: "string"
5098
5108
  }
5099
5109
  }).help().parseAsync();
5100
5110
  const dashDashArgs = argv["--"];
@@ -5159,8 +5169,19 @@ const proxy = async () => {
5159
5169
  stateless: argv.stateless,
5160
5170
  streamEndpoint: argv.server && argv.server !== "stream" ? null : argv.streamEndpoint ?? argv.endpoint
5161
5171
  });
5162
- return { close: () => {
5163
- return server.close();
5172
+ let tunnel;
5173
+ if (argv.tunnel) {
5174
+ console.info("establishing tunnel via tunnel.gla.ma");
5175
+ tunnel = await pipenet({
5176
+ host: "https://tunnel.gla.ma",
5177
+ port: argv.port,
5178
+ subdomain: argv.tunnelSubdomain
5179
+ });
5180
+ console.info("tunnel established at %s", tunnel.url);
5181
+ }
5182
+ return { close: async () => {
5183
+ await server.close();
5184
+ if (tunnel) await tunnel.close();
5164
5185
  } };
5165
5186
  };
5166
5187
  const createGracefulShutdown = ({ server, timeout }) => {