Tunnels — Getting Started

Your first tunnel

lpm tunnel                                 # defaults to port 3000
lpm tunnel 4000                            # tunnel to port 4000

The command prints an https:// URL that proxies to your local port. Free accounts get a random ephemeral subdomain on every run — fine for one-off webhook testing, painful for anything that wants a stable URL across restarts (which is why Pro/Org plans add claimed domains).

$ lpm tunnel 3000
✔ Tunnel ready
  → https://patient-stoat-9b3.lpm.llc → http://127.0.0.1:3000
  inspector: http://127.0.0.1:54218

Stop with Ctrl-C. The URL invalidates as soon as you do.

Naming the session

lpm tunnel 3000 --session "stripe-test"

The session name shows up in the inspector's session list and in any captured events. Useful when you bounce between multiple tunnels (a Stripe webhook tunnel for one project, a Slack tunnel for another) and want to remember which capture log goes with which.

Keeping webhook providers happy: --auto-ack

Webhook providers (Stripe, GitHub, Slack, Linear) deactivate endpoints that repeatedly return 5xx. When your local server is down or restarting, the tunnel will normally pass through whatever error the local port produces — which can cause the provider to disable your endpoint after a few failures.

--auto-ack returns 200 OK to the provider when the local server is unreachable, so the endpoint stays alive while you iterate:

lpm tunnel 3000 --auto-ack

The auto-ack response is logged in the inspector with a clear marker — you'll see which events were ack'd without ever reaching your code, so you don't accidentally mistake them for successfully-handled events. Replay them once your server is back up.

Gating the URL: --tunnel-auth (Pro/Org)

By default, anyone with the tunnel URL can hit it. For development scenarios where the URL might leak (sharing in a chat, posting in a Slack channel), require an auth token:

lpm tunnel 3000 --tunnel-auth

Callers must send a Bearer token issued at tunnel start. The CLI prints the token on startup; webhook providers won't satisfy it (most don't support arbitrary Bearer auth on the outbound webhook), so use this for human-callable URLs (preview sharing, MCP servers used by an agent that can be configured with a token), not for webhook receivers.

--tunnel-auth requires a Pro or Org plan.

Inspector port

The inspector (browser UI for captured webhooks) starts automatically on a free ephemeral port. Pass an explicit port for a stable bookmark, or skip it:

lpm tunnel 3000                            # inspector at http://127.0.0.1:<auto>
lpm tunnel 3000 --inspect-port 4500        # inspector at http://127.0.0.1:4500
lpm tunnel 3000 --no-inspect               # no inspector

The auto-pick is race-free against lpm dev's service ports and any other local server. An explicit --inspect-port is strict — if the port is already in use, the command fails with a clear diagnostic instead of silently rolling to another port.

lpm dev --tunnel accepts the same --inspect-port and --no-inspect flags and surfaces the inspector URL in the startup banner.

All flags

FlagEffect
<port>Local port to expose (default: 3000)
<domain>Use a claimed domain (Pro/Org) for this run
--org <SLUG>Operate against an organization
--tunnel-authRequire a Bearer token to access the tunnel URL (Pro/Org)
--auto-ackReturn 200 OK to webhooks when the local server is down
--session <NAME>Name this tunnel session in the inspector
--no-inspectDisable the auto-started inspector UI
--inspect-port <N>Bind the inspector to exactly this port

For the full CLI flag reference and global flags shared with other lpm commands, see cli.lpm.dev/docs/infra/tunnel.

Next