@shuyhere/pi-discord-bot

A small Discord harness built around Pi primitives.

Packages

Package details

skill

Install @shuyhere/pi-discord-bot from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@shuyhere/pi-discord-bot
Package
@shuyhere/pi-discord-bot
Version
0.0.1
Published
Mar 31, 2026
Downloads
22/mo · 4/wk
Author
shuyhere
License
MIT
Types
skill
Size
159.7 KB
Dependencies
1 dependency · 4 peers
Pi manifest JSON
{
  "skills": [
    "./skills"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-discord-bot

A Discord bot for Pi that lets you use your Pi agent in DMs and servers.

It keeps Pi as the agent core and adds a Discord transport layer with:

  • one runner per conversation
  • append-only session/log files
  • Discord-native embeds, buttons, and select menus
  • approval-gated Discord admin actions
  • systemd-friendly local operation

Quick start

  1. Install Pi: Pi quick start guide
  2. Install this package:
pi install npm:@shuyhere/pi-discord-bot
  1. Start Pi and ask it to guide setup:
/skill:pi-discord-bot help me set up the bot

What users can do

In DMs:

  • help me debug this error
  • summarize this file
  • write a Python script for me

In servers:

  • @your-bot help me build a React component
  • @your-bot explain this stack trace

Text commands:

  • /help
  • /session
  • /tree
  • /model
  • /settings
  • /stop

Why use this

  • Uses Pi's shared auth, settings, models, skills, and extensions
  • Keeps Discord as a transport layer instead of reimplementing an agent
  • Supports both chat-style prompting and command-style interaction
  • Works locally and with systemd

Architecture

This project does not reimplement Pi’s core agent loop. It uses:

  • @mariozechner/pi-agent-core Agent
  • @mariozechner/pi-coding-agent AgentSession
  • SessionManager
  • SettingsManager
  • AuthStorage
  • ModelRegistry

Main files:

  • src/main.ts — startup and command routing
  • src/discord.ts — Discord transport and interaction handling
  • src/discord-ui.ts — embed/card builders and Discord UI helpers
  • src/agent.ts — Pi runner/session wiring
  • src/agent-models.ts — model resolution helpers
  • src/agent-tree.ts — session tree formatting/browser helpers
  • src/context.ts — sync log.jsonl into Pi session state
  • src/store.ts — log + attachment persistence

Features

  • DM support
  • guild support with mention gating for normal chat
  • text commands like /tree in chat
  • Discord slash commands
  • model picker cards
  • scoped model selector cards
  • settings card
  • session tree browser card
  • approval cards for destructive / mutating actions
  • detail threads in guilds for verbose output
  • reactions for progress:
    • 🤔 thinking/working
    • 🧑‍💻 tool activity
  • long-message chunking
  • image attachment support
  • file attachment download + local-path handoff to Pi tools

Commands

Supported command surface:

  • /help
  • /new
  • /name <name>
  • /session
  • /tree
  • /tree <entryId>
  • /model
  • /model <provider/model-or-search>
  • /scoped-models
  • /scoped-models <pattern[,pattern...]>
  • /scoped-models clear
  • /settings
  • /compact [instructions]
  • /reload
  • /login [provider]
  • /logout [provider]
  • /stop

Unsupported in Discord:

  • /resume
  • /fork
  • /copy
  • /export
  • /share
  • /hotkeys
  • /changelog
  • /quit
  • /exit

Install

Use as a Pi package skill

  1. Install Pi — follow the Pi quick start guide and configure your provider auth (e.g. pi login).

  2. Install this package — run in your terminal:

pi install npm:@shuyhere/pi-discord-bot
  1. Start Pi and ask your agent — just run pi and ask it to help you set up the Discord bot:
/skill:pi-discord-bot help me set up the bot

The Pi agent will walk you through creating your Discord app, configuring the token, setting up the policy file, and starting the bot. You don't need to memorize any setup steps — just ask.

Alternatively, from a local source checkout:

pi install /absolute/path/to/pi-discord-bot

See also:

  • docs/using-skill-in-pi.md

Develop or run from source

npm install

Run locally

By default, the runtime workspace is outside the repo:

$XDG_STATE_HOME/pi-discord-bot/agent

or, if XDG_STATE_HOME is unset:

~/.local/state/pi-discord-bot/agent

Run with the default external workspace:

export DISCORD_TOKEN=...
npx tsx src/main.ts

Or override it explicitly:

PI_DISCORD_BOT_WORKDIR=/absolute/path/to/pi-discord-bot-agent npx tsx src/main.ts

Or:

npm run build
npm start

Auth and model selection

Do not hardcode model choices in the bot. This project uses Pi shared auth/settings/default model flow.

The bot reads model availability from Pi’s model registry and lets you choose with Discord UI.

Discord setup

Create a Discord application and bot, then enable:

  • Message Content Intent

Recommended scopes:

  • bot
  • applications.commands

Recommended bot permissions:

  • View Channels
  • Send Messages
  • Send Messages in Threads
  • Create Public Threads
  • Create Private Threads
  • Read Message History
  • Attach Files
  • Use Slash Commands
  • Manage Channels
    • needed if you want channel/category/thread admin tools to work

Policy file

Create the runtime policy file in the external workspace:

mkdir -p ~/.local/state/pi-discord-bot/agent
cp discord-policy.example.json ~/.local/state/pi-discord-bot/agent/discord-policy.json

Or, if using a custom workspace path:

mkdir -p "$PI_DISCORD_BOT_WORKDIR"
cp discord-policy.example.json "$PI_DISCORD_BOT_WORKDIR/discord-policy.json"

Example:

{
  "allowDMs": true,
  "guildIds": ["123456789012345678"],
  "channelIds": ["234567890123456789"],
  "mentionMode": "mention-only",
  "slashCommands": {
    "enabled": true
  }
}

Notes:

  • omit guildIds to allow all guilds
  • omit channelIds to allow all channels
  • mentionMode: "mention-only" means normal non-command guild chat must mention the bot
  • text commands beginning with / are accepted without mentioning the bot
  • slash commands can be registered globally or to a guild via policy/env

Attachments

Normal Discord message attachments are handled like this:

  • images (png, jpg, jpeg, gif, webp) are passed to Pi as image input
  • other files are downloaded into the conversation attachments/ directory and their local paths are added to the prompt so Pi tools can inspect them

Slash-command attachments are not currently wired.

Runtime layout

Default runtime root:

~/.local/state/pi-discord-bot/agent/

Layout:

agent/
  discord-policy.json
  MEMORY.md
  skills/
  guild:123:channel:456/
    MEMORY.md
    log.jsonl
    context.jsonl
    attachments/
    scratch/
    skills/
  dm:999/
    ...

Operator env/config guide

For operator-focused configuration, especially if you already use Pi CLI / TUI on the same machine, see:

  • docs/operator-env-config.md
  • docs/using-skill-in-pi.md
  • docs/publishing-checklist.md
  • docs/github-release-flow.md

Those guides explain:

  • how to install the package into Pi from npm or source
  • how to use /skill:pi-discord-bot
  • ~/.config/pi-discord-bot.env
  • Pi shared auth/settings expectations
  • workspace discord-policy.json
  • systemd usage
  • troubleshooting for operators

systemd

A user service file is included:

  • pi-discord-bot.service

Typical setup:

mkdir -p ~/.config/systemd/user ~/.config
cp pi-discord-bot.service ~/.config/systemd/user/
cp pi-discord-bot.env.example ~/.config/pi-discord-bot.env
$EDITOR ~/.config/pi-discord-bot.env
systemctl --user daemon-reload
systemctl --user enable --now pi-discord-bot.service

Useful commands:

systemctl --user status pi-discord-bot.service
journalctl --user -u pi-discord-bot.service -f
systemctl --user restart pi-discord-bot.service

Troubleshooting

Slash command updated in code but not in Discord

If you register commands globally, Discord may take time to refresh the slash-command UI. The bot may already support the command even if the Discord slash menu has not updated yet.

What you can do:

  • wait for Discord to refresh global commands
  • reopen/refresh the Discord client
  • use a text command like /tree directly in chat while waiting

Text command vs slash command

There are two ways to invoke commands:

  • slash command UI: /tree, /model, etc. from Discord command picker
  • plain text command message: a normal message beginning with /

In guilds:

  • normal non-command chat still follows mention gating
  • plain text commands beginning with / are accepted without mentioning the bot

Attachments

Current attachment behavior:

  • normal message image attachments are passed as image input
  • normal message non-image files are downloaded and exposed as local files for Pi tools
  • slash-command attachments are not currently supported

Admin tools do not work

Make sure the bot has the required Discord permissions for the action. For server structure mutations, you usually need:

  • View Channels
  • Send Messages
  • Read Message History
  • Use Slash Commands
  • Manage Channels
  • Create Public Threads
  • Create Private Threads

Debugging notes

The bot logs useful runtime events through the service log, including:

  • startup and slash command registration
  • skipped messages due to policy
  • backfill activity
  • queue/update warnings

Use:

journalctl --user -u pi-discord-bot.service -f

Security / hygiene

Runtime conversation data is stored under the external workspace directory (by default ~/.local/state/pi-discord-bot/agent/) and may contain:

  • user messages
  • assistant outputs
  • attachment metadata
  • local file paths
  • tool results

Treat the workspace directory as private runtime state. Do not commit or share it.

The repo includes a .gitignore that excludes runtime state and build artifacts.