No description
Find a file
xenarathon 21039b159e prompt(boxxo): add "A second opinion (consult tool)" clause
Teaches Boxxo to reach for the new consult tool ONLY when genuinely unsure
(judgment calls, shaky factual claims) — never for routine answers, never as a
stand-in for the real homelab tools, and to weigh the panel then answer in his
own voice. Parity clause; matching versions added to the OWUI prompt variants.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 09:47:16 -04:00
tests feat(groq): small-model ladder for tiebreak/tool-select (Groq 8b → Z.ai GLM-flash → Cerebras) so an exhausted daily bucket doesn't fail closed; reads content or reasoning_content 2026-07-12 19:45:57 -04:00
.env.example build: install router_core and configure deep-think backend envs 2026-07-11 17:59:38 -04:00
.gitignore feat: Boxxo Discord bot (self-contained Ollama + MCP) 2026-07-07 15:27:39 -04:00
bot.py fix(review): ack failure must not cascade into re-delivering the private code 2026-07-11 22:47:00 -04:00
boxxo-public-prompt.md feat(books): teach Boxxo request_book (books→LazyLibrarian, not Seerr); inject identity 2026-07-12 18:24:06 -04:00
boxxo-system-prompt.md prompt(boxxo): add "A second opinion (consult tool)" clause 2026-07-13 09:47:16 -04:00
brain.py feat(cloud): multi-provider fallback ladder (Cerebras gpt-oss-120b → Groq 70b → OpenRouter free) 2026-07-12 19:35:53 -04:00
compose.yaml feat: Boxxo Discord bot (self-contained Ollama + MCP) 2026-07-07 15:27:39 -04:00
Dockerfile feat(groq): tool pre-selection (shrink deep payload) + tiebreak + local-down cloud fallback 2026-07-12 18:55:19 -04:00
groqx.py feat(groq): small-model ladder for tiebreak/tool-select (Groq 8b → Z.ai GLM-flash → Cerebras) so an exhausted daily bucket doesn't fail closed; reads content or reasoning_content 2026-07-12 19:45:57 -04:00
LICENSE feat: Boxxo Discord bot (self-contained Ollama + MCP) 2026-07-07 15:27:39 -04:00
persona.py feat(persona): blockquote the answer (monologue), bold the canned line 2026-07-07 15:40:01 -04:00
README.md feat: Boxxo Discord bot (self-contained Ollama + MCP) 2026-07-07 15:27:39 -04:00
requirements.txt build: reinstate router_core dep (boxxo-router now packaged on Forgejo main) 2026-07-12 11:23:09 -04:00

Boxxo Discord Bot

A Discord bot that puts Boxxo — the household AI assistant — on your family's Discord server. Ask Boxxo anything in a chat message and it answers with live data (weather, the family calendar, what's downloading, smart-home state, "where do I find…") and its vending-machine personality.

Boxxo is a self-contained brain: the bot talks straight to a local Ollama model and a Model Context Protocol (MCP) tool server. There is no cloud service and no Open WebUI in the loop — the same tools Boxxo uses everywhere, reachable from Discord.

🤖 Built with Claude (model: Claude Opus 4.8). Licensed GPL-3.0.


What it does

  • Dedicated channel: in a channel you designate (e.g. #boxxo), every message goes to Boxxo.
  • Anywhere else: Boxxo answers when you @mention it, or in a direct message.
  • Remembers the thread: keeps a short rolling history per channel, so follow-ups like "move it to 4" work.
  • One-liner personality: every reply ends in one of Boxxo's six canned dub phrases.
  • Type /reset (or "forget") to clear the conversation history for that channel.
How a message flows (the short version)
  1. You send a message → the bot decides if it's for Boxxo (channel / mention / DM).
  2. It sends your text + recent history to the Ollama model with the list of MCP tools.
  3. If the model wants a tool (weather, calendar, …), the bot runs it on the MCP server and feeds the result back — looping until Boxxo has an answer.
  4. The answer gets its single personality line enforced, then posted back to Discord.

Setup

1. Create the bot in Discord

  1. Go to the Discord Developer PortalNew Application → name it Boxxo.
  2. Open BotReset Token → copy the token (this is BOXXO_DISCORD_BOT_TOKEN).
  3. On the same Bot page, turn ON the Message Content Intent (under Privileged Gateway Intents). The bot cannot read messages without this.
  4. Open OAuth2 → URL Generator → tick bot → permissions Send Messages + Read Message History → open the generated URL → invite Boxxo to your family server.

2. Get your IDs

In Discord, enable Settings → Advanced → Developer Mode, then right-click to Copy ID:

  • your family server (guild) → FAMILY_GUILD_ID
  • the #boxxo channel → BOXXO_CHANNEL_ID

3. Configure

Copy .env.example to boxxo-discord.env and fill in the token + IDs. The brain-wiring defaults (OLLAMA_URL, MODEL, MCP_URL) already match the F.A.S.C. homelab — change them if yours differ.

4. Build & run

DockHand can't build images, so build on a host, then bring it up:

docker build -t boxxo-discord:latest .
docker compose -p boxxo-discord up -d

Check the logs: docker logs -f boxxo-discord → you should see Boxxo online as ….


Personalization

Setting What to change
Personality / rules boxxo-system-prompt.md (kept in sync with the Open WebUI copy — edit both).
The six dub lines persona.py (enforce_one_line) and the system prompt — keep them matched.
Which model MODEL in the env (any Ollama model with tool-calling support).
Tools Boxxo has add them to the MCP server — the bot advertises whatever the server lists.
History length HISTORY_TURNS (default 6 turns).

Companion: announcements

Boxxo can also post to the family — "tell everyone dinner's at 7" — via the announce_family tool on the MCP server (needs BOXXO_DISCORD_BOT_TOKEN + FAMILY_ANNOUNCE_CHANNEL_ID set there). That's outbound only and lives with the tool server, not this bot.


Files

  • bot.py — the Discord gateway listener + message routing.
  • brain.py — the Ollama + MCP tool loop (Boxxo's brain).
  • persona.py — the one-line personality enforcer (vendored from the Open WebUI filter).
  • boxxo-system-prompt.md — Boxxo's system prompt (vendored copy).