OMP Discord Remote

One-sentence model

OMP is the real local AI coding agent; Pi is the legacy/upstream plugin name. Run OMP, but keep PI_* environment variables because the Discord plugin reads them.

Discord message
  -> private Discord bot
  -> pi-discord-remote plugin
  -> live local OMP session
  -> OMP response/tool calls stream back into Discord thread

Golden config

Put this in <workspace-home>/.env, replace <workspace-home> with the host’s absolute workspace-home path, and keep real secrets private:

PI_CODING_AGENT_DIR=<workspace-home>/.omp/agent
PI_DISCORD_ENV_FILE=<workspace-home>/.env
PI_SKIP_VERSION_CHECK=true
 
PI_DISCORD_ENABLED=true
PI_DISCORD_BOT_TOKEN=...
PI_DISCORD_CHANNEL_IDS=...
PI_DISCORD_USER_IDS=...
PI_DISCORD_LAUNCHER_SECRET=...
PI_DISCORD_SPAWN_COMMAND=<workspace-home>/.local/bin/omp-plugin-env
PI_DISCORD_SPAWN_ARGS=--allow-home
PI_DISCORD_THREAD_NAME_PREFIX=omp
PI_DISCORD_STEER_LABEL=[discord]

Correct launch

cd "$HOME"
omp --allow-home

--allow-home keeps the working directory stable, lets plugins load the configured workspace .env, and keeps Discord-spawned child sessions on the same config root.

Spawn bridge

Use this whenever a Pi plugin wants to spawn pi:

<workspace-home>/.local/bin/omp-plugin-env

Current purpose: provide legacy Pi plugin compatibility, then execute the real OMP binary. Do not rely on a plugin default of plain pi; force spawns through this wrapper.

Discord-side controls

From the OMP TUI:

/discord-status
/discord-launcher-status
/discord-test
/discord-reconnect
/discord-mute
/discord-unmute
/discord-arm

From Discord:

/new [message]     start a new session
/session           show active session
/compact           compact context
/abort or !abort   stop running turn
/mute              silence OMP output
/unmute            resume output

Message behavior:

OMP idle + Discord message  -> queues a normal turn, reacts ✅
OMP busy + Discord message  -> steers current turn, reacts 📥

/new behavior

If /discord-arm was run:
  /new replaces current session in-process.
 
If not armed:
  /new spawns a fresh OMP process using:
  PI_DISCORD_SPAWN_COMMAND=<workspace-home>/.local/bin/omp-plugin-env
  PI_DISCORD_SPAWN_ARGS=--allow-home

File attachment upload

@mporenta/pi-discord-remote@0.3.5 does not relay file/image attachments. Tool-image previews are not the same as a Discord file upload. When Discord asks for upload, send as file attachment, or similar, use the bot token directly against Discord REST.

Local file path
  -> verify it is safe to share
  -> choose active session thread under PI_DISCORD_CHANNEL_IDS
  -> POST multipart/form-data to /api/v10/channels/{thread_or_channel}/messages
  -> payload_json.attachments[0].id = "0"
  -> file part name = files[0]

Minimum env/permissions:

  • PI_DISCORD_BOT_TOKEN
  • PI_DISCORD_CHANNEL_IDS
  • Discord perms: View Channel, Send Messages, Send Messages in Threads, Attach Files, Read Message History

Best agent behavior:

  • Prefer the active session thread with recent human text containing upload, file attachment, or share img here.
  • Fallback to the parent allowlisted channel.
  • Disable mentions with allowed_mentions: {"parse":[]}.
  • Never print or paste the bot token.
  • On 50045, compress/export a smaller file.

Launcher

127.0.0.1:8765
GET  /health
POST /new-session

Expected health shape:

{"ok":true,"ready":true,"armed":false}

PI_DISCORD_LAUNCHER_SECRET should be a long random string. If the launcher says it is running without a secret, the common cause is that .env changed after OMP booted; restart OMP.

Security rules

Allowlisted Discord users effectively get keyboard-level access to the machine. Treat the bot token, launcher secret, and allowlists like SSH credentials.

Minimum hardening:

  • Private Discord application.
  • Private guild/channel.
  • Minimal PI_DISCORD_USER_IDS allowlist.
  • Minimal PI_DISCORD_CHANNEL_IDS allowlist.
  • Never commit .env or paste secrets into Discord.
  • Do not expose 127.0.0.1:8765 directly to the internet.
  • If remote access is required, use HTTPS reverse proxy + authentication + launcher secret.

Fast failure matrix

SymptomCauseFix
Launcher says no secretEnv missing at process bootSet PI_DISCORD_LAUNCHER_SECRET, restart OMP
Messages ignoredUser/channel not allowlistedFix PI_DISCORD_USER_IDS / PI_DISCORD_CHANNEL_IDS
/discord-status has ready=falseToken, intent, permission, or gateway issueCheck bot token, Message Content Intent, outbound Discord gateway access
/new opens wrong runtimeSpawn command wrongUse <workspace-home>/.local/bin/omp-plugin-env
Child session loses configWrong CWD/envUse --allow-home and PI_DISCORD_ENV_FILE=<workspace-home>/.env
Plugin says PiLegacy namingKeep PI_* vars; runtime is still OMP
Config changes ignoredPlugin read config once at bootRestart OMP

Best operating rule

<workspace-home>/.env                         = all Pi-plugin config
<workspace-home>/.local/bin/omp-plugin-env    = Pi-spawn -> OMP bridge
<workspace-home>/.omp/agent                   = OMP agent state
 
Launch:
cd "$HOME" && omp --allow-home