Run it
One file, no runtime. Three lines, none of them a setting.
curl -fsSL https://vitro.run/tunnel/install.sh | sh
vitro-tunnel login
vitro-tunnel tunnel
The installer puts it on your PATH; targets are
{linux,macos}-{amd64,arm64}. login is the same
OAuth sign-in claude mcp add uses — a browser, once, and
nothing to paste. tunnel with no port finds the dev server
already running in the directory you are in, and the fleet allocates the
port it answers on. Script is
served as plain text.
In a sandbox, where there is no browser
Same word. login notices and shows a code to approve on your
laptop or your phone instead of opening something here — RFC 8628, and
the credential it hands back needs no second host and does not expire
mid‑run.
vitro-tunnel login # picks the right door
vitro-tunnel login --device # or ask for the code
What has to be reachable, as data rather than prose:
/sandbox.json before anything is installed,
vitro-tunnel doctor --json from inside the box. And
tunnel tells you when your platform already publishes the
port and you need no tunnel at all.
Somewhere a script runs unattended
In CI, where nobody is present to approve anything, name the file and pin the version:
V=1.2.3
curl -fsSL "https://vitro.run/tunnel/linux-amd64?version=$V" -o vitro-tunnel
curl -fsSL "https://vitro.run/tunnel/linux-amd64/sha256?version=$V" \
| sed 's| .*| vitro-tunnel|' | shasum -a 256 -c -
chmod +x vitro-tunnel
The credential
login saves an OAuth grant in
~/.vitro/config.json and refreshes it on its own, which is
what lets a tunnel outlive one access token. Where a browser is the wrong
shape — CI, a baked image, a secret store — present a
psk_live_… instead. Flags win over
VITRO_URL/VITRO_KEY, so an image stays
overridable.
vitro-tunnel --key-file /run/secrets/vitro …
vitro-tunnel --key @/run/secrets/vitro … # one slot to fill
vitro-tunnel --key - … < /run/secrets/vitro
--url defaults to https://vitro.run; point it
at a vitro instance to use that instead.
When the client cannot reach the fleet
The same binary bridges MCP — see the tool reference.
vitro-tunnel mcp
vitro-tunnel serve --port 43218
Bytes on your own disk
The two things MCP has no shape for.
vitro-tunnel screenshot -page "$PAGE" -o broken.png
vitro-tunnel fetch vitro://artifact/9f2c -o shot.webp
Behind somebody else's network
HTTPS_PROXY is honoured. doctor exits
non-zero when it cannot reach the fleet — use it as a gate.
vitro-tunnel doctor