Agent on all boxes
Build the Magisk module with the hub URL baked in, flash it once, and never touch the box again.
The agent is a ~6 MB static Go binary started as root at boot by a Magisk module. It dials out over WSS, so the boxes work behind any NAT, CGNAT or changing IP with no ports open and no VPN.
Build the module
Bake the hub URL and an enrollment token in, so flashing is the only per-box step:
# SERVER is the hub URL — the same value as MAGNEMITE_PUBLIC_URL.
# docker compose: https://magnemite.example.com
# Coolify: https://agents.magnemite.example.com
make module SERVER=https://magnemite.example.com TOKEN=<enrollment token>
# → dist/magnemite-agent-0.1.2.zipOn Windows:
./scripts/build-agent.ps1 -Server https://magnemite.example.com -Token <token>Everything Go-related runs inside the golang image, so no toolchain is needed
on the host. The version comes from the VERSION file at the repo root, and
both build paths stamp it into module.prop.Magisk compares versionCode,
which is derived so it always moves with the version (0.1.2 → 102).
SERVER is the hub URL, never the dashboard's. A box pointed at the dashboard's domain fails
the handshake.
Install it now!
Through the Magisk app, or over adb:
adb push dist/magnemite-agent-0.1.2.zip /data/local/tmp/
adb shell "su -c 'magisk --install-module /data/local/tmp/magnemite-agent-0.1.2.zip'"
adb rebootIn bulk over the LAN:
./scripts/enroll.sh dist/magnemite-agent-0.1.2.zip 192.168.1.10 192.168.1.11
./scripts/enroll.sh dist/magnemite-agent-0.1.2.zip -f hosts.txtThat is the only time a box needs hands-on work. After it reboots, every later update rides the socket it opened itself: no adb, no LAN access. That includes the agent itself — see updating the agent, which the hub drives on its own and which never needs the module reflashing.
Without a baked-in config
Write /data/adb/magnemite/config.json on the box before rebooting:
{
"serverUrl": "https://magnemite.example.com",
"enrollmentToken": "…"
}The same values are available as flags: -server, -enroll-token, -name.
- The full list is in the environment reference.
What it does at boot
- Reads
config.json(or its flags). - Fixes DNS if
/etc/resolv.confis missing, see DNS on Android. - Enrolls if it has no device token yet, then rewrites the config without the enrollment token.
- Opens the WebSocket and sends
hellowith its serial, model, Android version, current Pokémon GO version and other useful information. - Heartbeats, and waits for an
install_job.
Which build goes on which box
make agent cross-compiles four binaries:
| Target | Used for |
|---|---|
linux/arm64 | the boxes |
linux/arm (GOARM=7) | older 32-bit boxes |
linux/amd64 | a fake fleet on a Linux host |
windows/amd64 | a fake fleet on Windows |
The module zip carries the two Linux ARM builds and picks at install time.