A full-stack Linux radio gateway that bridges analog and digital two-way radios to the internet: Mumble VoIP, Broadcastify streaming, Winlink email over packet radio, APRS tracking, Telegram bot control, AI-powered announcements, distributed AI transcription, and scheduled fleet health checks — all driven from a single Python process with a 20+ page web UI. Bus-based audio routing with a visual drag-and-drop editor, plugin-based radio support that scales across multiple machines via the link endpoint protocol, per-stream diagnostic tracing, and 95+ MCP tools for AI control.
Radios: TH-9800 (AIOC USBIP), TH-D75 (Bluetooth RFCOMM + SCO), KV4P (USB serial), FTM-150 (remote AIOC endpoint), IC-7100 (CI-V remote endpoint), RSPduo dual SDR receiver.
| Dashboard | Routing | Transcription |
|---|---|---|
![]() |
![]() |
![]() |
| TH-9800 | TH-D75 | KV4P |
|---|---|---|
![]() |
![]() |
![]() |
| SDR | ADS-B | Packet Radio |
|---|---|---|
![]() |
![]() |
![]() |
More screenshots in docs/screenshots/.
Radio hardware — TH-9800 (AIOC USB + CAT control), TH-D75 over Bluetooth, KV4P HT (SA818/DRA818), RSPduo SDR (single-tuner multi-channel or dual-tuner master/slave), plus any AIOC/CI-V-equipped radio as a remote endpoint via Gateway Link.
Audio routing v2.0 — bus-based mixer with a visual drag-and-drop editor at /routing. Four bus types (Listen / Solo / Duplex / Simplex Repeater), per-bus processing chain (gate / HPF / LPF / notch / neural denoise with RNNoise or DeepFilterNet 3), per-bus PCM + MP3 streaming, NUL sink for recording-only paths. Independent TX/RX muting per radio.
Transcription — distributed pool. Moonshine (linear cost, wins on short clips) + Whisper via faster-whisper (better accuracy on long clips), routed by clip length. Local engine or remote workers on other Linux boxes. Silero v5 VAD. Per-utterance frequency tagging and Mumble/Telegram cross-posting.
Loop recorder — per-bus continuous recording (1h – 7d retention), canvas waveform with click-to-play and drag-select export. Server-owned playback so it survives browser close.
Packet radio + Winlink — Direwolf TNC on an FTM-150 link endpoint, automatic audio/data mode switching. APRS decode + Leaflet map. Winlink email via Pat. BBS terminal.
AllStarLink — bridge into the AllStar network without running a radio node on the gateway. An in-gateway USRP (DVSwitch) plugin talks to a headless ASL3 bridge node; a /usrp panel connects to any node on demand (per-node disconnect, conference view), and AllStar audio routes to/from any bus like another radio. See docs/allstar_bridge.md.
Streaming — Broadcastify / Icecast via internal ffmpeg pipe (no DarkIce, no ALSA loopback). Auto-reconnect. Cloudflare quick-tunnel for free public HTTPS with URL discovery via Google Drive.
Control surfaces — 20+ page web UI, 95+ MCP tools, Telegram bot (text routes through Claude Code + MCP; voice notes stream straight to radio TX), Mumble chat commands (!speak, !cw), web mic + Android room monitor.
Fleet Manager — document-driven autonomous monitoring. Plain-English tasks in hourly.md / daily.md are handed to a Claude session on a schedule; structured reports come back with Telegram escalation on elevated severity. Auto-discovers nodes that change DHCP IP. See docs/fleet-manager.md.
Telemetry, AI, automation — Smart Announcements (Claude CLI → Edge TTS → broadcast on schedule), scheduled automation tasks, live transcription, dashboard CPU breakdown (real-time critical / background nice / iowait / per-core load avg).
Smaller features — Google TTS + 9 voice accents, soundboard with 10 announcement slots, EchoLink via named pipes, optional embedded Mumble server (1 or 2 instances), GPS receiver, ARD repeater directory with proximity search and SDR auto-tune, ADS-B aircraft tracking, DDNS, Gmail notifications.
See CHANGELOG.md for the detailed release history. Highlights:
- v4.0 (2026-05-31) — AllStarLink integration: in-gateway USRP bridge to a headless ASL3 node,
/usrpconnect/disconnect panel + top-frame meter, and the plugin platform made generic over discovered plugins (routing UI, meters, bus radio resolution,web_routesdispatch). - v3.7 (2026-05-18) — distributed transcription pool, audio meter unification (RG.vu), Fleet Manager docs, 6-hourly gdrive backup of operational docs, install.sh package-manager detection fix (#3).
- v3.6 (2026-05-08) — Fleet Manager: document-driven autonomous monitoring with scheduled Claude-driven checks, manifest-based fleet topology, Telegram escalation.
- v3.5 (2026-05-03) — persistent transcription log with FTS5 + plain-English search; tabbed dashboard; bus tick refactor with per-sink drain threads.
- v3.3 (2026-04-19) — DeepFilterNet 3 denoise, phase-aligned wet/dry, per-stream transcription workers.
- v3.2 (2026-04-19) — Moonshine ASR + Silero VAD + RNNoise.
- v3.0 (2026-04-08) — Unified audio engine + Loop Recorder + plugin auto-discovery.
- v2.0 (2026-04-01) — Bus-based routing + visual UI + plugin architecture.
Full walkthrough in INSTALL.md — prereqs, credential setup, per-feature checklists, troubleshooting. Summary below covers the happy path.
git clone https://github.com/ukbodypilot/radio-gateway.git
cd radio-gateway
bash scripts/install.shThe installer walks 15 phases (distro detection, system packages, ALSA loopback, Python packages, KV4P driver, UDEV rules, audio + realtime groups, optional Darkice / SDR / Mumble server, systemd unit). Ends with a health check that flags anything off.
After it finishes:
- Log out and back in (or
newgrp audio) so group memberships take effect. - Edit
gateway_config.txt— at minimum[mumble] MUMBLE_SERVER / MUMBLE_PORT / MUMBLE_USERNAME / MUMBLE_PASSWORD. The example config opens with a Fresh-Install-Minimum block. - Start:
sudo systemctl enable --now radio-gateway && sudo journalctl -u radio-gateway -f. - Open
http://<host>:8080/dashboard.
Start at docs/index.md — pages grouped by audience (install / operate / extend / understand decisions).
A few that are likely the most useful:
- docs/transcription-pool.md — distributed ASR architecture + deploying a remote worker
- docs/fleet-manager.md — document-driven monitoring with worked English-task examples
- docs/gateway_link.md — link endpoint protocol for remote radios
- docs/allstar_bridge.md — AllStarLink bridge node + in-gateway USRP plugin +
/usrppanel - docs/plugin-development.md — writing a new radio plugin
- docs/config-reference.md — every
gateway_config.txtkey, grouped by feature
radio-gateway/
├── radio_gateway.py entry point
├── gateway_core.py RadioGateway class, main loop
├── gateway_setup.py phased initialization helpers
├── gateway_mcp.py MCP server (95+ tools, stdio)
├── web_server.py HTTP/WS server + config UI
├── web_routes_*.py per-domain POST handlers (transcribe / radio / audio / text / system / voice / manager / automation)
├── audio_bus.py, bus_manager.py bus mixer
├── audio_sources.py all source/sink classes
├── transcriber.py, transcribe_engine.py ASR + pool dispatcher
├── manager_engine.py Fleet Manager scheduler
├── th9800_plugin.py, kv4p_plugin.py, sdr_plugin.py, ic7100_link_plugin.py radio plugins
├── gateway_link.py link endpoint protocol + server
├── loop_recorder.py per-bus continuous recording
├── packet_radio.py Direwolf TNC + Pat client
├── smart_announce.py, radio_automation.py
├── web_pages/ HTML pages + common.css/.js (the shell)
├── docs/ feature docs grouped by audience (see docs/index.md)
├── scripts/ install.sh + systemd unit templates
├── tools/ telegram_bot.py, transcribe_worker.py, link_endpoint.py
└── examples/gateway_config.txt the canonical config template (read this once)
MIT.
Issues and PRs welcome. See docs/plugin-development.md for the plugin contract — adding a new radio is the most common contribution shape.








