Skip to content

Serin511/Compact-Bot

Repository files navigation

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

Via npx (recommended)

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 Capture the current CLI screen as a code block
/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

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors