mira-pi
Pi extension for Discord project threads
Package details
Install mira-pi from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:mira-pi- Package
mira-pi- Version
0.2.0- Published
- Jun 8, 2026
- Downloads
- not available
- Author
- waveringana
- License
- unknown
- Types
- extension
- Size
- 31.6 KB
- Dependencies
- 1 dependency · 2 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
mira-pi
a pi extension that connects a pi agent to discord via project threads. it uses discord.js to listen for messages and registers tools so the agent can interact with threads.
install with pi install npm:mira-pi
how it works
the extension runs inside the pi runtime. on startup it:
- loads config from env vars,
.pi/discord.json, and~/.pi/discord.json - restores the thread registry from
~/.mira/registry.json - connects to discord via discord.js (listening for
messageCreateevents) - registers five tools that the agent can call
when a message arrives in a project thread, the extension either passes it to a
waiting wait_for_message call, queues it, or pushes it to the agent via
pi.sendUserMessage().
config
config is loaded from three sources, highest priority first:
| priority | source | notes |
|---|---|---|
| 1 | env vars | DISCORD_TOKEN, DISCORD_CHANNEL_ID, MIRA_PROJECT |
| 2 | .pi/discord.json |
project-local override |
| 3 | ~/.pi/discord.json |
global fallback |
{
"token": "your-bot-token",
"channelId": "parent-channel-id",
"project": "optional-override"
}
project defaults to the basename of the current working directory. set
MIRA_PROJECT or the json key to override it. placeholder values like
"your-bot-token" are treated as empty so example configs don't break things.
message flow
discord message arrives (messageCreate)
│
├─ not a thread? → ignore
├─ thread name ≠ project? → ignore
├─ author is a bot? → ignore
│
├─ wait_for_message is waiting? → resolve the promise, wake the agent
├─ queue is empty, agent is in session? → pi.sendUserMessage() to push it
└─ otherwise → queue it for later
the wait_for_message tool blocks until a message comes in or the timeout
expires. the queue drains into wait_for_message first — if there's a queued
message when the tool is called, it returns immediately.
registry
thread metadata is persisted to ~/.mira/registry.json:
{
"threads": {
"my-project": {
"threadId": "1513348392011694264",
"project": "my-project",
"name": "my-project",
"parentChannelId": "1513094027011166279",
"createdAt": "2026-06-08T00:00:00.000Z"
}
}
}
this survives restarts so find_or_create_thread can return existing threads
without hitting the discord api.
tools
the extension registers these tools with the pi runtime:
| tool | description |
|---|---|
find_or_create_thread |
look up a thread in the registry or create a new one. posts a link in the parent channel on creation |
send_message |
send a message to a thread by id |
read_messages |
fetch recent messages (default 20, chronological). includes the agent's own messages |
list_threads |
list all tracked project threads from the registry |
wait_for_message |
block until a message arrives. timeout in seconds (default 300) |
install
mkdir -p ~/.pi/agent/extensions/mira
cp index.ts package.json ~/.pi/agent/extensions/mira/
npm --prefix ~/.pi/agent/extensions/mira install --omit=dev
dependencies
discord.js^14 — discord gateway client@earendil-works/pi-coding-agent(peer) — pi extension api typestypebox(peer) — runtime tool parameter validation