yummy is a Mattermost bot bridge for pi and codex CLIs with:
- single-post progress updates (edits one bot message as work runs)
- stateless resume tokens (
/sessions,/resume) - per-channel and per-thread engine/model/reasoning preferences
- optional OAuth login helpers for OpenAI Codex and GitHub Copilot
Credit to the original pi project by Mario Zechner and contributors:
- Node.js 20+
- Mattermost bot account + token
piand/orcodexCLI installed and authenticated
npm ci
npm run build
export YUMMY_URL="https://mattermost.example.com"export YUMMY_TOKEN="YOUR_BOT_TOKEN"export YUMMY_DEFAULT_ENGINE="pi"# pi|codexexport YUMMY_ALLOWED_USERS="alice,bob,@carol"# strongly recommended
node dist/main.js /var/lib/yummyYUMMY_URL/YUMMY_TOKEN can also be set as MM_URL/MM_TOKEN.
Core:
| Variable | Required | Description |
|---|---|---|
YUMMY_URL | yes | Mattermost base URL (for example https://mattermost.example.com) |
YUMMY_TOKEN | yes | Mattermost bot token |
YUMMY_DEFAULT_ENGINE | no | pi (default) or codex |
YUMMY_ALLOWED_USERS | no | Comma/space-separated allowlist of usernames or user IDs |
PI runner:
| Variable | Required | Description |
|---|---|---|
YUMMY_PI_CMD | no | CLI command path (default pi) |
YUMMY_PI_MODEL | no | Default model |
YUMMY_PI_PROVIDER | no | Provider passed to pi --provider ... |
YUMMY_PI_EXTRA_ARGS | no | Extra CLI args |
YUMMY_PI_SESSION_DIR | no | Explicit session directory |
YUMMY_PI_THINKING | no | `off |
YUMMY_PI_TITLE | no | Display label in progress UI |
Codex runner:
| Variable | Required | Description |
|---|---|---|
YUMMY_CODEX_CMD | no | CLI command path (default codex) |
YUMMY_CODEX_EXTRA_ARGS | no | Extra CLI args (default -c notify=[]) |
YUMMY_CODEX_TITLE | no | Display label in progress UI |
YUMMY_CODEX_MODEL | no | Default model |
YUMMY_CODEX_REASONING | no | `none |
- DMs always trigger the bot.
- In channels, mentions trigger by default.
- Replies to bot messages trigger.
/trigger allcan enable non-mention channel messages for a channel/thread scope.cancelor/cancelstops the active run for the channel/thread queue.
All commands can be used in-channel or thread-scoped (thread when sent in a thread).
| Command | Description |
|---|---|
/pi <prompt> | Force pi runner for this message |
/codex <prompt> | Force codex runner for this message |
/sessions | List recent sessions |
/resume [n] [prompt] | Resume session by index or latest |
/session [n] [prompt] | Alias for /resume |
/agent [pi|codex|clear] | Get/set/clear default engine |
/model [pi|codex] <model|clear> | Get/set/clear model override |
/reasoning [pi|codex] <off|minimal|low|medium|high|xhigh|clear> | Get/set/clear reasoning override |
/trigger [mentions|all|clear] | Get/set/clear trigger mode |
/login openai-codex | Start OpenAI Codex OAuth flow |
/login github-copilot [enterprise-domain] | Start GitHub Copilot device flow |
- Saved to
~/.pi/agent/auth.json(or$PI_CODING_AGENT_DIR/auth.json). - File permissions are restricted to user-only (
0600). - Do not commit this file.
Per channel:
<channelId>/log.jsonlmessage log<channelId>/attachments/*downloaded files<channelId>/sessions.jsonlstored resume lines
Global:
prefs.jsonchannel/thread defaults and overrides
Use a dedicated directory (for example /var/lib/yummy), not the repo root.
- Run with a dedicated bot account and minimum necessary Mattermost permissions.
- Set
YUMMY_ALLOWED_USERSto limit who can invoke the bot. - Keep runtime data on persistent storage with restricted filesystem ACLs.
- Run under a process manager (
systemd, container orchestrator, etc.). - Monitor logs and rotate/retain
log.jsonlbased on your policy.
Example systemd unit:
[Unit]Description=yummy Mattermost bridge
After=network-online.target
[Service]Type=simple
WorkingDirectory=/opt/yummy
Environment=YUMMY_URL=https://mattermost.example.com
Environment=YUMMY_TOKEN=REPLACE_ME
Environment=YUMMY_DEFAULT_ENGINE=pi
Environment=YUMMY_ALLOWED_USERS=alice,bob
ExecStart=/usr/bin/node /opt/yummy/dist/main.js /var/lib/yummy
Restart=always
RestartSec=3
User=yummy
Group=yummy
[Install]WantedBy=multi-user.target