@maheidem/pi-slack
Pi extension: Slack with a consistent, scriptable control-panel UX.
Package details
Install @maheidem/pi-slack from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@maheidem/pi-slack- Package
@maheidem/pi-slack- Version
0.2.1- Published
- Sep 11, 2026
- Downloads
- 290/mo · 290/wk
- Author
- marcos-heidemann
- License
- MIT
- Types
- extension, skill, prompt
- Size
- 319.1 KB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"extensions": [
"./extensions/index.ts"
],
"skills": [
"./skills"
],
"prompts": [
"./prompts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-slack
Pi extension for Slack, backed by the official Slack MCP server.
After a one-time browser login it registers the server's 27 tools verbatim as
slack_* Pi tools, plus five extension-owned companion tools backed by the
Slack Web API (same token) for what the MCP catalog lacks: unread state,
mark-read, message edit/delete, and name→ID resolution. A scriptable control
panel (/slack) covers status, settings, and session management.
Two surfaces, one login
- MCP surface (27 tools) —
https://mcp.slack.com/mcp, registered verbatim from the server'stools/list(names, descriptions, schemas). - Web API surface (5 companion tools) — direct
https://slack.com/api/*calls with the same user token, added by the extension itself (v0.2.1): Slack's hosted MCP catalog has no read-state, message-edit, or message-delete tool, and the granted OAuth scopes already cover those Web API methods. All companion calls go through the same queue/refresh/retry discipline as MCP calls.
Install
pi install npm:@maheidem/pi-slack@0.2.1
# then /reload in any running session
Requires a Pi settings entry (packages) pointing at the installed package —
pi install handles that.
Login
/slack login
Opens the Slack browser OAuth flow (PKCE, user token). A localhost callback
on port 3118 (configurable) completes it; no code is pasted by hand. When the
browser can't open, /slack login prints the authorize URL for manual use.
Tokens are user tokens (xoxe.xoxp-…) with a lifetime of roughly 12 hours;
the extension refreshes them proactively before expiry and reactively (single
refresh + retry) if the server rejects one mid-session. When the refresh
itself fails, the state becomes degraded and tools stop with a clear
"run /slack login again" message.
/slack logout [--yes] drops the local tokens and clears the cached tool
catalog (the confirmation is required in non-TUI mode via --yes).
Config
Everything lives in ~/.pi/agent/slack.json (created on first load,
mode 0600 — it holds OAuth tokens). Override the location with the
PI_SLACK_CONFIG environment variable.
serverUrl— defaulthttps://mcp.slack.com/mcpclientId— shipped default; change only if you register your own Slack appredirectPort— localhost OAuth callback port (default 3118)loginTimeoutMs,requestTimeoutMs,maxResultChars,queueLimitenabledTools— empty = all 27 catalog tools; a comma list restricts registration (the 5 companion tools are never gated by it)
Inspect with /slack config get (values via /slack config set <field> <value>),
or /slack doctor for full diagnostics.
Usage
/slack control panel (TUI) / status (print mode)
/slack status connection + queue + catalog status
/slack login browser OAuth flow
/slack logout [--yes] drop tokens (confirm in TUI)
/slack test initialize handshake + tools/list probe
/slack doctor diagnostics incl. quarantine + version
/slack tools list cached catalog tool names
/slack tools refresh re-fetch tools/list now
/slack unread unread summary (Web API scan)
/slack config get|set|reset
/slack paths config file location
/slack help
The 27 tools
slack_add_list_record, slack_add_reaction, slack_complete_file_upload,
slack_create_canvas, slack_create_conversation, slack_create_list,
slack_get_file_upload_url, slack_get_reactions,
slack_list_channel_members, slack_list_user_channels, slack_read_canvas,
slack_read_channel, slack_read_file, slack_read_list, slack_read_thread,
slack_read_user_profile, slack_schedule_message, slack_search_channels,
slack_search_emojis, slack_search_public, slack_search_public_and_private,
slack_search_users, slack_send_message, slack_send_message_draft,
slack_update_canvas, slack_update_list, slack_update_list_record
Names are registered verbatim as the server reports them; a stale cached catalog is refreshed in the background at session start.
The 5 companion tools (extension-provided, Slack Web API)
slack_unread_summary — unread counts per conversation (DMs, group DMs,
public/private channels), excluding your own messages; bounded scan (20 s
deadline, 300 conversations). slack_mark_read — move a conversation's read
position (ts defaults to its latest message). slack_edit_message /
slack_delete_message — edit/delete your own messages (Slack enforces
this for user tokens). slack_resolve_channel — resolve a channel name or
query to channel IDs (top 5 ranked matches) before sending.
Companion tools register/unregister with the same lifecycle as catalog tools:
logged-out sessions expose zero slack_* tools total.
Sending messages
slack_send_message requires a channel_id (e.g. C0123456789), not a
channel name. Resolve names first:
slack_search_channels(public) /slack_search_public_and_privateslack_list_user_channelsfor the channels you're already in
Attachments use the slack_get_file_upload_url → upload →
slack_complete_file_upload pair.
Development
npm test # offline: fake MCP server on 127.0.0.1
npm run typecheck
Source of truth: extensions/ (adapter index.ts, application.ts,
config.ts, domain/, vendored ui/). Tests in tests/ include the frozen
27-name parity set and a tarball-integrity gate for the files allowlist.