A production-ready Discord bot that aggregates messages from configured channels, summarizes them via local Ollama, and DMs you daily and weekly.
- Daily summary — Messages from configured channels summarized and sent via DM at a scheduled time
- Weekly summary — Last 7 days of daily summaries aggregated into a weekly digest
- 7-day retention — Summaries stored in SQLite for weekly rollup; old data pruned automatically
- Python 3.11+
- Ollama running locally with a model (e.g.
ollama pull llama3.2) - Discord bot token and server access for the channels you want to monitor
-
Create a Discord application and bot
-
Invite the bot to your servers with "Read Message History" and "Send Messages" (for DMs)
-
Install Ollama and pull a model:
ollama pull llama3.2 -
Copy
.env.exampleto.envand fill in values:cp .env.example .env
-
Run with Docker:
docker-compose up -d
Or run locally:
python -m venv .venv source .venv/bin/activate # or `.\\.venv\\Scripts\\activate` on Windows pip install -r requirements.txt python -m src.main
| Variable | Description |
|---|---|
DISCORD_TOKEN |
Bot token |
DISCORD_USER_ID |
Your Discord user ID (recipient of summaries) |
CHANNEL_IDS |
Comma-separated channel IDs to monitor |
OLLAMA_HOST |
Ollama API URL (use http://host.docker.internal:11434 in Docker to reach host Ollama) |
OLLAMA_MODEL |
Model name (e.g. llama3.2, mistral) |
SUMMARY_UTC_HOUR |
Hour for daily summary (0–23) |
SUMMARY_UTC_MINUTE |
Minute for daily summary |
SUMMARY_WEEKLY_DAY |
Day of week for weekly summary (0=Mon, 6=Sun) |
SUMMARY_WEEKLY_UTC_HOUR |
Hour for weekly summary |
SUMMARY_WEEKLY_UTC_MINUTE |
Minute for weekly summary |
- Bot must be in the server and have Read Message History in each monitored channel
- Ollama must be reachable from the container (e.g.
host.docker.internalon Mac/Windows) - Only the last 500 messages per channel per run are collected
If Cortex runs in Docker and cannot reach Ollama:
-
Ollama must listen on all interfaces — By default Ollama binds to
127.0.0.1, which is unreachable from a container. On the host, start Ollama with:OLLAMA_HOST=0.0.0.0 ollama serve
Or set
OLLAMA_HOST=0.0.0.0in your shell before runningollama serve. If Ollama runs as a service, configure it to listen on0.0.0.0. -
Use the right
OLLAMA_HOSTin .env — Inside the container,localhostrefers to the container, not your machine. In.envset:OLLAMA_HOST=http://host.docker.internal:11434(Mac/Windows Docker Desktop). On Linux,
host.docker.internalis not defined by default — add todocker-compose.ymlunder the service:extra_hosts: - "host.docker.internal:host-gateway"
-
Verify Ollama is reachable — On the host:
curl http://localhost:11434/api/tags. From inside the container:docker exec cortex curl -s http://host.docker.internal:11434/api/tagsA JSON response means Ollama is reachable.
If Ollama is not installed or you want a proper systemd service:
-
Install Ollama (if needed):
curl -fsSL https://ollama.com/install.sh | shThis creates the
ollamauser and installs the systemd unit. -
Stop any running Ollama so port 11434 is free:
sudo systemctl stop ollama pkill ollama # fallback if not managed by systemd -
Configure Ollama to listen on all interfaces (required for Docker). Use an override file so updates do not overwrite your config:
sudo mkdir -p /etc/systemd/system/ollama.service.d printf '[Service]\nEnvironment="OLLAMA_HOST=0.0.0.0"\n' | sudo tee /etc/systemd/system/ollama.service.d/override.conf
-
Reload, enable, and start:
sudo systemctl daemon-reload sudo systemctl enable ollama sudo systemctl start ollama -
Verify — Ollama should listen on
0.0.0.0:11434:ss -tlnp | grep 11434 # Expected: 0.0.0.0:11434 (not 127.0.0.1) curl -s http://localhost:11434/api/tags
-
Pull a model (once):
ollama pull llama3.2
Useful commands:
sudo systemctl status ollama— check statussudo systemctl restart ollama— restart after config changessudo journalctl -u ollama -f— follow logs