繁體中文 | English
Run Claude Code sessions from Discord, LINE, Slack, Telegram, Email, or Web UI. Each platform maps messages to project folders on your filesystem, with interactive tool approval, session persistence, and real-time streaming.
⚠️ Warning: Personal Use OnlyThis project is intended for personal use only. Sharing your Claude Code access with others or using this bot to provide Claude Code as a service may violate Anthropic's Terms of Service. Violations could result in your account being suspended or terminated. Please use responsibly.
| Platform | Connection | Project Selection | Approval UX | Media |
|---|---|---|---|---|
| Discord | WebSocket | Channel name = folder | Reaction (check/X) | Images |
| LINE | Webhook | /project <name> command |
Postback buttons | Images, Voice |
| Slack | Socket Mode | Channel name = folder | Reaction (check/X) | Images |
| Telegram | Long Polling | /project <name> command |
Inline keyboard | Images, Voice |
| IMAP IDLE | Subject tag [project-name] |
Clickable link | Image attachments | |
| Web UI | WebSocket | Dropdown selector | In-browser modal | - |
You can enable any combination of platforms simultaneously. At least one platform must be configured.
- Install Node.js (v18+) and Claude Code CLI
- Clone and install:
git clone <repository-url> cd claude-code-discord-bot npm install
- Create
.envfrom the template:cp .env.example .env
- Set
BASE_FOLDERand configure at least one platform (see Platform Setup) - Run:
npm start
User Message (Discord / LINE / Slack / Telegram / Email / Web UI)
|
v
Bot parses message, determines project folder
|
v
Spawns: claude --output-format stream-json -p 'prompt' --mcp-config ...
|
v
Claude Code runs in BASE_FOLDER/{project-name}/
|
|-- Safe tools (Read, Glob, Grep, ...) --> auto-approved
|-- Dangerous tools (Bash, Write, Edit, ...) --> asks user for approval
|
v
Results streamed back to user via platform API
- MCP Permission Server (Express.js on port 3001) handles tool approval requests
- mcp-bridge.cjs bridges Claude Code's stdio MCP protocol to the HTTP server
- Each platform has its own permission manager with native approval UX
- SQLite database stores sessions and task history
Synchronous (Discord, Slack, Web UI): One Claude process per channel/connection. Messages queue if a process is already running. Sessions persist and resume across messages.
Asynchronous (LINE, Telegram, Email): Tasks run in the background. Users can send new messages while tasks are running. Results are delivered as push notifications when complete.
By default, this bot spawns Claude Code CLI processes. Alternatively, you can use the Claude API directly without installing Claude Code CLI:
CLAUDE_MODE=api
ANTHROPIC_API_KEY=sk-ant-api03-...
ANTHROPIC_MODEL=claude-sonnet-4-20250514 # Optional
ANTHROPIC_MAX_TOKENS=8192 # Optional| Feature | CLI Mode (default) | API Mode |
|---|---|---|
| Requires Claude Code CLI | Yes | No |
| Requires ANTHROPIC_API_KEY | No | Yes |
| Available tools | All Claude Code tools | Read, Glob, Grep, Bash, Write, Edit |
| Session persistence | Via Claude Code | In-memory only |
| Cost tracking | No | Yes (per-session) |
API mode is useful if you don't have Claude Code CLI installed or want more control over API parameters.
Required for all platforms:
# Base path containing your project folders
BASE_FOLDER=/Users/you/reposYour project folders should be organized under BASE_FOLDER:
/Users/you/repos/
├── my-app/ # Discord: #my-app channel / LINE+Telegram: /project my-app / Email: [my-app]
├── api-server/
├── frontend/
└── experiments/
Create a bot at the Discord Developer Portal:
- New Application > Bot section > Copy token
- Enable Message Content Intent under Privileged Gateway Intents
- OAuth2 > URL Generator > Scopes:
bot,applications.commands - Bot Permissions: Send Messages, Use Slash Commands, Read Message History, Embed Links, Add Reactions
- Invite the bot to your server with the generated URL
DISCORD_TOKEN=your_bot_token
ALLOWED_USER_IDS=your_discord_user_id1,your_discord_user_id2
DISCORD_CHANNEL_IDS=123456789,987654321 # Optional: restrict to specific channelsHow to get your User ID: Discord Settings > Advanced > Enable Developer Mode > Right-click your name > Copy User ID
Usage: Create Discord channels matching your folder names. Send messages in any channel (except #general) to run Claude Code in the corresponding folder.
| Command | Description |
|---|---|
| Any message | Run Claude Code with your message as the prompt |
/cancel |
Cancel the current running task (session preserved) |
/clear |
Reset the current channel's session |
Approval: When Claude needs to run a dangerous tool, the bot posts a message. React with ✅ to approve or ❌ to deny. Timeout: 30 seconds.
Create a bot at the LINE Developers Console:
- Create a Messaging API channel
- Copy the Channel Access Token and Channel Secret
- Set the webhook URL to
https://<your-domain>:3001/line/webhook
LINE_CHANNEL_ACCESS_TOKEN=your_channel_access_token
LINE_CHANNEL_SECRET=your_channel_secret
LINE_ALLOWED_USER_IDS=U1234abc,U5678def # Optional: restrict accessUsage: Send direct messages to the bot. Select a project first, then send prompts.
| Command | Description |
|---|---|
/project |
List available projects |
/project <name> |
Select a project |
/result |
Get the latest task result |
/status |
Check running tasks |
/cancel |
Cancel the current running task (session preserved) |
/clear |
Clear the session for the current project |
/help |
Show help |
| Any message | Run Claude Code (requires project selected) |
| Send photo | Attach image to prompt |
| Send voice | Transcribe and run as prompt (requires Speechmatics) |
Approval: Bot sends a flex message with Approve / Deny buttons. Timeout: 5 minutes.
Note: LINE requires a public HTTPS URL for the webhook endpoint. You need a reverse proxy or tunnel (e.g., ngrok) pointing to port 3001.
Create an app at api.slack.com/apps:
- Create new app > From scratch
- Enable Socket Mode (Settings > Socket Mode) and generate an App-Level Token with
connections:writescope - App Home > Messages Tab > Check "Allow users to send Slash commands and messages from the messages tab"
- Event Subscriptions > Subscribe to bot events:
message.channels- Messages in public channelsmessage.groups- Messages in private channelsmessage.im- Direct messagesreaction_added- Reaction events for approval
- OAuth & Permissions > Bot Token Scopes:
chat:write- Send messageschannels:history,channels:read- Read public channelsgroups:history,groups:read,groups:write- Read/write private channelsim:history,im:read,im:write- Read/write direct messagesreactions:read,reactions:write- Handle approval reactionsfiles:read- Read file attachmentscommands- Slash commands
- Slash Commands > Create these commands (Request URL is not needed for Socket Mode):
/clear- Reset the session/cancel- Cancel the current task/project- Select a project
- Install to workspace and copy the Bot Token
SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_APP_TOKEN=xapp-your-app-token
SLACK_SIGNING_SECRET=your_signing_secret
SLACK_ALLOWED_USER_IDS=U01234567,U89012345 # Optional: restrict access
SLACK_CHANNEL_IDS=C01234567,C89012345 # Optional: restrict to specific channelsUsage: Invite the bot to channels matching your folder names, or send direct messages.
| Context | Project Selection |
|---|---|
| Channel | Channel name = folder (e.g., #my-app → BASE_FOLDER/my-app) |
| DM | Use /project <name> command to select |
| Command | Description |
|---|---|
| Any message | Run Claude Code with your message as the prompt |
/project |
List available projects |
/project <name> |
Select a project |
/cancel |
Cancel the current running task (session preserved) |
/clear |
Reset the current channel's session |
Approval: Bot posts an approval message. React with ✅ to approve or ❌ to deny. Timeout: 30 seconds.
Note: Slack uses Socket Mode, so no public URL is needed.
Create a bot via @BotFather:
- Send
/newbotto BotFather and follow the prompts - Copy the bot token
TELEGRAM_BOT_TOKEN=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
TELEGRAM_ALLOWED_USER_IDS=123456789,987654321 # Optional: restrict accessUsage: Send direct messages to the bot. Select a project first, then send prompts.
| Command | Description |
|---|---|
/start |
Welcome message |
/project |
List available projects |
/project <name> |
Select a project |
/result |
Get the latest task result |
/status |
Check running tasks |
/cancel |
Cancel the current running task (session preserved) |
/clear |
Clear the session for the current project |
/help |
Show help |
| Any message | Run Claude Code (requires project selected) |
| Send photo | Attach image to prompt |
| Send voice | Transcribe and run as prompt (requires Speechmatics) |
Approval: Bot sends a message with inline Approve / Deny buttons. Timeout: 5 minutes.
Note: Telegram uses long polling, so no public URL is needed.
Use any email account that supports IMAP and SMTP (Gmail, Outlook, etc.).
For Gmail: enable App Passwords (requires 2FA enabled).
EMAIL_USER=claude-bot@gmail.com
EMAIL_PASS=your_app_password
EMAIL_IMAP_HOST=imap.gmail.com # Optional, defaults shown
EMAIL_IMAP_PORT=993
EMAIL_SMTP_HOST=smtp.gmail.com
EMAIL_SMTP_PORT=587
EMAIL_ALLOWED_SENDERS=user@example.com,user2@example.com # Optional: restrict accessUsage: Send emails to the bot address. Include the project name in the subject line using brackets.
| Action | Description |
|---|---|
Subject: [my-app] fix the login bug |
Run Claude Code in the my-app folder with the email body as the prompt |
Body: /result |
Get the latest task result |
Body: /status |
Check running tasks |
Body: /cancel |
Cancel the current running task (session preserved) |
Body: /clear |
Clear the session for the project in the subject |
Body: /help |
Show help |
Approval: Bot sends an HTML email with clickable Approve / Deny links. Each link contains a one-time token. Timeout: 5 minutes.
Note: Email uses IMAP IDLE for real-time monitoring. Replies maintain the email thread via In-Reply-To and References headers.
Remote servers: If running on a remote server, set PUBLIC_URL so approval links point to the correct address:
PUBLIC_URL=https://your-domain.com:3001No external accounts needed. The Web UI runs on the same server as the MCP permission server.
WEB_UI_ENABLED=true
WEB_UI_PASSWORD=your_secret_password # Optional: leave unset for no authUsage: Open http://localhost:3001/ in your browser. Select a project from the dropdown, then type prompts.
| Action | Description |
|---|---|
| Select project dropdown | Choose which project folder to work in |
| Type message + Send | Run Claude Code with your message as the prompt |
| Cancel Task button | Cancel the current running task (session preserved) |
| Clear Session button | Reset the session for the current project |
Approval: When Claude needs to run a dangerous tool, a modal pops up in the browser with Approve / Deny buttons. Timeout: 120 seconds.
Features: Real-time streaming via WebSocket, dark theme UI, tool call tracking with status indicators.
Note: No public URL is needed. The Web UI is served from the existing Express server.
LINE and Telegram support voice messages. To enable transcription, add a Speechmatics API key:
SPEECHMATICS_API_KEY=your_api_key
SPEECHMATICS_LANGUAGE=cmn # Language code (default: cmn). Use cmn_en for Mandarin & English bilingual.Supported languages: en, cmn, cmn_en, ja, ko, fr, de, es, and many more.
Voice messages are transcribed to text and then passed to Claude Code as the prompt.
Claude Code uses various tools (read files, write files, run commands, etc.). This bot categorizes them:
Auto-approved (safe, read-only):
Read,Glob,Grep,LS,TodoRead,WebFetch,WebSearch
Requires approval (modifies filesystem or runs commands):
Bash,Write,Edit,MultiEdit,NotebookEdit,TodoWrite
Denied (unknown tools):
- Any tool not in the above lists is denied by default
When approval is needed, the bot sends a platform-native prompt and waits for the user to approve or deny. If no response is received within the timeout, the tool is denied.
| Platform | Approval Method | Timeout |
|---|---|---|
| Discord | Reaction (check/X) | 30s |
| LINE | Postback buttons | 5 min |
| Slack | Reaction (check/X) | 30s |
| Telegram | Inline keyboard | 5 min |
| HTTP link click | 5 min | |
| Web UI | Browser modal | 2 min |
To skip interactive approval for specific tools, set AUTO_APPROVE_TOOLS in your .env:
AUTO_APPROVE_TOOLS=Edit,WriteAvailable tool names for auto-approval:
| Tool | Description |
|---|---|
Bash |
Run shell commands |
Write |
Create or overwrite files |
Edit |
Edit existing files |
MultiEdit |
Edit multiple locations in a file |
TodoWrite |
Write todo items |
Comma-separated, case-sensitive. Tools not listed here will still follow the default approval flow.
# MCP server port (default: 3001)
MCP_SERVER_PORT=3001
# Claude process timeout in seconds (default: 300, max: 43200 = 12 hours)
CLAUDE_PROCESS_TIMEOUT=300
# Discord/Slack approval timeout in seconds (default: 30)
MCP_APPROVAL_TIMEOUT=30
# Default behavior on timeout: 'allow' or 'deny' (default: deny)
MCP_DEFAULT_ON_TIMEOUT=deny
# LINE approval timeout in seconds (default: 300)
LINE_APPROVAL_TIMEOUT=300
# Telegram approval timeout in seconds (default: 300)
TELEGRAM_APPROVAL_TIMEOUT=300
# Email approval timeout in seconds (default: 300)
EMAIL_APPROVAL_TIMEOUT=300
# WebUI approval timeout in seconds (default: 120)
WEBUI_APPROVAL_TIMEOUT=120
# Auto-approve specific tools without interactive approval (comma-separated)
# Available: Bash, Write, Edit, MultiEdit, TodoWrite
# AUTO_APPROVE_TOOLS=Edit,Writesrc/
├── index.ts # Entry point, initializes all enabled platforms
├── types/index.ts # Shared type definitions
├── utils/config.ts # Environment validation
├── shared/
│ ├── shell.ts # Claude CLI command builder
│ ├── process-runner.ts # Spawns and streams Claude processes
│ ├── base-permission-manager.ts # Abstract approval logic
│ ├── permissions.ts # Tool safety classification
│ └── speechmatics.ts # STT API integration
├── db/database.ts # SQLite: sessions + task results
├── mcp/server.ts # Express.js MCP permission server
└── channel/
├── discord/ # Discord.js bot
├── line/ # LINE webhook handler
├── slack/ # Slack Bolt bot (Socket Mode)
├── telegram/ # Telegraf bot (Long Polling)
├── email/ # IMAP IDLE + SMTP
└── webui/ # WebSocket + static HTML
Each channel directory contains:
client.ts— Bot client (event handling, commands)manager.ts— Claude Code session/task managementpermission-manager.ts— Platform-specific approval UXshell.ts— Platform-specific command buildermessages.ts— Message formattingtypes.ts— Type definitions
npm run test:run # Run once
npm test # Watch mode- Create
src/channel/<platform>/with the 6 standard files - Add platform to
PlatformBridgeConfig.platformunion insrc/shared/shell.ts - Add platform config to
mcp-bridge.cjs - Add MCP route in
src/mcp/server.ts - Add database tables in
src/db/database.ts(if async task model) - Add config validation in
src/utils/config.ts - Add initialization in
src/index.ts
When running, the MCP server exposes a health endpoint:
curl http://localhost:3001/health{
"status": "ok",
"server": "Claude Code Permission Server",
"version": "1.0.0",
"port": 3001
}This project was originally inspired by claude-code-discord-bot by @timoconnellaus. The initial Discord integration concept came from that project. This repository has since been substantially rewritten and expanded to support multiple platforms (LINE, Slack, Telegram, Email, Web UI), a shared architecture, and many additional features.
MIT License. See LICENSE for details.
