Skip to content

CLI Reference

xeri edited this page Jul 14, 2026 · 1 revision

CLI Reference

One binary, several commands. Everything here is verified against the actual command definitions — where the README says something different, the README is wrong.

proxyforward                                  # GUI
proxyforward gateway                          # run the gateway engine in the console
proxyforward agent                            # run the agent engine in the console
proxyforward pair <pairing-code>              # configure this machine as an agent
proxyforward firewall <status|add|remove>
proxyforward service <install|uninstall|start|stop|run>
proxyforward --version

proxyforward

No arguments → the GUI. Double-clicking the exe in Explorer does the same thing.

If an engine is already running (typically the Windows service), the GUI attaches to it over the named pipe as a thin client rather than starting a second engine. Exactly one process ever owns the ports and the config.

proxyforward gateway / proxyforward agent

Runs the engine in that role, in the console, with no window. Use this on a headless VPS or under a process supervisor.

Flag Default Meaning
--config <path> %APPDATA%\proxyforward\config.toml Use a different config file.
--log-level <level> from config (info) debug, info, warn or error.
--headless true No effect. These subcommands are always headless. The flag exists but is never read — don't rely on --headless=false doing anything.

On start it loads the config, adopts the role from the subcommand if the config doesn't have one, and refuses to start if the config's role contradicts the subcommand (so you can't accidentally run your gateway config as an agent). On first run it generates what that role needs: a token for a gateway, an identity for an agent.

proxyforward pair <pairing-code>

Takes the code the gateway showed you and writes an agent config from it. It does not start anything — run proxyforward agent afterwards.

It validates the code, stores the gateway host/port, the auth token and the pinned certificate fingerprint, generates an agent identity if there isn't one, and creates a default Minecraft tunnel — but only if you have no tunnels yet, so re-pairing never clobbers your setup.

Flag Default Meaning
--config <path> %APPDATA%\proxyforward\config.toml
--local <host:port> 127.0.0.1:25565 Where your Minecraft server actually listens.
--public-port <port> 25565 The port to request on the gateway.
proxyforward pair "pf1://mc.example.com:8474/3f9a…/#sha256:9b1e…" --local 192.168.1.50:25565
proxyforward agent

Quote the code — it contains / and #, and an unquoted # will be eaten by some shells.

proxyforward firewall <status|add|remove>

Manages the single program-scoped inbound rule named proxyforward. See Networking and Firewall.

  • status — no elevation required.
  • add / remove — elevate via a UAC prompt.

Because the rule is scoped to the program and not to a port, you add it once and never think about it again, even after changing ports.

proxyforward service <install|uninstall|start|stop|run>

Manages the Windows service. This command takes no flags — in particular there is no --role (the README is wrong about this). The role comes from the config file, which install seeds into %ProgramData%\proxyforward from your current user config.

run is what the service manager itself invokes; you don't run it by hand.

See Windows Service.

proxyforward --version

Prints the version and commit stamped in at build time. A source build with no -ldflags will report a development version — that's expected, see Installation.


Hidden commands

elevated-task (the internal target proxyforward re-launches as administrator to add a firewall rule or install the service) and tray-spike (a leftover prototype) are hidden and not supported. Don't use them.

Running two setups on one machine

Point each at its own config and they won't interfere:

proxyforward gateway --config C:\tmp\gw.toml
proxyforward pair "<code>" --config C:\tmp\ag.toml
proxyforward agent   --config C:\tmp\ag.toml

Note that only one engine at a time can own the named pipe, so you cannot run two engines side by side on one machine — that conflict is fatal by design.

Clone this wiki locally