Bots that join your Mumble server like a person would: post alerts, announce a relay, keep chat history, play music, drive tests.
Quick start ·
Docs ·
Examples ·
Releases ·
Changelog
mumbot is one small binary (or Docker image) with headless bots for Mumble voice chat. It is built from modules: run one, or several together as one bot user on one connection. Every bot logs in with its own client certificate, exactly like a person with a Mumble client, so it works with any unmodified, standard Mumble server: no server plugin, no server config change, no protocol extension. Its messages look the same in the official Mumble client and in Mumcord.
| Module | What it does | Build | Docs |
|---|---|---|---|
webhook |
Monitoring, CI or any script sends one HTTP request with an API key; the bot posts it into a channel. | main + tester | webhook.md |
peer |
Connects the server to a mumpeer relay: announces the relay to Mumcord clients and hands out short-lived relay tokens. | main + tester | peer.md |
Test bot (say, expect, play, script, …) |
A scripted second participant for automated tests: chat, user state, admin steps, checks, voice play/record/level. Exit code 0 = passed. | tester only | cli.md |
| Load test | Fills a local test server with up to 1000 users, with churn, chat and talkers. | tester, from source | cli.md |
music |
Plays MP3s (from a media folder, an upload or an allowed URL) as voice into a channel, with a queue, skip, stop and volume over an HTTP API. | main + tester | music.md |
plugins |
Stays online and suggests the Mumcord plugins your community uses to every Mumcord client that joins. | main + tester | plugins.md |
history |
Stays online, records the chat of the channels you choose and hands it to Mumcord clients that were offline (history sync). | main + tester | history.md |
Note
Release 0.2.0 adds the peer, history and music modules, mumbot run, the [voice]
settings and the separate tester build.
flowchart LR
ci["Monitoring, CI, scripts"] -- "HTTP + API key" --> bot
subgraph bot ["mumbot (one bot user)"]
webhook["webhook module"]
peer["peer module"]
music["music module"]
history["history module"]
plugins["plugins module"]
end
bot -- "TLS, own client certificate" --> server[("Standard Mumble server<br/>(unmodified)")]
peer -- "status and tokens (relay API)" --> relay["mumpeer relay"]
server --- mumcord["Mumcord clients"]
server --- mumble["Official Mumble clients"]
mumcord -. "relayed voice when a direct link fails" .-> relay
tester["mumbot-tester in CI"] -- "scripted steps, exit code" --> testsrv[("Throwaway test server")]
- The bot is a normal user on the server. Chat goes in as ordinary channel messages; the
peer,historyandpluginsmodules talk to Mumcord clients with plugin data, which official Mumble clients ignore. - The bot itself never relays voice. mumpeer does that, and only for Mumcord clients that ask for it.
Only registered users get relay tokens (
[peer] registered_only, on by default), or only the members ofallowed_groupswhen you configure them; see docs/peer.md. - The tester build belongs in CI, next to a throwaway server, never on a production server.
Post a message into your Mumble server in 30 seconds:
KEY=$(openssl rand -hex 32)
cat > bot.toml <<EOF
[server]
host = "mumble.example.org" # your server
channel = "Lobby"
[http]
listen = "0.0.0.0:8080"
[[keys]]
key = "$KEY"
label = "quickstart"
channels = ["Lobby"]
EOF
chmod 644 bot.toml
docker run -d --name mumbot -p 127.0.0.1:8080:8080 \
-v "$PWD/bot.toml:/config/bot.toml:ro" -v mumbot-data:/data \
ghcr.io/mumcord/mumbot:0.5.4curl -s -H "X-API-Key: $KEY" http://127.0.0.1:8080/channels # find the channel id
curl -s -X POST http://127.0.0.1:8080/message -H "X-API-Key: $KEY" \
-d '{"channel": 1, "message": "**deploy** finished"}'
# {"delivered":true}No server at hand? examples/webhook-with-server starts a
standard Mumble server next to the bot with one docker compose up.
curl -LO https://github.com/Mumcord/mumbot/releases/download/v0.4.1/mumbot-0.4.1-linux-x86_64.tar.gz
curl -LO https://github.com/Mumcord/mumbot/releases/download/v0.4.1/SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing && tar xzf mumbot-0.4.1-linux-x86_64.tar.gz
./mumbot webhook --config bot.tomlEach archive holds mumbot (mumbot.exe on Windows) at the top level, next to the licence, this
README, the changelog and bot.example.toml.
A throwaway Mumble server plus the scripted test bot, one command per test step:
cd examples/ci-test-bot
printf 'SUPERUSER_PASSWORD=%s\n' "$(openssl rand -hex 16)" > .env
docker compose up -d --wait mumble-server
# Is the client under test in Root and unmuted? Exit code 0 = yes.
docker compose run --rm -T bot --name Observer --timeout 20 expect user MyClient --in Root --muted false
# Several steps on one connection, one per line.
printf '%s\n' 'say "<b>hello</b>"' 'expect message --from MyClient --contains hi' 'sleep 1' \
| docker compose run --rm -T bot --name Bob script
docker compose --profile bot down -vReady to copy: smoke-test.sh and a
GitHub Actions workflow. Only point the test bot at
local or throwaway servers.
Since 0.2.0:
mumbot webhook --config bot.toml # one module
mumbot peer --config bot.toml
mumbot music --config bot.toml
mumbot history --config bot.toml
mumbot plugins --config bot.toml
mumbot run --config bot.toml --modules webhook,peer,history,music # several, one connection, one bot user
MUMBOT_MODULES=webhook,peer,history,music mumbot run --config bot.toml # same, handy in DockerOr list them in bot.toml and run mumbot run --config bot.toml:
[modules]
enabled = ["webhook", "peer", "history"]The command line wins over the config. Only the sections of the chosen modules are checked, and
when one module fails the whole bot stops. In Docker, set the container command to run and
choose the modules with MUMBOT_MODULES or [modules]; the image runs webhook by default.
Details: docs/modules.md.
The music module has its own HTTP listener (127.0.0.1:8081 by default) and its own API keys
([[music.keys]], sent as X-API-Key), separate from the webhook's:
| Endpoint | Does |
|---|---|
POST /play |
Queue an MP3: {"file": "…"} from media_dir, {"url": "…"} from an allowed host, or an audio/mpeg upload; optional channel and interrupt. |
GET /queue · GET /now-playing |
The current track, the waiting tracks and the volume. |
POST /skip · POST /stop |
Skip the current track; stop and clear the queue. |
POST /volume |
{"volume": 0–100}. |
GET /health |
Connection state, no key needed. |
curl -s -X POST http://127.0.0.1:8081/play -H "X-API-Key: $MUSIC_KEY" -d '{"file": "jingle.mp3"}'
# {"queued":true,"id":1,"position":0,"title":"Artist – Jingle"}Sources, limits and error codes: docs/music.md.
One TOML file (bot.toml, in Docker /config/bot.toml) with a section per concern:
| Section | For |
|---|---|
[server] |
The Mumble server, channel, the bot's name and data folder, server_cert_sha256. |
[modules] |
Which modules mumbot run starts (optional). |
[http], [[keys]] |
The webhook module's listener and its API keys. |
[[token]] |
Channel passwords (optional). |
[peer] |
The mumpeer relay for the peer module. |
[music], [[music.keys]] |
The music module's listener, media folder, URL allowlist, limits and API keys. |
[history] |
Channels to record, retention and database for the history module. |
[[plugins.announce]] |
Up to 8 Mumcord plugins the plugins module suggests. |
[voice] |
Voice bitrate (bitrate, --bitrate, MUMBOT_VOICE_BITRATE). |
Voice senders (the music module and the tester's play) use one bitrate setting:
[voice]
bitrate = 96000 # bit/s, 6000 to 510000; default 96000
frame_ms = 20 # packet length: 10 or 20--bitrate/--frame-ms win over MUMBOT_VOICE_BITRATE/MUMBOT_VOICE_FRAME_MS, which win over
[music] bitrate/frame_ms, which win over [voice]. The server's bandwidth limit always wins:
the bot lowers the bitrate to fit and logs a warning.
Secrets such as SERVER_PASSWORD and MUMBOT_PEER_API_SECRET come from the environment. Every
key, default and variable: docs/configuration.md; a commented start:
examples/bot.example.toml.
| Docs | |
|---|---|
| Modules and builds | Run one module or several; the two builds. |
| Webhook bot · HTTP API | Endpoints, authentication, message format. |
| Peer bot | Announce a mumpeer relay to Mumcord clients. |
| Music bot | Play MP3s into a channel: endpoints, sources, limits. |
| History bot | Record channel chat for Mumcord clients that were offline. |
| Plugins bot | Suggest your community's Mumcord plugins to everyone who joins. |
| CLI | Every command and flag, test-bot scripts, voice checks, load test. |
| Security | API keys, the client certificate, TLS, server certificate checking. |
All modules
- Always TLS to the server, with the bot's own client certificate. That certificate is the bot's
identity: keep the data folder (
/datain Docker) on a persistent volume, back it up, never share it. - Logs hold request metadata only: no API keys, no passwords, no message texts.
- The Docker image runs as a non-root user (uid 10001).
Webhook
- Plain HTTP on
127.0.0.1:8080by default; put a TLS reverse proxy in front to reach it from other machines. - One long random API key per caller, limited to its channels and rate-limited; keys are compared in constant time.
- Caller text is escaped: only a small Markdown subset and
http/httpslinks get through, never HTML. - It does not check the server certificate yet: run it on the same host or a trusted network as the server.
Peer
- Requires a pinned server certificate (
server.server_cert_sha256) and refuses any other server. - The relay's API secret (32+ characters) lives in a private file or
MUMBOT_PEER_API_SECRET, never inbot.tomlor Git. - Hands out short-lived relay tokens only; it never sees or relays voice.
Music
- Plain HTTP on
127.0.0.1:8081by default, its own API keys (a webhook key cannot play audio), rate-limited and limited to their channels. - Files only from the configured media folder; URLs are off by default, then only from listed hosts, never to private addresses, without redirects, with size, length and time limits.
History
- Records only the channels you list (
[history] channels), never private messages, never voice. - Keeps messages at most 7 days (
retention_days, 1 to 7) and the newest 5000 per channel (max_messages_per_channel); older ones are deleted. Its comment tells everyone what it records. - Set
server.server_cert_sha256: it hands out recorded chat, and with the pin it refuses any other server. - The SQLite file is readable only by the bot's user; chat texts never go into logs.
Test bot (tester build)
- Only for local or throwaway test servers. Generate the SuperUser password per CI run and remove the server with its volumes afterwards.
More: docs/security.md.
| Example | Use it to |
|---|---|
webhook/ |
Run the webhook bot against the Mumble server you already have. |
webhook-with-server/ |
Try everything on one machine: bot plus a standard Mumble server. |
peer-with-relay/ |
Try the peer bot with a mumpeer relay and a standard Mumble server. |
music/ |
Run the music bot against the Mumble server you already have. |
history/ |
Run the history bot against the Mumble server you already have. |
webhook-and-history/ |
Run two modules in one bot: post into channels and keep their chat history. |
ci-test-bot/ |
Test a Mumble client in CI against a throwaway server (tester image). |
Every release ships two variants. Both binaries are called mumbot; only the archive and image
names differ. Check downloads against SHA256SUMS from the same release.
| mumbot (main) | mumbot-tester | |
|---|---|---|
| Contains | The production modules (webhook, peer, history, music, plugins). No test code. |
The same plus the scripted test bot (checks, voice, samples). |
| Use it for | Bots on real servers. | Testing Mumble servers and clients in CI. |
| Archive | mumbot-<version>-<target> |
mumbot-tester-<version>-<target> |
| Docker image | ghcr.io/mumcord/mumbot:<version> |
ghcr.io/mumcord/mumbot-tester:<version> |
| Linux x86_64 (static) | mumbot-<version>-linux-x86_64.tar.gz |
mumbot-tester-<version>-linux-x86_64.tar.gz |
| Linux arm64 (static) | mumbot-<version>-linux-aarch64.tar.gz |
mumbot-tester-<version>-linux-aarch64.tar.gz |
| Windows x86_64 | mumbot-<version>-windows-x86_64.zip |
mumbot-tester-<version>-windows-x86_64.zip |
| macOS (Apple Silicon and Intel) | mumbot-<version>-macos-universal.tar.gz |
mumbot-tester-<version>-macos-universal.tar.gz |
- Images are multi-arch (
linux/amd64,linux/arm64), non-root, with a health check on/health. Stable releases also getlatest; pin a version tag. - The main build answers a test command with a pointer to the tester build (exit code 2).
- The tester variant exists since 0.2.0 (see the note under Modules).
From source (Rust 1.90+):
cargo build --release # mumbot, needs CMake (builds Opus for the music module)
cargo build --release --features tester # mumbot-tester| Mumcord | A modern desktop voice and chat client for standard Mumble servers. |
| mumpeer | A relay that connects Mumcord clients when a direct link fails. |
| mumbot | Friendly headless bots: webhooks, relay discovery, chat history, music, test automation. |
mumbot is built on Mumcord's protocol and codec crates
(mumcord-protocol,
mumcord-codec), and Mumcord's end-to-end tests use its
test bot. You do not need Mumcord: the bots work with any standard Mumble server.
Issues and pull requests are welcome.
cargo fmt --check
cargo clippy --all-targets -- -D warnings && cargo test # main build
cargo clippy --all-targets --features tester -- -D warnings && cargo test --features tester # tester build
cp testenv/.env.example testenv/.env && testenv/up.sh # local test server (Docker)
MUMBOT_LIVE=1 cargo test --features tester -- --ignored --test-threads=1 # live tests against it- Features start as a spec in
specs/; the roadmap lists what comes next. - Small commits in Conventional Commits style, user-visible
changes in
CHANGELOG.md. - Never test against public or third-party Mumble servers; use
testenv/.