Teamspeak 6 Web Server Status
A simple webview of your Teamspeak 6 Server. This is a Python re-write of ts6-web-explorer along with a visual overhaul
Visitors who know the server password can also join voice straight from the browser, no TeamSpeak client needed.
Running
Requires Python 3.13+ (uv) and, for browser voice, Node.js 22.12+.
uv sync
uv run run.py
That one command starts the dashboard and the voice gateway (gateway npm dependencies are installed automatically on first run). Open http://<host>:5000.
- Copy
.env.templateto.envand fill in the secrets (TS_HOST,TS_API_KEY,TS_SERVER_PASSWORD) - Everything else is configured in
config.toml, which is shared by the dashboard and the voice gateway - Images in
config.tomlare referenced based on the root of this repo - Spacer channels are hidden
- Channels with the text
AFKare shown, the number of users in this channel is used as the AFK users indicator uv run app.pystill runs the dashboard alone (no voice)
Browser voice
browser ──HTTP/WS :5000──▶ gateway (Node) ──proxy──▶ dashboard (Flask, 127.0.0.1:5001)
│
└──UDP voice──▶ TeamSpeak server :9987
- The gateway owns the public port: it serves
/ws/voiceand forwards everything else to Flask, so there is only one port to expose / reverse-proxy. - Each browser gets its own TeamSpeak client inside the gateway (via
@honeybbq/teamspeak, pure JS). Mic audio is sent as 20 ms PCM frames over the WebSocket and encoded to Opus on the gateway; incoming Opus is decoded in the browser with WebCodecs (or on the gateway for browsers without it). No WebRTC. - Access control: voice is only offered when
TS_SERVER_PASSWORDis set. Visitors must type the server password; the gateway checks it (constant time) before opening any TeamSpeak connection, and the TeamSpeak server checks it again. Repeated wrong passwords lock the IP out ([voice] max_failed_logins,lockout_minutes). Cross-origin WebSocket connections are rejected. - Limits for small machines:
[voice] max_sessionsandmax_sessions_per_ip. - While connected, the channel list is rendered live from the voice session (talking indicators, join buttons per channel, password-protected channels prompt for their password).
- Controls: mute, deafen, voice activity (with sensitivity) or push-to-talk (hold the button or
V), output volume.
Deployment notes
- Browsers only allow microphone access on HTTPS or
localhost. Put the app behind a TLS reverse proxy (Caddy, nginx, ...) and forward WebSocket upgrades for/ws/voice. If your proxy rewrites theHostheader, add your public origin to[voice] allowed_origins; settrust_proxy = trueso per-IP limits useX-Forwarded-For. - arm64 / SBCs: everything is pure JS/WASM (Opus via
opusscript), sonpmneeds no compiler. If you want lower CPU use,cd gateway && npm install @discordjs/opus(native addon) and the gateway will pick it up automatically. - The gateway needs outbound UDP to the TeamSpeak voice port (
TS_VOICE_PORT, default 9987). - Gateway tests:
cd gateway && npm test.
