Web-based management interface for TeamSpeak servers. Control virtual servers, channels, clients, permissions, music bots, automated workflows, and embeddable server widgets — all from your browser.
Built on the WebQuery HTTP API (the ServerQuery replacement in modern TeamSpeak builds). Telnet is not used or supported.
Live overview of your server: online users, channel count, uptime, ping, bandwidth graph, and server capacity at a glance.
Run multiple music bots per server. Each bot has its own queue, volume control, and playback state. Supports radio streams, YouTube, and a local music library. Users in the bot's channel can control it via text commands (!radio, !play, !vol, etc.).
Visual node-based editor for building automated server workflows. Drag triggers, conditions, and actions onto the canvas, connect them, and deploy. Supports TS3 events, cron schedules, webhooks, and chat commands as triggers.
Get started quickly with pre-built flow templates. Covers common use cases like temporary channel creation, AFK movers, idle kickers, online counters, and group protection. One click to import, then customize to your needs.
- Dashboard with live server stats, bandwidth graph, and capacity overview
- Virtual server list with start/stop controls
- Channel tree with drag-and-drop ordering
- Client list with kick, ban, move, poke actions
- Server & channel group management
- Permission editor (server, channel, client, group-level)
- Ban list management
- Token / privilege key management
- Complaint viewer
- Offline message system
- Server log viewer with filtering
- Channel file browser with upload/download
- Instance-level settings
- Multiple bots per server, each with independent queue and playback
- Radio station streaming with ICY metadata and live title updates
- YouTube playback via yt-dlp (search, download, queue)
- Music library management (upload, organize, playlists)
- Volume control, pause, skip, previous, shuffle, repeat
- Stereo audio support with stable 20ms pacing
- Auto-reconnect with exponential backoff on disconnect
- In-channel text commands for hands-free control
- Music request history tracking
- Live video streaming from YouTube, Twitch, or direct URLs to TeamSpeak channels
- WebRTC-based with Go sidecar relay (Pion) for low-latency delivery
- Quality presets (480p, 720p, 1080p)
- In-browser preview with WebRTC playback
- A/V synchronization via RTCP Sender Reports
- Runs as a Docker sidecar container alongside the backend
- Visual flow editor with drag-and-drop node canvas
- Triggers: TS3 events, cron schedules, webhooks (with mandatory secrets), chat commands (global or channel-specific)
- Actions: kick, ban, move, message, poke, channel create/edit/delete, HTTP requests, WebQuery commands
- Conditions, variables, delays, loops, logging
- Animated channel names (rotating text on a timer)
- Placeholder system with filters and expressions
- Pre-built templates for common automation tasks
- Embeddable server status banner for websites and forums
- Token-based public access (no authentication required)
- Available as live page, SVG, or PNG image
- Dark and light themes
- Configurable: show/hide channel tree and client list
- Setup wizard for initial admin account (no default credentials)
- AES-256-GCM encryption for stored credentials (API keys, SSH passwords)
- SSRF protection on all outbound HTTP requests and FFmpeg URLs
- Rate limiting on authentication endpoints
- JWT access + refresh token rotation with reuse detection
- Role-based access control (admin / viewer)
- Per-server access control for multi-tenant setups
- WebQuery command whitelist in bot flows (blocks destructive commands)
- Authenticated WebSocket connections
- Password complexity requirements
- yt-dlp cookie file management for accessing age-restricted or member-only YouTube content
- Upload cookies via file or paste directly in the UI
- Admin-only settings panel
┌──────────────┐ ┌──────────────┐ ┌─────────────────┐
│ Frontend │────▶│ Backend │────▶│ TS Server │
│ React SPA │ │ Express API │ │ WebQuery HTTP │
│ nginx :80 │ │ Node :3001 │ │ SSH (events) │
└──────────────┘ └──────┬───────┘ └─────────────────┘
│
┌──────┴───────┐
│ SQLite │
│ (Prisma) │
└──────────────┘
│
┌──────┴───────┐
│ Sidecar │
│ Go/Pion │
│ WebRTC :9800│
└──────────────┘
Public: /widget/:token ──▶ SVG / PNG / JSON (no auth)
Four packages in a pnpm monorepo:
| Package | Description |
|---|---|
@ts6/common |
Shared types, constants, utilities |
@ts6/backend |
Express API, WebQuery client, bot engine, voice bots, widgets |
@ts6/frontend |
React SPA with Vite, TailwindCSS, shadcn/ui |
sidecar |
Go WebRTC media relay (Pion) for video streaming |
The backend proxies all TeamSpeak API calls. The frontend never has direct access to API keys or server credentials.
Frontend: React 18, Vite, TailwindCSS, shadcn/ui, TanStack Query + Table, React Flow, Recharts, Zustand
Backend: Node.js, Express, Prisma (SQLite), JWT authentication, WebQuery HTTP client, SSH event listener
Voice/Audio: Custom TS3 voice protocol client (UDP), Opus encoding, FFmpeg, yt-dlp
Video Streaming: Go sidecar with Pion WebRTC v4, RTCP Sender Reports for A/V sync
- Download the
docker-compose.yml - Create a
.envfile next to it:
JWT_SECRET=your-random-secret-at-least-32-characters
ENCRYPTION_KEY=another-random-secret-for-credential-encryptionGenerate secure values:
echo "JWT_SECRET=$(openssl rand -base64 32)" >> .env
echo "ENCRYPTION_KEY=$(openssl rand -base64 32)" >> .env- Start the stack:
docker compose up -d- Open
http://localhost:3000/setupand create your admin account - Log in, then add your TeamSpeak server connection under Settings → Connections (host, WebQuery port, API key)
JWT_SECRETis required — the backend will refuse to start in production without it.ENCRYPTION_KEYis optional but recommended — if not set,JWT_SECRETis used as fallback for credential encryption.
git clone https://github.com/clusterzx/ts6-manager.git
cd ts6-manager
echo "JWT_SECRET=$(openssl rand -base64 32)" >> .env
echo "ENCRYPTION_KEY=$(openssl rand -base64 32)" >> .env
docker compose -f docker-compose.local.yml up -d --buildUse docker-compose.coolify.yml as a starting point. Key differences from the standard compose:
- No
portssection — the reverse proxy handles routing - Set the domain on the frontend service in Coolify (port 80)
- If your TS server runs in a separate Docker network, add it as an external network on the backend service:
services:
backend:
networks:
- ts6-network
- ts-server-net
networks:
ts-server-net:
external: true
name: your-ts-server-network-idRequires: Node.js 20+, pnpm 9+
pnpm install
pnpm dev # starts backend + frontend in parallelBackend runs on :3001, frontend on :5173 (Vite dev server).
Prisma with SQLite. On first run:
cd packages/backend
npx prisma migrate deployThe Docker images handle migrations automatically on startup.
| Variable | Default | Description |
|---|---|---|
JWT_SECRET |
— | Required. Secret for JWT signing. Must be set in production. |
ENCRYPTION_KEY |
— | Optional. Dedicated key for AES-256-GCM credential encryption. Falls back to JWT_SECRET if not set. |
PORT |
3001 |
Backend port |
DATABASE_URL |
file:./data/ts6webui.db |
SQLite database path |
JWT_ACCESS_EXPIRY |
15m |
Access token lifetime |
JWT_REFRESH_EXPIRY |
7d |
Refresh token lifetime |
FRONTEND_URL |
http://localhost:3000 |
CORS origin |
MUSIC_DIR |
/data/music |
Directory for downloaded music files |
SIDECAR_URL |
— | Optional. Full URL of the WebRTC sidecar service (e.g. http://ts6-sidecar:9800). Set in Docker when sidecar runs as a separate container. |
YT_COOKIE_FILE |
— | Optional. Path to a Netscape-format cookies.txt file for yt-dlp. Can also be managed via Settings → YouTube in the UI. |
| Variable | Default | Description |
|---|---|---|
VIDEO_QUEUE_SIZE |
2048 |
Size of the video RTP queue |
AUDIO_QUEUE_SIZE |
4096 |
Size of the audio RTP queue |
SYNC_PLAYOUT_BUFFER_MS |
4 |
Small playout buffer used by the adaptive pacing logic |
SYNC_VIDEO_BIAS_MS |
4 |
Optional extra holdback for video to fine-tune sync |
AUDIO_DELAY_MS |
0 |
Legacy / manual audio delay option With the current pacing logic this is typically expected to stay at 0 |
SIDECAR_DEBUG_LOGS |
1 |
Enables verbose debug logging for high-frequency runtime details |
VIDEO_READ_RTP_BUFFER |
4194304 |
UDP OS-socketbuffer for video port |
AUDIO_READ_RTP_BUFFER |
1048576 |
UDP OS-socketbuffer for audio port |
VIDEO_BUFSIZE |
1M |
FFmpeg Video Buffer |
When a music bot is connected to a channel, users in that channel can control it via chat:
| Command | Description |
|---|---|
!radio |
List available radio stations |
!radio <id> |
Play a radio station |
!play <url> |
Play from YouTube URL |
!play |
Resume paused playback |
!stop |
Stop playback |
!pause |
Toggle pause/resume |
!skip / !next |
Next track in queue |
!prev |
Previous track |
!vol |
Show current volume |
!vol <0-100> |
Set volume |
!np |
Show current track |
- TeamSpeak server with WebQuery HTTP enabled (not raw/telnet)
- WebQuery API key (generated via
apikeyaddor server admin tools) - SSH access to the TS server (only needed for bot flow event triggers)
yt-dlpandffmpeginstalled on the backend (included in the Docker image)
MIT



