JackBoxAutoVIPServer extracts the current Jackbox lobby room code on the host machine and serves it over a tiny TCP protocol so other tools on your LAN can read it automatically. It is the first piece of an auto-VIP setup: once a client or bot can reliably read the room code, it can join the room and claim the VIP seat for you. (The auto-join VIP bot itself is future work — see below.)
When you launch a Jackbox game, the server intercepts the game's own backend
traffic, reads the room code straight out of it, and broadcasts it to every
connected client as the ASCII bytes RoomCode:<CODE> (no terminator) on TCP port
38469. New clients receive the current code the moment they connect; whenever
the code changes (a new room) the new code is broadcast. The server binds
0.0.0.0, so a client elsewhere on the LAN can connect.
It understands all three room-code protocols Jackbox packs use, so it works across both current and older packs:
- ecast (newer packs) — the code is in the
POST /api/v2/roomsresponse body. - Blobcast over REST (some older packs) — the code is the
roomIdin the host'sPOST /accessTokenrequest. - Blobcast over socket.io (oldest packs) — the code arrives in the
CreateRoomwebsocket frame.
Because it reads the code from the game's own network traffic, it survives game updates — there is nothing per-game or per-version to maintain.
- Linux
- Steam, with at least one Jackbox game installed
- bubblewrap (
bwrap) - mitmproxy on your
PATH—pipx install mitmproxy iptablesand a cgroup v1net_clshierarchy — used to redirect only the game's traffic to the proxy. Setting this up is onesudocommand per session.qrencode— only needed if you use the relay (below); it renders the pairing QR code. Most distros package it (qrencodeon Arch/Debian/Fedora).- Python's
tkinter— also only needed for the relay; it draws the pairing window itself. Already included on Arch/CachyOS (bundled with thepythonpackage). Debian/Ubuntu needpython3-tk; Fedora needspython3-tkinter.
Clone the repository and install the Python dependencies:
git clone https://github.com/username/JackBoxAutoVIPServer.git cd JackBoxAutoVIPServer python -m venv .venv &&. .venv/bin/activate pip install -r requirements.txt
With Steam fully closed (Steam rewrites its config on exit and would clobber the change), run the installer once:
python3 install.py
This finds every installed Jackbox game and sets its Steam launch option to
<repo>/jbvip-run.sh %command%.Once per session (e.g. after a reboot), activate the game-scoped traffic redirect. It needs
sudoand stays active until you remove it or reboot:sudo ./jbvip-redirect-up.sh
This redirects only the Jackbox game's
:443and:38203to the proxy — nothing else on the machine is touched. Remove it any time withsudo ./jbvip-redirect-down.sh.Start Steam and launch any Jackbox game normally. The room code is now served on TCP
:38469. Test it with:nc 127.0.0.1 38469
Create a room in the game and the client prints
RoomCode:<CODE>.
Each Jackbox game is launched through jbvip-run.sh, which:
- starts
mitmproxyin transparent mode (loadingextractor/addon.py) only while the game runs; - builds a CA bundle of your system CAs plus the mitmproxy CA and injects it into
the game's own mount namespace only via
bwrap --bind <bundle> /etc/ssl/certs/ca-certificates.crt; - puts the game in a
net_clscgroup whose:443/:38203traffic the kernel redirect (jbvip-redirect-up.sh) sends to the proxy.
The game process is never modified or injected into — the redirect happens in the
kernel, scoped to the game's cgroup — so even fragile older (Adobe AIR) packs run
normally. The mitmproxy CA is trusted only inside that one game's mount
namespace and vanishes when the game exits; the rest of the system never trusts
it. The addon watches the game's traffic, extracts the room code (ecast or
Blobcast), and hands it to the asyncio TCP server that speaks RoomCode:<CODE>.
A transparent redirect (rather than the HTTPS_PROXY env var the project first
used) is required because the oldest packs open their room-code websocket as a
raw TLS socket that ignores proxy settings — only a kernel-level redirect catches
it, and unlike injecting a library into the game it doesn't crash the AIR runtime.
By default the room code is served only on your LAN, over TCP 38469. If you want
a client to receive it from anywhere — a phone on cellular, or a friend's
house — you can run the small relay in relay/ on a VPS. The host pushes the
code out over ordinary outbound HTTPS, so there is nothing to port-forward and
nothing new listening on your machine.
See relay/README.md for deployment. Once it is running, create
~/.config/jbvip/relay.env — the launcher reads it on every game launch:
mkdir -p ~/.config/jbvip
cat >~/.config/jbvip/relay.env <<'EOF'JBVIP_RELAY_URL=https://your-relay.exampleEOF
chmod 600 ~/.config/jbvip/relay.envA file rather than export because Steam launches the game with the environment
the Steam client itself started with, so variables exported in a terminal never
reach it.
There is no token to configure any more. Every credential is minted fresh
at launch: jbvip-run.sh creates a session on the relay the moment it starts
(before the game itself launches), and that session — and everything it can
do — is deleted again when the game exits. Nothing about the relay is
long-lived on this machine.
Concretely, once JBVIP_RELAY_URL is configured, every launch shows a small
QR-code window before the game starts, meant to be scanned to pair a phone
with that game night. The phone app that does the pairing does not exist
yet. Scanning the QR with an ordinary camera app just opens a web page
telling you to open it in the jbvip app, which does not subscribe — so today
the window can never close itself. Either press Skip to close it at once
and launch the game LAN-only, or leave it, and after 120 seconds it gives up
and launches the game the same way. A dead or unreachable relay is handled
identically: the game always launches — LAN-only if the relay could not
be reached, reachable from any phone that paired if it could.
If the relay does not seem to be working, launch a game once and then look at
~/.local/state/jbvip/last-run.log. The launcher keeps the proxy log there —
and only there, and only when that run actually reported a relay problem, with
room codes redacted out of it. Nothing is kept when the relay is working or
when it is not configured at all.
The relay is entirely optional. Without that file, everything works exactly as before, LAN-only.
With Steam closed, clear the launch options the installer added:
python3 uninstall.py- An auto-join VIP bot that consumes the
RoomCode:<CODE>stream and takes the VIP seat for you automatically.
I welcome contributors who want to make this project better and bigger. If you would like to contribute, please fork the repository, make your changes on a branch, and submit a pull request with a clear description of the changes.
Please feel free to submit an issue for any questions, bug reports, or feature requests.
MIT License
Whether you're helping me fix bugs, proposing new features, improving the documentation, or spreading the word, thank you! Please enjoy the program.