JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 551
  • Score
    100M100P100Q89817F
  • License MIT

Multi-platform chat bot (Discord + Slack) powered by Claude Code MCP channels

Package Exports

  • @serin511/compact-bot
  • @serin511/compact-bot/dist/wrapper.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@serin511/compact-bot) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Compact Bot

A self-hosted chat bridge that connects Discord and Slack to Claude Code via MCP Channel plugins. Runs on your Claude Max subscription — no API key required.

Why not the official Discord plugin?

Claude Code ships with a built-in Channels plugin — but CLI-native commands like /compact and /clear simply don't work through it. They need to be typed directly into the interactive terminal, and MCP servers have no way to do that.

This project started as a fix for that one problem: a wrapper that owns the Claude Code process and can forward PTY commands on your behalf. It then grew into a full-featured bridge with multi-platform support, session management, and more.

Official Plugin vs Compact Bot

Official Plugin This Project
Platforms Discord only Discord + Slack (simultaneous)
Session Ephemeral (new context per invocation) Persistent (always-on, shared across platforms)
Session control None /new, /clear, /compact
Model switching Manual restart /model sonnet (auto-restart)
Working directory Fixed at launch /cwd /path (auto-restart)
Screen capture N/A /capture (virtual terminal buffer)
System prompt Not configurable Custom file injection (--append-system-prompt)
Message customization N/A All bot messages overridable via JSON
Auto-recovery N/A Auto-respawn on unexpected exit

The core problem

The official plugin is spawned by Claude Code as a child MCP server. This means:

  • No PTY access — CLI commands (/compact, /clear) can't be forwarded because there's no terminal to type into
  • No lifecycle control — when Claude Code stops, everything stops, and there's no way to restart from chat
  • No state across restarts — switching models or working directories requires manually killing and restarting

Compact Bot solves this by inverting the relationship — a wrapper owns and controls the Claude Code process:

wrapper.ts (always-on)
  ├── Manages Claude Code lifecycle (spawn / kill / respawn)
  ├── Virtual terminal buffer (@xterm/headless) for screen capture
  ├── IPC socket for bidirectional control
  └── Claude Code (node-pty)
        ├── Discord MCP server
        └── Slack MCP server

The wrapper can restart Claude Code on command (/new, /model), forward CLI commands (/compact, /clear), and auto-respawn on crashes — all without losing the chat connection.

Features

  • Multi-platform — Discord and Slack run as independent MCP servers, conditionally enabled by token
  • Shared session — Both platforms share the same Claude Code context
  • Attachments — Upload images/files; Claude downloads them via download_attachment tool
  • Reply context — Discord message references and Slack threads are preserved
  • MCP toolsreply, react, edit_message, fetch_messages, download_attachment
  • Customizable messages — Override any bot message via data/messages.json
  • Custom system prompt — Append instructions via SYSTEM_PROMPT_PATH

Prerequisites

  • Node.js >= 20
  • Claude Code CLI installed and authenticated (claude --version)
  • Claude Max subscription (logged in via claude login)
  • Build toolsbuild-essential / python3 for node-pty compilation
  • At least one of: Discord Bot Token or Slack Bot Token

Quick Start

npx @serin511/compact-bot init   # interactive setup → ~/.config/compact-bot/.env
npx @serin511/compact-bot        # run from anywhere

From source

git clone https://github.com/Serin511/Compact-Bot.git
cd Compact-Bot
npm install
cp .env.example .env   # edit with your tokens
npm run build
npm start

Setup

Discord Bot

  1. Go to Discord Developer PortalNew Application
  2. Bot → Enable all Privileged Gateway Intents:
    • Presence Intent
    • Server Members Intent
    • Message Content Intent (required)
  3. Copy the bot token → paste into .env as DISCORD_BOT_TOKEN
  4. OAuth2URL Generator → Scopes: bot → Permissions:
    • Send Messages / Send Messages in Threads
    • Read Message History
    • Attach Files / Add Reactions
  5. Open the generated URL to invite the bot to your server

Slack Bot

  1. Go to Slack APICreate New AppFrom scratch
  2. Socket Mode → Enable → Create App-Level Token (connections:write) → copy xapp-... token
  3. OAuth & Permissions → Add Bot Token Scopes:
    • channels:history, channels:read, groups:history, groups:read
    • im:history, im:read, im:write, mpim:history, mpim:read
    • chat:write, files:read, files:write, reactions:write, users:read
  4. Install to Workspace → copy Bot User OAuth Token (xoxb-...)
  5. Event Subscriptions → Enable → Subscribe to bot events:
    • message.channels, message.groups, message.im, message.mpim
  6. App Home → Enable Messages Tab and allow messages from users
  7. Paste tokens into .env as SLACK_BOT_TOKEN and SLACK_APP_TOKEN
  8. Invite the bot to channels: /invite @botname

Environment Variables

# Platform tokens (at least one required)
DISCORD_BOT_TOKEN=
SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...

# Optional
# DEFAULT_MODEL=claude-sonnet-4-6     # empty = CLI default
# DEFAULT_CWD=~/projects              # empty = current directory
MAX_TURNS=50                           # 0 = unlimited
ALLOWED_CHANNEL_IDS=                   # comma-separated, empty = all
SLACK_ALLOWED_CHANNEL_IDS=
# CLAUDE_PATH=claude                   # defaults to "claude" from PATH
# DANGEROUSLY_SKIP_PERMISSIONS=true    # pass --dangerously-skip-permissions
SYSTEM_PROMPT_PATH=data/system-prompt.txt
VERBOSE=false

Commands

All commands work from both Discord and Slack.

Command Description
/new Start a fresh session (kills and respawns Claude Code)
/clear Clear current context (forwarded to CLI)
/compact [hint] Compress context with optional focus hint
/model <name> Switch model — sonnet, opus, haiku, or full model ID
/cwd <path> Change Claude Code's working directory
/capture [--all] Capture the current CLI screen as a code block. Default sends only the visible viewport as one message; add --all to dump the full scrollback. Works even while Claude Code is waiting for user input
/help Show available commands

Any other message is forwarded to Claude as a channel notification.

Running in Production

Claude Code requires an interactive PTY, so use tmux or screen:

tmux new-session -d -s claude-bot 'npm start'

# Attach to view logs
tmux attach -t claude-bot

Message Customization

Create data/messages.json to override any bot message:

{
  "newSession": "Starting fresh session...",
  "captureRequested": "Capturing screen..."
}

See src/messages.ts for all available keys and template variables.

Custom System Prompt

Create a text file and point SYSTEM_PROMPT_PATH to it:

echo "Always respond in English. Be concise." > data/system-prompt.txt

The content is injected via --append-system-prompt when Claude Code starts.

Troubleshooting

Bot doesn't respond to messages

  • Verify Message Content Intent is enabled (Discord Developer Portal → Bot)
  • Check ALLOWED_CHANNEL_IDS — empty means all channels
  • Ensure the bot has read/write permissions in the channel

Claude CLI auth error

claude auth status
claude login

node-pty build fails

sudo apt install build-essential python3
npm rebuild node-pty

Session feels stuck

  • Send /new to hard-restart Claude Code
  • Send /clear to reset context without restarting

License

MIT