# Port Zero Set your ports to 0. Port Zero handles the rest — no conflicts, ever. Port Zero gives every local service a stable domain name, so the random OS-assigned port a program binds never collides with another. It works the same for a plain process or a Docker container. Local tunnels are free and open source (GPLv3); Cloud tunnels reach the LAN and the internet and need a subscription. Site: https://portzero.net Docs: https://portzero.net/docs Product/dashboard: https://app.portzero.cloud Source: https://github.com/PortZeroNetwork/portzero ## Install - macOS: brew tap PortZeroNetwork/portzero && brew install portzero - Linux: curl -fsSL https://portzero.net/install.sh | sh - Windows: download the latest .msi release asset from https://github.com/PortZeroNetwork/portzero/releases ## The PZ_TUNNEL contract Set the environment variable PZ_TUNNEL before you exec a program. Its value is the full domain name and port that clients should use to reach that program: PZ_TUNNEL=..portzero.local: Rules: - Bind the program to port 0. Port 0 tells the OS to pick a free port at random; Port Zero forwards the domain's port to whatever the OS assigned, so two programs never fight over the same number. - PZ_TUNNEL must be set in the environment BEFORE the program starts. Port Zero discovers the process/container by this variable and wires up the tunnel. - A hostname ending in `.portzero.local` is a free, local-only Local tunnel (open source, single machine, no account). - A hostname ending in `.tunnel.portzero.cloud` is a Cloud tunnel: reachable from the LAN and the internet, requires `portzero login` and a subscription. Form: `...tunnel.portzero.cloud:`, where `` is your portzero.cloud account name. - The port after the colon is the port clients use (usually 80), not the port the program binds. ### Templates The subdomain may use templates so parallel copies of a project each get a distinct, stable URL: - `{branch}` — current git branch, e.g. `{branch}.myapp.portzero.local:80` - `{worktree}` — current git worktree name This is the git-worktree use case: run `main` and a feature branch at the same time, each on its own URL, with no port conflicts. Works for any TCP protocol, not just HTTP. ## How it works (Local tunnel) When PZ_TUNNEL ends in `.portzero.local`, the background service: 1. Creates a virtual network interface (NIC) on the machine if needed. 2. Assigns a virtual IP on that NIC for the process/container. 3. Creates a virtual DNS record for that IP from the PZ_TUNNEL template. 4. Forwards the PZ_TUNNEL port on that IP to the program's real random port. For `.tunnel.portzero.cloud`, Port Zero instead opens a reverse-proxy tunnel to portzero.cloud, which forwards a public subdomain to the local program. ## Core CLI commands - portzero start — start the background service / a tunnel - portzero status — list discovered processes and their tunnel URLs - portzero url — print the stable URL for the current project/tunnel - portzero env — print PZ_TUNNEL and related env for a project - portzero wait — block until a tunnel is ready (useful in scripts) - portzero doctor — diagnose networking/DNS/permission problems - portzero login — authenticate for Cloud tunnels - portzero mcp — run the MCP server so coding agents can drive the CLI ## For coding agents Run `portzero agents setup` to auto-configure MCP for every supported agent on this machine (Claude Code, Codex, pi.dev, opencode, Grok Build) — registers `portzero mcp` and writes a short explainer into each agent's user-level instructions file. No manual JSON editing needed. Use `--dry-run` to preview. Suggested one-shot prompt for a repo: Install Port Zero (https://portzero.net/install.sh) and set PZ_TUNNEL so this project's dev server gets a stable web..portzero.local URL. Then run `portzero agents setup` to register the MCP server. Prefer `portzero mcp` (Model Context Protocol server) when integrating an agent: it exposes starting tunnels, reading the live URL, and waiting for readiness as tools, so the agent does not have to parse CLI output.