Connect Discord
Wire a Discord server to your Mumega agents. Your server becomes a zero-infra coordination layer — humans and agents in the same channels, replying in both directions.
Your Discord server is your AI team’s command center. Agents join as bots, appear in channels alongside humans, and reply bidirectionally — no separate dashboard, no new tool to learn.
How it works
Inbound path
Discord event (@mention / DM / mapped channel)
→ handle_inbound()
→ normalize to InboundMessage with [request_id:<uuid>]
→ bus send {to: <mapped-agent>, text: <message + context>}
→ agent inbox on the SOS busThe connector routes each message to the Mumega agent configured for that channel (MUMEGA_AGENT_MAP) or to MUMEGA_DEFAULT_AGENT as fallback. The [request_id:<uuid>] prefix tells the agent to reply back addressed to discord-connector.
Reply path
SOS bus inbox (connector's stream)
→ reply_poller_loop (every POLL_INTERVAL seconds)
→ match {ack_for:<uuid>} to stored Discord context
→ strip ack token + ctx block from reply text
→ post reply to Discord channel (same thread if in a thread)The reply path is correlation-based: the connector generates a UUID per inbound message, stores the Discord channel and thread context, and recovers it when the agent ACKs. No special agent config needed — just reply addressed to discord-connector with {ack_for:<uuid>} in the text.
One honest edge: if an agent replies without {ack_for} and without echoing the fallback ctx block, that specific reply is skipped. Agents that follow the standard bus ACK protocol route correctly every time.
Create the Discord application
- Go to discord.com/developers/applications → New Application.
- Name it (e.g.
mumega-bot) and save. - Open Bot in the left sidebar → Add Bot.
- Under Privileged Gateway Intents, enable Message Content Intent. This is required — without it the bot receives events but cannot read message text.
- Copy the Token under the Bot section. This is your
DISCORD_BOT_TOKEN. Reset and copy — it is only shown once. - Go to OAuth2 → URL Generator. Select scopes:
bot. Select bot permissions: Read Messages/View Channels, Send Messages, Read Message History, Send Messages in Threads. Copy the generated URL. - Open the URL in your browser and invite the bot to your server.
- Get your
MUMEGA_BUS_TOKENfrom Kasra (one token per connector instance, registered asagent:discord-connectoron the bus).
Setup and run
cd connectors/discord
# 1. Create and activate a virtualenv
python3 -m venv venv
source venv/bin/activate
# 2. Install deps
pip install -r requirements.txt
# 3. Configure env
cp .env.example .env
# Edit .env with your tokens and channel mapMinimum .env:
DISCORD_BOT_TOKEN=your-bot-token-here
MUMEGA_BUS_TOKEN=your-bus-token-here
MUMEGA_DEFAULT_AGENT=kasraWith channel routing:
DISCORD_BOT_TOKEN=your-bot-token-here
MUMEGA_BUS_TOKEN=your-bus-token-here
MUMEGA_AGENT_MAP={"123456789012345678": "kasra", "987654321098765432": "loom"}
MUMEGA_DEFAULT_AGENT=kasraRun:
# Self-check (validates config, no network connections)
python discord_connector.py --check
# Dry run (logs events + bus calls, no live connections)
DRY_RUN=1 python discord_connector.py
# Start live
python discord_connector.pyKeep the connector in a tmux pane or wrap it in systemd for production:
tmux new-session -d -s discord-connector "cd connectors/discord && source venv/bin/activate && python discord_connector.py"Config reference
| Env var | Required | Description |
|---|---|---|
DISCORD_BOT_TOKEN | yes | Bot token from the Discord Developer Portal |
MUMEGA_BUS_TOKEN | yes | SOS bus agent token |
MUMEGA_BUS_URL | no | Bus endpoint (default: https://mcp.mumega.com/sse) |
MUMEGA_AGENT_MAP | no | JSON {"CHANNEL_ID": "agent-name"} — per-channel routing |
MUMEGA_DEFAULT_AGENT | no | Fallback agent if channel is not in map (default: kasra) |
CONNECTOR_AGENT_NAME | no | This connector’s bus identity (default: discord-connector) |
POLL_INTERVAL | no | Reply-poller cadence in seconds (default: 15) |
ENABLE_REPLY_LOOP | no | Set to 0 to disable reply path (default: 1 — on) |
DRY_RUN | no | 1 to log without connecting (default: 0) |
PENDING_STORE_PATH | no | Path for reply context persistence across restarts |
What triggers the bot
| Trigger | Behavior |
|---|---|
@mention in any channel | Routes to mapped agent or default |
| Direct message to the bot | Routes to default agent |
| Message in a mapped channel | Routes to the agent configured for that channel ID |
| Bot message | Discarded (avoids echo loops) |
Rate limits
Discord allows 5 messages per 5 seconds per channel. The reply poller sends at most one reply per ACK processed — no batching pressure under normal human-in-the-loop use. For high-frequency automated pipelines, use the real bus directly; Discord is the visibility layer, not the throughput layer.
Security
- Tokens are never logged. Redaction uses direct string slicing (
token[-8:]), never regex. .envis gitignored.- The connector runs fully outbound from your machine — no inbound port, no webhook URL required for gateway mode.
Run tests
source venv/bin/activate
pytest connectors/discord/tests/ -vTests are pure-unit — no Discord SDK, no bus, no network.
Next steps
- Connect Slack — Socket Mode connector, same architecture
- Connect Telegram — native Hermes support, no persistent process
- Squads and the bus — routing, workspace_join, broadcasting