Expose localhost to the internet with HTTPS and TCP tunnels
A tunnel gives a service on your machine or local network a public address. Run one command and anyone on the internet can reach localhost:3000 at a URL like https://amber-otter.tunnel.canister.software. It does the same job as an ngrok or Cloudflare tunnel, without an account, an API key, or a dashboard to sign in to.
Use it to:
- share a local web app or API with a teammate or client;
- receive webhooks from Stripe, GitHub, or any other service on your laptop;
- reach a device on your home network, such as a Raspberry Pi, a camera, or an MQTT broker;
- demo work in progress without deploying it.
1. Install the CLI
Section titled “1. Install the CLI”The consensus command runs on Bun:
curl -fsSL https://bun.com/install | bashnpm install -g @canister-software/consensus-cliSee CLI setup for details.
2. Open an HTTP tunnel
Section titled “2. Open an HTTP tunnel”Start your local server, then point a tunnel at it:
consensus tunnel http localhost:3000The tunnel gets a public HTTPS URL on tunnel.canister.software, with a short name such as amber-otter:
https://amber-otter.tunnel.canister.software → localhost:3000Every request to that URL is forwarded to your local port, and the response goes back the same way. TLS is handled for you, so your local server can stay plain HTTP.
On macOS the tunnel opens in its own Terminal window with a live dashboard: the public URL, request counts, and a log of each request as it arrives. Keep the window open; closing it closes the tunnel.
Tunnel to another device on your network
Section titled “Tunnel to another device on your network”The target does not have to be your own machine. Anything your machine can reach works:
consensus tunnel http 192.168.1.101:80803. Open a TCP tunnel
Section titled “3. Open a TCP tunnel”For services that do not speak HTTP, such as a database, an MQTT broker, or SSH, open a TCP tunnel:
consensus tunnel tcp localhost:1883All TCP tunnels share one public address, tcp.tunnel.canister.software:20000. To tell the server which tunnel a connection is for, a client sends the tunnel’s name and a newline as the first line, then talks to your service as normal:
{ printf 'amber-otter\n'; cat; } | nc tcp.tunnel.canister.software 20000How it works
Section titled “How it works”- The CLI asks the network for a tunnel with
POST /tunneland receives a public address and a one-time token. - It opens a WebSocket to the network with that token. That connection carries the tunnel’s traffic.
- When a request reaches the public address, the network sends it down your connection; the CLI forwards it to your local target and returns the response.
Because the connection is outbound from your machine, you do not need to open a port on your router or firewall. See the API reference for the full POST /tunnel options, including private tunnels that are reachable only through the proxy.
Next steps
Section titled “Next steps”- Proxying HTTP requests: route your app’s outbound requests through the network
- Static IP for API whitelisting: send traffic from one stable IP address
- Metered WebSocket sessions: open prepaid, bounded WebSocket sessions
- Coming from another tool? See the ngrok alternative and Cloudflare Tunnel alternative comparisons