You have a MacBook on your desk and a Linux server in the cloud. Both have Claude Code installed. You want to send a message from your phone on Discord and have the right machine pick it up, execute it, and report back — without ever opening a terminal. This guide shows you exactly how to set that up.
你桌上有一台 MacBook,雲端有一台 Linux server。兩台都裝了 Claude Code。你想從手機上的 Discord 發一段訊息,讓正確的機器接收、執行,然後回報結果——完全不需要開終端機。這篇指南會一步步教你怎麼做到。
The Problem: One Developer, Multiple Machines
Modern developers often work across multiple machines:
- A MacBook for frontend development
- A Linux workstation or cloud VM for backend / ML workloads
- A home server running side projects
Each machine has its own Claude Code installation. Each needs its own terminal session. Switching between machines means SSH-ing in, reattaching tmux sessions, and keeping track of which machine is doing what.
What if you could unify all of this into a single Discord server?
The idea is simple:
- Each machine runs a Discord bot that bridges Claude Code to a set of Discord channels
- Each channel maps to a specific project on a specific machine
- You send a message in
#mac-frontend, and your MacBook handles it - You send a message in
#linux-backend, and your Linux server handles it - All responses stream back to Discord in real time
This turns Discord into a unified command center for all your Claude Code instances.
問題:一個開發者,多台機器
現代開發者經常同時使用多台機器:
- MacBook 用來做前端開發
- Linux 工作站或雲端 VM 處理後端 / ML 任務
- 家裡的 server 跑 side project
每台機器都有自己的 Claude Code 安裝。每台都需要獨立的終端 session。在不同機器間切換意味著 SSH 登入、重新 attach tmux session、追蹤哪台機器正在做什麼。
如果能把這一切統一到一個 Discord server 裡呢?
概念很簡單:
- 每台機器運行一個 Discord bot,將 Claude Code 橋接到一組 Discord channel
- 每個 channel 對應特定機器上的特定專案
- 你在
#mac-frontend發訊息,MacBook 就會處理 - 你在
#linux-backend發訊息,Linux server 就會處理 - 所有回應即時串流回 Discord
這樣 Discord 就變成了所有 Claude Code 實例的統一控制中心。
Architecture Overview
The multi-machine Discord bridge pattern follows a consistent architecture regardless of which solution you choose:
Developer's Phone / Browser
|
v
Discord Server
| |
v v
#mac-chan #linux-chan
| |
v v
Bot A Bot B
(Machine A) (Machine B)
| |
v v
Claude Code Claude Code
(local) (local)Key architectural principles:
- One bot per machine: Each physical/virtual machine runs its own Discord bot process
- Channel-to-project mapping: Each Discord channel is bound to a specific project directory on a specific machine
- Outbound-only connections: Bots connect outward to Discord — no inbound ports needed, no firewall rules to configure
- Independent operation: Each bot operates independently; if Machine A goes offline, Machine B keeps working
- Local execution: Claude Code runs locally on each machine with full filesystem access — nothing is proxied through Discord
This architecture means you never need to expose SSH ports, set up VPNs, or configure reverse proxies. Discord's infrastructure handles all the networking.
架構概覽
多主機 Discord 橋接模式遵循一致的架構,無論你選擇哪個方案:
開發者的手機 / 瀏覽器
|
v
Discord Server
| |
v v
#mac-chan #linux-chan
| |
v v
Bot A Bot B
(Machine A) (Machine B)
| |
v v
Claude Code Claude Code
(local) (local)核心架構原則:
- 一台機器一個 bot:每台實體或虛擬機器運行自己的 Discord bot 程序
- Channel 對應專案:每個 Discord channel 綁定到特定機器上的特定專案目錄
- 僅出站連線:Bot 向外連接 Discord——不需要開入站 port,不需要設定防火牆規則
- 獨立運作:每個 bot 獨立運作;Machine A 離線時,Machine B 照常工作
- 本地執行:Claude Code 在每台機器上本地運行,擁有完整的檔案系統存取權——沒有任何東西透過 Discord 代理
這種架構意味著你永遠不需要暴露 SSH port、設定 VPN 或配置反向代理。Discord 的基礎設施處理所有網路連線。
Solution Landscape: Six Open-Source Projects Compared
The community has built several open-source solutions for bridging Claude Code with Discord. Here is a comprehensive comparison:
Comparison Matrix
| Feature | claudecode-discord | disco-demon | disclaude | discord-agent-bridge | tmuxcord | cc-conductor |
|---|---|---|---|---|---|---|
| Uses tmux | No (Agent SDK) | Yes | Yes | Yes | Yes | No (node-pty) |
| Bidirectional | Yes | Yes | Yes | Monitor only | Yes | Yes |
| Multi-machine | Built-in | Manual | Manual | Manual | Manual | Manual |
| Tool approval UI | Yes (buttons) | No | No | No | Yes (buttons) | No |
| Streaming output | Yes (1.5s edits) | Yes | No | 30s polling | Yes | Yes |
| File attachments | Yes | Yes | No | No | No | No |
| Persistence | DB + auto-restart | tmux + service | tmux + bg procs | tmux + daemon | tmux + bot | node-pty + daemon |
| Native tray app | Yes (3 OSes) | No | No | No | No | No |
| Language | TypeScript | Node.js | Python | TypeScript | TypeScript | TypeScript |
| Setup complexity | Medium | Low-medium | Very low | Medium | Low | Medium |
Quick Summary of Each
1. claudecode-discord — The most mature option. Uses the Claude Agent SDK directly instead of tmux scraping. Multi-machine support is a first-class feature with per-channel project registration. Includes a native tray app, tool approval buttons, streaming output, and usage dashboards.
2. disco-demon — The best tmux-based bidirectional bridge. Each Discord channel maps to one tmux session running one Claude Code instance. Supports skill installation and image attachments. Good balance of features and simplicity.
3. disclaude — The simplest option. A Python-based three-component system (Discord bot, tmux injector, CLI responder). Extremely hackable but limited in features. Best for developers who want to understand every line of code.
4. discord-agent-bridge — Monitor-only. Polls tmux every 30 seconds and sends output to Discord. Cannot send commands back. Useful only for passive monitoring.
5. tmuxcord — Thread-per-session model with ANSI color rendering. Permission prompts become Discord buttons. Smart diff polling reduces noise. Has a 24-hour idle auto-cleanup.
6. cc-conductor — Orchestrator pattern with one control channel. Each session gets its own Discord channel and detached worker process. Supports session resumability across daemon restarts.
Which Should You Choose?
- Want the most polished experience? Use claudecode-discord
- Want real tmux sessions you can attach to locally? Use disco-demon
- Want to hack and learn? Use disclaude
- Just want to monitor output? Use discord-agent-bridge
- Want per-session threads with color output? Use tmuxcord
- Want centralized orchestration? Use cc-conductor
The rest of this guide focuses on the top three: claudecode-discord (recommended), disco-demon (best tmux-based), and disclaude (simplest).
方案全景:六大開源專案比較
社群已經建立了多個開源方案來橋接 Claude Code 與 Discord。以下是完整比較:
比較矩陣
| 功能 | claudecode-discord | disco-demon | disclaude | discord-agent-bridge | tmuxcord | cc-conductor |
|---|---|---|---|---|---|---|
| 使用 tmux | 否(Agent SDK) | 是 | 是 | 是 | 是 | 否(node-pty) |
| 雙向通訊 | 是 | 是 | 是 | 僅監控 | 是 | 是 |
| 多主機支援 | 內建 | 手動 | 手動 | 手動 | 手動 | 手動 |
| 工具核准 UI | 是(按鈕) | 否 | 否 | 否 | 是(按鈕) | 否 |
| 串流輸出 | 是(1.5 秒更新) | 是 | 否 | 30 秒輪詢 | 是 | 是 |
| 檔案附件 | 是 | 是 | 否 | 否 | 否 | 否 |
| 持久化 | DB + 自動重啟 | tmux + service | tmux + 背景程序 | tmux + daemon | tmux + bot | node-pty + daemon |
| 原生 tray 應用 | 是(3 個 OS) | 否 | 否 | 否 | 否 | 否 |
| 語言 | TypeScript | Node.js | Python | TypeScript | TypeScript | TypeScript |
| 設定複雜度 | 中等 | 低至中等 | 非常低 | 中等 | 低 | 中等 |
各方案快速摘要
1. claudecode-discord —— 最成熟的選擇。直接使用 Claude Agent SDK 而非 tmux 抓取。多主機支援是一等公民功能,支援 per-channel 專案註冊。包含原生 tray 應用、工具核准按鈕、串流輸出和使用量儀表板。
2. disco-demon —— 最佳的 tmux 雙向橋接方案。每個 Discord channel 對應一個 tmux session,運行一個 Claude Code 實例。支援 skill 安裝和圖片附件。功能和簡潔度之間取得良好平衡。
3. disclaude —— 最簡單的選擇。基於 Python 的三組件系統(Discord bot、tmux injector、CLI responder)。極度可改造但功能有限。最適合想理解每一行程式碼的開發者。
4. discord-agent-bridge —— 僅監控。每 30 秒輪詢 tmux 並將輸出發送到 Discord。無法回傳指令。僅適合被動監控。
5. tmuxcord —— 每個 session 一個 thread 的模式,支援 ANSI 色彩渲染。權限提示變成 Discord 按鈕。智慧 diff 輪詢減少雜訊。有 24 小時閒置自動清理。
6. cc-conductor —— 編排器模式,一個控制 channel 管理所有 session。每個 session 有自己的 Discord channel 和分離的 worker 程序。支援跨 daemon 重啟的 session 恢復。
你該選哪個?
- 想要最完善的體驗? 用 claudecode-discord
- 想要能在本地 attach 的真正 tmux session? 用 disco-demon
- 想要改造學習? 用 disclaude
- 只想監控輸出? 用 discord-agent-bridge
- 想要 per-session thread 和彩色輸出? 用 tmuxcord
- 想要集中化編排? 用 cc-conductor
本指南接下來聚焦前三名:claudecode-discord(推薦)、disco-demon(最佳 tmux 方案)和 disclaude(最簡方案)。
Recommended Solution: claudecode-discord
Full Dual-Machine Deployment Tutorial
claudecode-discord is the most feature-complete solution. It uses the Claude Agent SDK directly, which means it does not rely on tmux scraping or send-keys hacks. Instead, it manages Claude Code sessions programmatically through the SDK, achieving persistence via a background daemon with database-backed session state.
Why it is the recommended choice:
- Multi-machine is a built-in, first-class feature
- Tool approval happens via Discord buttons (Allow / Deny)
- Output streams in real time with 1.5-second message edits
- File attachments work (send files to Claude, receive generated files)
- Native tray apps for macOS, Linux, and Windows
- Auto-restart and auto-start on boot
- Usage dashboard to track token consumption
Prerequisites (Per Machine)
Before starting, ensure each machine has:
- Node.js 20 or later — check with
node --version - Claude Code CLI installed and authenticated — check with
claude --version - Git — for cloning the repository
- A stable internet connection — bots maintain a WebSocket to Discord
Step 1: Create Two Discord Bots
You need one bot per machine. Both bots will live in the same Discord server but respond to different channels.
For Bot A (Machine A):
- Go to
https://discord.com/developers/applications - Click New Application, name it something like
Claude-MacBook - Go to the Bot tab
- Click Reset Token and copy the token — save it securely
- Enable MESSAGE CONTENT INTENT under Privileged Gateway Intents
- Go to OAuth2 tab
- Under Scopes, select:
bot,applications.commands - Under Bot Permissions, select:
- Send Messages
- Embed Links
- Read Message History
- Use Slash Commands
- Copy the generated URL and open it in your browser to invite Bot A to your server
For Bot B (Machine B):
Repeat the exact same steps, naming it something like Claude-Linux. You now have two bots in your Discord server.
Step 2: Prepare Your Discord Server
Create channels that map to your projects:
Discord Server: "My Dev Hub"
├── #mac-frontend (will be handled by Bot A)
├── #mac-api (will be handled by Bot A)
├── #linux-ml-pipeline (will be handled by Bot B)
├── #linux-infra (will be handled by Bot B)
└── #general (not mapped to any bot)Note down your Discord Server ID (Guild ID):
- Enable Developer Mode in Discord (Settings → Advanced → Developer Mode)
- Right-click your server name → Copy Server ID
Also note your Discord User ID:
- Right-click your username → Copy User ID
Step 3: Set Up Machine A
SSH into (or open a terminal on) Machine A:
# Clone the repository
git clone https://github.com/chadingTV/claudecode-discord.git
cd claudecode-discord
# Run the installer
./install.shCreate the .env file:
# .env for Machine A (MacBook)
DISCORD_BOT_TOKEN=your-bot-a-token-here
DISCORD_GUILD_ID=your-server-id
ALLOWED_USER_IDS=your-discord-user-id
BASE_PROJECT_DIR=/Users/yourname/projects| Variable | Description |
|---|---|
| DISCORD_BOT_TOKEN | The token you copied for Bot A |
| DISCORD_GUILD_ID | Your Discord server ID |
| ALLOWED_USER_IDS | Comma-separated Discord user IDs that can use the bot |
| BASE_PROJECT_DIR | Root directory where your projects live |
Start the bot:
# macOS
./mac-start.sh
# This starts the daemon + tray app
# The tray icon shows bot statusStep 4: Set Up Machine B
SSH into Machine B:
# Clone the repository
git clone https://github.com/chadingTV/claudecode-discord.git
cd claudecode-discord
# Run the installer
./install.shCreate the .env file:
# .env for Machine B (Linux Server)
DISCORD_BOT_TOKEN=your-bot-b-token-here
DISCORD_GUILD_ID=your-server-id
ALLOWED_USER_IDS=your-discord-user-id
BASE_PROJECT_DIR=/home/yourname/projectsStart the bot:
# Linux
./linux-start.shStep 5: Register Channels to Projects
In Discord, go to each channel and use the /register slash command:
In #mac-frontend:
/register path:frontend-appThis maps #mac-frontend to /Users/yourname/projects/frontend-app on Machine A.
In #mac-api:
/register path:api-serverIn #linux-ml-pipeline:
/register path:ml-pipelineThis maps #linux-ml-pipeline to /home/yourname/projects/ml-pipeline on Machine B.
In #linux-infra:
/register path:infrastructureEach bot only responds to /register commands in channels where it can see messages. Since each bot is its own application, the slash commands are scoped per bot.
Step 6: Using It
Now the setup is complete. Here is how daily usage works:
Sending a task to a specific machine:
Simply type in the appropriate channel:
In #mac-frontend:
> Add a dark mode toggle to the settings page
In #linux-ml-pipeline:
> Run the training pipeline with the new dataset and report metricsBot A picks up the first message and runs it on your MacBook. Bot B picks up the second and runs it on your Linux server.
Tool approval:
When Claude Code needs to run a potentially dangerous tool (file write, shell command, etc.), a Discord message appears with Allow and Deny buttons. Click Allow to proceed, or Deny to block the action.
File attachments:
You can attach files to your Discord messages. Claude Code receives them in the project directory. Conversely, when Claude generates files, they can be sent back as Discord attachments.
Checking session status:
The tray app (macOS/Linux/Windows) shows:
- Current active sessions
- Token usage
- Bot connection status
Step 7: Auto-Start on Boot
macOS (launchd):
The ./mac-start.sh script can configure auto-start. Alternatively, create a Launch Agent manually:
# Create the plist file
cat > ~/Library/LaunchAgents/com.claudecode.discord.plist << 'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.claudecode.discord</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/node</string>
<string>/Users/yourname/claudecode-discord/dist/index.js</string>
</array>
<key>WorkingDirectory</key>
<string>/Users/yourname/claudecode-discord</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/claudecode-discord.log</string>
<key>StandardErrorPath</key>
<string>/tmp/claudecode-discord-error.log</string>
</dict>
</plist>
PLIST
# Load it
launchctl load ~/Library/LaunchAgents/com.claudecode.discord.plistLinux (systemd):
sudo cat > /etc/systemd/system/claudecode-discord.service << 'SERVICE'
[Unit]
Description=Claude Code Discord Bot
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=yourname
WorkingDirectory=/home/yourname/claudecode-discord
ExecStart=/usr/bin/node dist/index.js
Restart=always
RestartSec=10
EnvironmentFile=/home/yourname/claudecode-discord/.env
[Install]
WantedBy=multi-user.target
SERVICE
sudo systemctl daemon-reload
sudo systemctl enable claudecode-discord
sudo systemctl start claudecode-discordThe Final Architecture
Your Phone (Discord App)
|
v
Discord Server: "My Dev Hub"
| | | |
v v v v
#mac-frontend #mac-api #linux-ml #linux-infra
| | | |
+------+-------+ +------+-------+
| |
v v
Bot A (Claude-MacBook) Bot B (Claude-Linux)
Agent SDK Session Mgr Agent SDK Session Mgr
| |
v v
Claude Code CLI Claude Code CLI
/Users/.../projects /home/.../projectsBoth bots report back to the same Discord server. You see all responses in one place. You control which machine handles what by simply choosing the right channel.
推薦方案:claudecode-discord
完整雙主機部署教學
claudecode-discord 是功能最完整的方案。它直接使用 Claude Agent SDK,不依賴 tmux 抓取或 send-keys 技巧。它透過 SDK 程式化管理 Claude Code session,靠背景 daemon 和資料庫支援的 session 狀態實現持久化。
為什麼它是推薦選擇:
- 多主機支援是內建的一等公民功能
- 工具核准透過 Discord 按鈕進行(Allow / Deny)
- 輸出以 1.5 秒訊息編輯的方式即時串流
- 檔案附件可用(向 Claude 發送檔案,接收生成的檔案)
- macOS、Linux、Windows 原生 tray 應用
- 自動重啟和開機自動啟動
- 使用量儀表板追蹤 token 消耗
前置條件(每台機器)
開始之前,確保每台機器有:
- Node.js 20 或更新版本 —— 用
node --version檢查 - Claude Code CLI 已安裝且已認證 —— 用
claude --version檢查 - Git —— 用來 clone 倉庫
- 穩定的網路連線 —— bot 需要維持與 Discord 的 WebSocket 連線
步驟 1:建立兩個 Discord Bot
你需要每台機器一個 bot。兩個 bot 都在同一個 Discord server 中,但回應不同的 channel。
Bot A(Machine A):
- 前往
https://discord.com/developers/applications - 點擊 New Application,命名為類似
Claude-MacBook - 進入 Bot 分頁
- 點擊 Reset Token 並複製 token —— 安全保存
- 在 Privileged Gateway Intents 下啟用 MESSAGE CONTENT INTENT
- 進入 OAuth2 分頁
- 在 Scopes 下選擇:
bot、applications.commands - 在 Bot Permissions 下選擇:
- Send Messages
- Embed Links
- Read Message History
- Use Slash Commands
- 複製生成的 URL 並在瀏覽器中開啟,將 Bot A 邀請到你的 server
Bot B(Machine B):
重複完全相同的步驟,命名為類似 Claude-Linux。現在你的 Discord server 中有兩個 bot。
步驟 2:準備 Discord Server
建立對應專案的 channel:
Discord Server: "My Dev Hub"
├── #mac-frontend (由 Bot A 處理)
├── #mac-api (由 Bot A 處理)
├── #linux-ml-pipeline (由 Bot B 處理)
├── #linux-infra (由 Bot B 處理)
└── #general (不對應任何 bot)記下你的 Discord Server ID(Guild ID):
- 在 Discord 中啟用開發者模式(Settings → Advanced → Developer Mode)
- 右鍵點擊 server 名稱 → Copy Server ID
同時記下你的 Discord User ID:
- 右鍵點擊你的使用者名稱 → Copy User ID
步驟 3:設定 Machine A
SSH 登入(或在 Machine A 上開啟終端):
# Clone 倉庫
git clone https://github.com/chadingTV/claudecode-discord.git
cd claudecode-discord
# 執行安裝程式
./install.sh建立 .env 檔案:
# Machine A(MacBook)的 .env
DISCORD_BOT_TOKEN=your-bot-a-token-here
DISCORD_GUILD_ID=your-server-id
ALLOWED_USER_IDS=your-discord-user-id
BASE_PROJECT_DIR=/Users/yourname/projects| 變數 | 說明 |
|---|---|
| DISCORD_BOT_TOKEN | 你為 Bot A 複製的 token |
| DISCORD_GUILD_ID | 你的 Discord server ID |
| ALLOWED_USER_IDS | 逗號分隔的允許使用 bot 的 Discord 使用者 ID |
| BASE_PROJECT_DIR | 專案所在的根目錄 |
啟動 bot:
# macOS
./mac-start.sh
# 這會啟動 daemon + tray 應用
# tray 圖示顯示 bot 狀態步驟 4:設定 Machine B
SSH 登入 Machine B:
# Clone 倉庫
git clone https://github.com/chadingTV/claudecode-discord.git
cd claudecode-discord
# 執行安裝程式
./install.sh建立 .env 檔案:
# Machine B(Linux Server)的 .env
DISCORD_BOT_TOKEN=your-bot-b-token-here
DISCORD_GUILD_ID=your-server-id
ALLOWED_USER_IDS=your-discord-user-id
BASE_PROJECT_DIR=/home/yourname/projects啟動 bot:
# Linux
./linux-start.sh步驟 5:將 Channel 註冊到專案
在 Discord 中,前往每個 channel 並使用 /register slash command:
在 #mac-frontend 中:
/register path:frontend-app這將 #mac-frontend 對應到 Machine A 上的 /Users/yourname/projects/frontend-app。
在 #mac-api 中:
/register path:api-server在 #linux-ml-pipeline 中:
/register path:ml-pipeline這將 #linux-ml-pipeline 對應到 Machine B 上的 /home/yourname/projects/ml-pipeline。
在 #linux-infra 中:
/register path:infrastructure每個 bot 只會回應它能看到訊息的 channel 中的 /register 命令。因為每個 bot 是獨立的 application,slash command 的作用範圍是 per bot 的。
步驟 6:日常使用
設定完成。以下是日常使用方式:
向特定機器發送任務:
在對應的 channel 中輸入即可:
在 #mac-frontend 中:
> 在設定頁面加一個深色模式切換開關
在 #linux-ml-pipeline 中:
> 用新的資料集跑一次 training pipeline 並回報指標Bot A 接收第一條訊息,在你的 MacBook 上執行。Bot B 接收第二條,在你的 Linux server 上執行。
工具核准:
當 Claude Code 需要執行有潛在風險的工具(寫入檔案、執行 shell 命令等)時,Discord 會出現帶有 Allow 和 Deny 按鈕的訊息。點擊 Allow 繼續,或點擊 Deny 阻止該操作。
檔案附件:
你可以在 Discord 訊息中附加檔案。Claude Code 會在專案目錄中接收它們。反過來,當 Claude 生成檔案時,也可以作為 Discord 附件傳回。
檢查 session 狀態:
tray 應用(macOS/Linux/Windows)顯示:
- 當前活躍的 session
- Token 使用量
- Bot 連線狀態
步驟 7:開機自動啟動
macOS(launchd):
./mac-start.sh 腳本可以設定自動啟動。或者手動建立 Launch Agent:
# 建立 plist 檔案
cat > ~/Library/LaunchAgents/com.claudecode.discord.plist << 'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.claudecode.discord</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/node</string>
<string>/Users/yourname/claudecode-discord/dist/index.js</string>
</array>
<key>WorkingDirectory</key>
<string>/Users/yourname/claudecode-discord</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/claudecode-discord.log</string>
<key>StandardErrorPath</key>
<string>/tmp/claudecode-discord-error.log</string>
</dict>
</plist>
PLIST
# 載入
launchctl load ~/Library/LaunchAgents/com.claudecode.discord.plistLinux(systemd):
sudo cat > /etc/systemd/system/claudecode-discord.service << 'SERVICE'
[Unit]
Description=Claude Code Discord Bot
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=yourname
WorkingDirectory=/home/yourname/claudecode-discord
ExecStart=/usr/bin/node dist/index.js
Restart=always
RestartSec=10
EnvironmentFile=/home/yourname/claudecode-discord/.env
[Install]
WantedBy=multi-user.target
SERVICE
sudo systemctl daemon-reload
sudo systemctl enable claudecode-discord
sudo systemctl start claudecode-discord最終架構
你的手機(Discord App)
|
v
Discord Server: "My Dev Hub"
| | | |
v v v v
#mac-frontend #mac-api #linux-ml #linux-infra
| | | |
+------+-------+ +------+-------+
| |
v v
Bot A (Claude-MacBook) Bot B (Claude-Linux)
Agent SDK Session Mgr Agent SDK Session Mgr
| |
v v
Claude Code CLI Claude Code CLI
/Users/.../projects /home/.../projects兩個 bot 都回報到同一個 Discord server。你在一個地方看到所有回應。你只需選擇正確的 channel 就能控制哪台機器處理什麼任務。
tmux Alternative: disco-demon
For Those Who Want Real tmux Sessions
If you prefer real tmux sessions — ones you can attach to locally and see the full terminal output — disco-demon is your best option. It uses tmux send-keys and capture-pane for full bidirectional communication with Claude Code.
Why choose disco-demon over claudecode-discord?
- You can
tmux attachto see exactly what Claude is doing in real time - You are already comfortable with tmux workflows
- You want the simplicity of "one channel = one tmux session"
- You want to install Claude Code Skills from ClawHub/GitHub directly through Discord
Architecture
Discord Channel
|
v
disco-demon (Node.js)
|
+-- send-keys --> tmux session --> Claude Code
|
+-- capture-pane <-- tmux session (output)
|
v
Discord Channel (response)Each Discord channel creates a tmux session named disco_{last4-of-guild}_{channel-name}. For example, if your Guild ID ends in a1b2 and the channel is #frontend, the tmux session is disco_a1b2_frontend.
Setup on Machine A
# Clone the repository
git clone https://github.com/QwertyMcQwertz/disco-demon.git
cd disco-demon
# Install dependencies
npm install
# Create .env
cat > .env << 'ENV'
DISCORD_TOKEN=your-bot-a-token
DISCORD_GUILD_ID=your-server-id
ALLOWED_USERS=your-discord-user-id
ALLOWED_PATHS=/Users/yourname/projects
ENVStart the bot:
npm startSetup on Machine B
Repeat the same steps with Bot B's token:
git clone https://github.com/QwertyMcQwertz/disco-demon.git
cd disco-demon
npm install
cat > .env << 'ENV'
DISCORD_TOKEN=your-bot-b-token
DISCORD_GUILD_ID=your-server-id
ALLOWED_USERS=your-discord-user-id
ALLOWED_PATHS=/home/yourname/projects
ENV
npm startCreating Sessions from Discord
In your Discord channel, use the /disco command:
/disco new myproject ~/projects/myprojectThis creates a new tmux session and starts Claude Code inside it, pointed at the specified directory.
Other commands:
/disco new {name} {path}— Create a new session/disco list— List active sessions/disco stop— Stop the current channel's session/disco skill install {url}— Install a Claude Code Skill from a URL
Attaching Locally
The killer feature of tmux-based solutions: you can attach to the session from a local terminal and see everything Claude is doing in real time.
# List disco-demon sessions
tmux ls | grep disco_
# Attach to a specific session
tmux attach -t disco_a1b2_frontendYou will see the full Claude Code terminal UI, including the thinking animation, tool calls, and output. This is particularly useful for debugging or when you want more detail than Discord provides.
Important: Do not type into the tmux session while the bot is active. Let the bot handle input via Discord. If you need to intervene, stop the bot first or use a separate tmux pane.
Image Attachments
disco-demon supports sending images to Claude Code. Simply attach an image to your Discord message, and the bot will pass it to Claude. This is useful for:
- Sharing screenshots of UI bugs
- Sending design mockups for Claude to implement
- Providing visual context for tasks
Session Persistence
tmux sessions persist across SSH disconnects by nature. But you also need the bot process itself to persist. Options:
Using pm2:
npm install -g pm2
pm2 start npm --name disco-demon -- start
pm2 save
pm2 startupUsing systemd (Linux):
sudo cat > /etc/systemd/system/disco-demon.service << 'SERVICE'
[Unit]
Description=disco-demon Discord Bot
After=network-online.target
[Service]
Type=simple
User=yourname
WorkingDirectory=/home/yourname/disco-demon
ExecStart=/usr/bin/npm start
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
SERVICE
sudo systemctl daemon-reload
sudo systemctl enable disco-demon
sudo systemctl start disco-demonUsing launchd (macOS):
cat > ~/Library/LaunchAgents/com.disco-demon.plist << 'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.disco-demon</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/npm</string>
<string>start</string>
</array>
<key>WorkingDirectory</key>
<string>/Users/yourname/disco-demon</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/disco-demon.log</string>
<key>StandardErrorPath</key>
<string>/tmp/disco-demon-error.log</string>
</dict>
</plist>
PLIST
launchctl load ~/Library/LaunchAgents/com.disco-demon.plistIdle Timeout
disco-demon has a 24-hour idle timeout. If no messages are sent to a session for 24 hours, it is automatically cleaned up. This prevents zombie tmux sessions from accumulating.
To adjust or disable this timeout, check the configuration options in the .env file or the source code.
Security Warning
disco-demon routes Discord messages directly into a tmux session running Claude Code. This means anyone who can post in the Discord channel can effectively run arbitrary commands on your machine through Claude Code.
Mitigations:
- Always set
ALLOWED_USERSin.env - Always set
ALLOWED_PATHSto restrict which directories Claude can access - Use a private Discord server — do not use this on a public server
- Consider running Claude Code with restricted permissions
tmux 替代方案:disco-demon
給想要真正 tmux session 的人
如果你偏好真正的 tmux session——可以在本地 attach 並看到完整終端輸出的那種——disco-demon 是你的最佳選擇。它使用 tmux 的 send-keys 和 capture-pane 實現與 Claude Code 的全雙向通訊。
為什麼選 disco-demon 而不是 claudecode-discord?
- 你可以
tmux attach即時看到 Claude 正在做什麼 - 你已經熟悉 tmux 工作流程
- 你想要「一個 channel = 一個 tmux session」的簡潔性
- 你想要透過 Discord 直接從 ClawHub/GitHub 安裝 Claude Code Skill
架構
Discord Channel
|
v
disco-demon (Node.js)
|
+-- send-keys --> tmux session --> Claude Code
|
+-- capture-pane <-- tmux session(輸出)
|
v
Discord Channel(回應)每個 Discord channel 會建立一個 tmux session,命名為 disco_{guild-id-後-4-碼}_{channel-名稱}。例如,如果你的 Guild ID 結尾是 a1b2 而 channel 是 #frontend,tmux session 就是 disco_a1b2_frontend。
Machine A 設定
# Clone 倉庫
git clone https://github.com/QwertyMcQwertz/disco-demon.git
cd disco-demon
# 安裝依賴
npm install
# 建立 .env
cat > .env << 'ENV'
DISCORD_TOKEN=your-bot-a-token
DISCORD_GUILD_ID=your-server-id
ALLOWED_USERS=your-discord-user-id
ALLOWED_PATHS=/Users/yourname/projects
ENV啟動 bot:
npm startMachine B 設定
用 Bot B 的 token 重複相同步驟:
git clone https://github.com/QwertyMcQwertz/disco-demon.git
cd disco-demon
npm install
cat > .env << 'ENV'
DISCORD_TOKEN=your-bot-b-token
DISCORD_GUILD_ID=your-server-id
ALLOWED_USERS=your-discord-user-id
ALLOWED_PATHS=/home/yourname/projects
ENV
npm start從 Discord 建立 Session
在你的 Discord channel 中,使用 /disco 命令:
/disco new myproject ~/projects/myproject這會建立一個新的 tmux session,並在裡面啟動 Claude Code,指向指定的目錄。
其他命令:
/disco new {name} {path}—— 建立新 session/disco list—— 列出活躍的 session/disco stop—— 停止當前 channel 的 session/disco skill install {url}—— 從 URL 安裝 Claude Code Skill
本地 Attach
tmux 方案的殺手級功能:你可以從本地終端 attach 到 session,即時看到 Claude 正在做的一切。
# 列出 disco-demon 的 session
tmux ls | grep disco_
# Attach 到特定 session
tmux attach -t disco_a1b2_frontend你會看到完整的 Claude Code 終端 UI,包括思考動畫、工具呼叫和輸出。這在除錯或你想要比 Discord 提供更多細節時特別有用。
重要: 在 bot 活躍時不要在 tmux session 中打字。讓 bot 透過 Discord 處理輸入。如果你需要介入,先停止 bot 或使用另一個 tmux pane。
圖片附件
disco-demon 支援向 Claude Code 發送圖片。只需在 Discord 訊息中附加圖片,bot 就會傳給 Claude。這對以下情況很有用:
- 分享 UI bug 的截圖
- 發送設計稿讓 Claude 實作
- 為任務提供視覺化上下文
Session 持久化
tmux session 天然在 SSH 斷線後持續存在。但你也需要讓 bot 程序本身持久化。選項:
使用 pm2:
npm install -g pm2
pm2 start npm --name disco-demon -- start
pm2 save
pm2 startup使用 systemd(Linux):
sudo cat > /etc/systemd/system/disco-demon.service << 'SERVICE'
[Unit]
Description=disco-demon Discord Bot
After=network-online.target
[Service]
Type=simple
User=yourname
WorkingDirectory=/home/yourname/disco-demon
ExecStart=/usr/bin/npm start
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
SERVICE
sudo systemctl daemon-reload
sudo systemctl enable disco-demon
sudo systemctl start disco-demon使用 launchd(macOS):
cat > ~/Library/LaunchAgents/com.disco-demon.plist << 'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.disco-demon</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/npm</string>
<string>start</string>
</array>
<key>WorkingDirectory</key>
<string>/Users/yourname/disco-demon</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/disco-demon.log</string>
<key>StandardErrorPath</key>
<string>/tmp/disco-demon-error.log</string>
</dict>
</plist>
PLIST
launchctl load ~/Library/LaunchAgents/com.disco-demon.plist閒置超時
disco-demon 有 24 小時閒置超時。如果一個 session 24 小時內沒有收到訊息,就會被自動清理。這防止殭屍 tmux session 累積。
要調整或停用此超時,請查看 .env 檔案或原始碼中的設定選項。
安全警告
disco-demon 將 Discord 訊息直接路由到運行 Claude Code 的 tmux session 中。這意味著任何能在 Discord channel 中發文的人都能透過 Claude Code 在你的機器上執行任意命令。
緩解措施:
- 一定要在
.env中設定ALLOWED_USERS - 一定要設定
ALLOWED_PATHS來限制 Claude 可以存取的目錄 - 使用私人 Discord server —— 不要在公開 server 上使用
- 考慮以受限權限運行 Claude Code
Simplest Option: disclaude
For Quick Hacking and Learning
disclaude is a minimalist Python-based solution that takes a radically simple approach. If you want to understand every line of code in your Discord-to-Claude bridge, this is the one to pick.
Architecture
disclaude has three components that work together:
Discord
|
v
bot.py (Discord bot)
|
v
SQLite DB (message queue)
|
v
injector.py (reads DB, sends to tmux)
|
v
tmux session (running Claude Code)
|
v
Claude Code calls cli.py to respond
|
v
cli.py send CHANNEL_ID "message"
|
v
Discord (response appears)How messages flow:
- A user sends a message in Discord
bot.pyreceives it and writes it to a SQLite databaseinjector.pypolls the SQLite database and sends new messages to the tmux session viasend-keys- Claude Code receives the message formatted as:
[Discord #channel | author (ch:CHANNEL_ID)]: message - A Claude Code Skill file instructs Claude to use
cli.py send CHANNEL_ID "message"to reply cli.pysends the reply back to the Discord channel
This is a delightfully hackable architecture. Each component is a small, standalone script.
Quick Setup
# Clone the repository
git clone https://github.com/boffman/disclaude.git
cd disclaude
# Create .env with your bot token and configuration
cat > .env << 'ENV'
DISCORD_TOKEN=your-bot-token
ENV
# Start everything (creates tmux session automatically)
./disclaude.shThe disclaude.sh script:
- Starts
bot.pyin the background - Creates a tmux session
- Starts Claude Code inside the tmux session with
--dangerously-skip-permissions - Starts
injector.pyin the background
How Claude Knows to Reply
disclaude uses a Claude Code Skill file (typically placed in .claude/skills/) that instructs Claude:
When you receive a message from Discord (identified by the
[Discord #channel | author (ch:CHANNEL_ID)]format), respond using the CLI tool:python cli.py send CHANNEL_ID "Your response here"
This means Claude Code itself is responsible for calling the reply function. It is not automated — Claude decides when and how to respond based on the Skill instructions.
Limitations
disclaude is intentionally minimal:
- No tool approval UI — Claude runs with
--dangerously-skip-permissions, meaning all tools are auto-approved - No streaming — responses appear all at once when Claude calls
cli.py - No file attachments — text-only communication
- Brand new project — expect rough edges
- No built-in rate limiting — you must trust your allowed users
- Single machine focus — multi-machine requires running separate instances manually
When to Use disclaude
- You want to prototype a Discord-Claude bridge quickly
- You want to understand the internals and customize the code
- You are comfortable with the security implications of
--dangerously-skip-permissions - You do not need streaming output or file attachments
最簡方案:disclaude
用於快速試驗和學習
disclaude 是一個極簡的 Python 方案,採取了一種極度簡單的方式。如果你想理解 Discord 到 Claude 橋接中的每一行程式碼,選這個就對了。
架構
disclaude 有三個協同工作的元件:
Discord
|
v
bot.py(Discord bot)
|
v
SQLite DB(訊息佇列)
|
v
injector.py(讀取 DB,發送到 tmux)
|
v
tmux session(運行 Claude Code)
|
v
Claude Code 呼叫 cli.py 回應
|
v
cli.py send CHANNEL_ID "message"
|
v
Discord(回應出現)訊息流程:
- 使用者在 Discord 中發送訊息
bot.py接收並寫入 SQLite 資料庫injector.py輪詢 SQLite 資料庫,透過send-keys將新訊息發送到 tmux session- Claude Code 收到格式化為
[Discord #channel | author (ch:CHANNEL_ID)]: message的訊息 - Claude Code Skill 檔案指示 Claude 使用
cli.py send CHANNEL_ID "message"回覆 cli.py將回覆傳回 Discord channel
這是一個非常容易改造的架構。每個元件都是小型、獨立的腳本。
快速設定
# Clone 倉庫
git clone https://github.com/boffman/disclaude.git
cd disclaude
# 建立 .env,填入你的 bot token 和設定
cat > .env << 'ENV'
DISCORD_TOKEN=your-bot-token
ENV
# 啟動所有東西(自動建立 tmux session)
./disclaude.shdisclaude.sh 腳本會:
- 在背景啟動
bot.py - 建立一個 tmux session
- 在 tmux session 中以
--dangerously-skip-permissions啟動 Claude Code - 在背景啟動
injector.py
Claude 如何知道要回覆
disclaude 使用 Claude Code Skill 檔案(通常放在 .claude/skills/ 中)來指示 Claude:
當你收到來自 Discord 的訊息(以
[Discord #channel | author (ch:CHANNEL_ID)]格式識別),使用 CLI 工具回應:python cli.py send CHANNEL_ID "Your response here"
這意味著 Claude Code 自身負責呼叫回覆函式。它不是自動化的——Claude 根據 Skill 指示決定何時以及如何回應。
限制
disclaude 是刻意極簡的:
- 沒有工具核准 UI —— Claude 以
--dangerously-skip-permissions運行,所有工具都自動核准 - 沒有串流 —— 回應在 Claude 呼叫
cli.py時一次性出現 - 沒有檔案附件 —— 純文字通訊
- 非常新的專案 —— 預期會有粗糙的邊角
- 沒有內建速率限制 —— 你必須信任允許的使用者
- 單機器導向 —— 多主機需要手動運行多個獨立實例
何時使用 disclaude
- 你想要快速原型化一個 Discord-Claude 橋接
- 你想要理解內部原理並自訂程式碼
- 你能接受
--dangerously-skip-permissions的安全性影響 - 你不需要串流輸出或檔案附件
Security Configuration
Critical for Multi-Machine Setups
When you bridge Claude Code to Discord, you are effectively creating a remote command execution interface. This section covers the security measures you must configure.
1. User Allowlists
Every solution supports restricting which Discord users can interact with the bot.
claudecode-discord:
# .env
ALLOWED_USER_IDS=123456789012345678,987654321098765432disco-demon:
# .env
ALLOWED_USERS=123456789012345678,987654321098765432disclaude: Configure in the bot.py source or .env file.
How to get Discord User IDs:
- Enable Developer Mode (Discord Settings → Advanced → Developer Mode)
- Right-click any user → Copy User ID
Always use explicit user IDs. Never rely on role-based access alone, as roles can be assigned by server admins you may not control.
2. Path Restrictions
Limit which directories Claude Code can access. This prevents a compromised or misbehaving session from accessing sensitive files outside your project directories.
claudecode-discord:
# .env
BASE_PROJECT_DIR=/Users/yourname/projectsClaude can only access subdirectories of this path.
disco-demon:
# .env
ALLOWED_PATHS=/Users/yourname/projectsdisclaude: No built-in path restriction. Claude runs with full filesystem access. You can mitigate this by running Claude Code in a container or restricted user account.
3. Private Server Requirement
Never use these tools on a public Discord server.
Even with user allowlists, a public server increases your attack surface:
- Server admins can read all channel messages, including sensitive code output
- Compromised Discord accounts of allowed users grant full access
- Discord's message history stores all your commands and Claude's responses
Recommended setup:
- Create a dedicated private Discord server
- Invite only yourself (and trusted team members if needed)
- Do not add any public bots or integrations beyond your Claude bots
- Enable two-factor authentication on your Discord account
4. The Arbitrary Command Execution Risk
The fundamental risk of all these solutions is the same: Discord messages become commands executed on your machine.
Consider these scenarios:
- Your Discord account gets compromised → attacker has shell access to all connected machines
- A teammate's account gets compromised → same result if they are in the allowlist
- You accidentally paste a malicious prompt → Claude executes it with your user's permissions
Mitigations:
Tool approval (claudecode-discord, tmuxcord): These solutions show Allow/Deny buttons before executing potentially dangerous tools. This is the strongest protection but requires you to actively monitor and approve actions.
Restricted Claude permissions: Run Claude Code without
--dangerously-skip-permissionswhen possible. This forces Claude to ask for approval before file writes and shell commands.Separate user accounts: Run the bot under a restricted OS user account that only has access to project directories.
Network segmentation: If running on cloud VMs, ensure the VM only has access to necessary resources. Use security groups / firewall rules to limit outbound access.
Regular token rotation: Periodically regenerate your Discord bot tokens and update the
.envfiles.
5. Bot Token Security
Your Discord bot token is equivalent to a password. If leaked, anyone can impersonate your bot.
- Never commit
.envfiles to git — add.envto your.gitignore - Never share bot tokens in Discord messages — even in private channels
- Use environment variables or secret managers in production deployments
- Regenerate tokens immediately if you suspect a leak
安全配置
多主機設定的關鍵
當你將 Claude Code 橋接到 Discord 時,你實際上是在建立一個遠端命令執行介面。本節涵蓋你必須配置的安全措施。
1. 使用者允許清單
每個方案都支援限制哪些 Discord 使用者可以與 bot 互動。
claudecode-discord:
# .env
ALLOWED_USER_IDS=123456789012345678,987654321098765432disco-demon:
# .env
ALLOWED_USERS=123456789012345678,987654321098765432disclaude: 在 bot.py 原始碼或 .env 檔案中配置。
如何取得 Discord User ID:
- 啟用開發者模式(Discord Settings → Advanced → Developer Mode)
- 右鍵點擊任何使用者 → Copy User ID
永遠使用明確的 user ID。不要僅依賴角色存取控制,因為角色可能被你無法控制的 server 管理員指派。
2. 路徑限制
限制 Claude Code 可以存取哪些目錄。這防止被入侵或行為異常的 session 存取專案目錄以外的敏感檔案。
claudecode-discord:
# .env
BASE_PROJECT_DIR=/Users/yourname/projectsClaude 只能存取此路徑的子目錄。
disco-demon:
# .env
ALLOWED_PATHS=/Users/yourname/projectsdisclaude: 沒有內建路徑限制。Claude 以完整檔案系統存取權運行。你可以透過在容器或受限使用者帳號中運行 Claude Code 來緩解。
3. 私人 Server 要求
絕對不要在公開的 Discord server 上使用這些工具。
即使有使用者允許清單,公開 server 也會增加你的攻擊面:
- Server 管理員可以讀取所有 channel 訊息,包括敏感的程式碼輸出
- 被入侵的允許使用者 Discord 帳號將獲得完整存取權
- Discord 的訊息歷史記錄儲存了你所有的命令和 Claude 的回應
建議設定:
- 建立一個專用的私人 Discord server
- 只邀請你自己(如有需要可邀請受信任的團隊成員)
- 除了你的 Claude bot 之外,不要添加任何公開 bot 或整合
- 在你的 Discord 帳號上啟用雙因素驗證
4. 任意命令執行風險
所有這些方案的根本風險都一樣:Discord 訊息變成在你機器上執行的命令。
考慮以下場景:
- 你的 Discord 帳號被入侵 → 攻擊者對所有連接的機器有 shell 存取權
- 團隊成員的帳號被入侵 → 如果他們在允許清單中,結果相同
- 你意外貼上惡意 prompt → Claude 以你的使用者權限執行它
緩解措施:
工具核准(claudecode-discord、tmuxcord): 這些方案在執行有潛在風險的工具前顯示 Allow/Deny 按鈕。這是最強的保護,但需要你主動監控和核准操作。
限制 Claude 權限: 盡可能不使用
--dangerously-skip-permissions運行 Claude Code。這強制 Claude 在寫入檔案和執行 shell 命令前請求核准。分離使用者帳號: 在只能存取專案目錄的受限 OS 使用者帳號下運行 bot。
網路隔離: 如果在雲端 VM 上運行,確保 VM 只能存取必要的資源。使用安全群組 / 防火牆規則限制出站存取。
定期輪換 token: 定期重新產生你的 Discord bot token 並更新
.env檔案。
5. Bot Token 安全
你的 Discord bot token 等同於密碼。如果洩漏,任何人都可以冒充你的 bot。
- 永遠不要將
.env檔案提交到 git —— 把.env加入你的.gitignore - 永遠不要在 Discord 訊息中分享 bot token —— 即使在私人 channel 也不行
- 在生產部署中使用環境變數或密鑰管理器
- 如果懷疑洩漏,立即重新產生 token
Persistence Strategies
Keeping Sessions Alive Across Reboots and Disconnects
Persistence is the key challenge in remote Claude Code management. You need two layers of persistence:
- Session persistence — the Claude Code session survives terminal disconnects
- Bot persistence — the Discord bot process survives reboots and crashes
Layer 1: tmux Session Persistence
For tmux-based solutions (disco-demon, disclaude), tmux naturally provides session persistence:
# Sessions survive SSH disconnects
ssh user@machine
tmux new -s claude-work
# Start Claude Code
claude
# Disconnect SSH — session keeps running
# Reconnect later
ssh user@machine
tmux attach -t claude-work
# Claude Code is still runningWhat kills tmux sessions:
- Machine reboot
tmux kill-servertmux kill-session -t session-name- Running out of memory (OOM killer)
What does NOT kill tmux sessions:
- SSH disconnect
- Terminal window closing
- Network interruption
- Logging out of the desktop session (on Linux servers)
For claudecode-discord (which uses Agent SDK, not tmux), session persistence is handled by the daemon's database. Sessions are automatically restored when the daemon restarts.
Layer 2: Bot Process Persistence
The bot process itself needs to survive reboots and crashes. Here are the three main approaches:
systemd (Linux — recommended):
# /etc/systemd/system/claude-bot.service
[Unit]
Description=Claude Code Discord Bot
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=yourname
WorkingDirectory=/home/yourname/claudecode-discord
ExecStart=/usr/bin/node dist/index.js
Restart=always
RestartSec=10
EnvironmentFile=/home/yourname/claudecode-discord/.env
# Resource limits (optional but recommended)
MemoryMax=2G
CPUQuota=80%
[Install]
WantedBy=multi-user.targetKey systemd commands:
# Enable auto-start on boot
sudo systemctl enable claude-bot
# Start the service
sudo systemctl start claude-bot
# Check status
sudo systemctl status claude-bot
# View logs
journalctl -u claude-bot -f
# Restart after config change
sudo systemctl restart claude-botlaunchd (macOS — recommended):
# ~/Library/LaunchAgents/com.claude.bot.plist
# (See full example in the claudecode-discord section above)Key launchd commands:
# Load (start + enable auto-start)
launchctl load ~/Library/LaunchAgents/com.claude.bot.plist
# Unload (stop + disable auto-start)
launchctl unload ~/Library/LaunchAgents/com.claude.bot.plist
# Check if running
launchctl list | grep claudepm2 (Cross-platform alternative):
# Install pm2 globally
npm install -g pm2
# Start the bot
pm2 start npm --name claude-bot -- start
# Or for a specific script
pm2 start dist/index.js --name claude-bot
# Save the process list (so pm2 knows what to restart)
pm2 save
# Generate startup script (auto-start pm2 on boot)
pm2 startup
# This outputs a command — copy and run it
# View logs
pm2 logs claude-bot
# Monitor
pm2 monitSession Resume After Crash
What happens when things go wrong?
claudecode-discord: Sessions are stored in a database. When the daemon restarts, it checks for active sessions and resumes them. This is the most robust approach.
disco-demon: tmux sessions survive bot crashes. When the bot restarts, it reconnects to existing tmux sessions by name. If a tmux session died (e.g., due to OOM), you need to create a new one via /disco new.
disclaude: If the bot crashes, the tmux session keeps running but stops receiving new messages from Discord. Restart disclaude.sh to reconnect.
Recommended Persistence Stack
For a production-grade multi-machine setup:
| Component | Machine A (macOS) | Machine B (Linux) |
|---|---|---|
| Bot process manager | launchd | systemd |
| Session persistence | Agent SDK DB | Agent SDK DB |
| Auto-restart | KeepAlive=true | Restart=always |
| Log management | /tmp/ or Console.app | journalctl |
| Boot start | RunAtLoad=true | WantedBy=multi-user |
持久化策略
讓 Session 在重啟和斷線後存活
持久化是遠端 Claude Code 管理的關鍵挑戰。你需要兩層持久化:
- Session 持久化 —— Claude Code session 在終端斷線後存活
- Bot 持久化 —— Discord bot 程序在重啟和崩潰後存活
第一層:tmux Session 持久化
對於 tmux 方案(disco-demon、disclaude),tmux 天然提供 session 持久化:
# Session 在 SSH 斷線後存活
ssh user@machine
tmux new -s claude-work
# 啟動 Claude Code
claude
# 斷開 SSH —— session 繼續運行
# 稍後重新連線
ssh user@machine
tmux attach -t claude-work
# Claude Code 仍在運行什麼會殺死 tmux session:
- 機器重啟
tmux kill-servertmux kill-session -t session-name- 記憶體用盡(OOM killer)
什麼不會殺死 tmux session:
- SSH 斷線
- 終端視窗關閉
- 網路中斷
- 登出桌面 session(在 Linux server 上)
對於 claudecode-discord(使用 Agent SDK 而非 tmux),session 持久化由 daemon 的資料庫處理。Daemon 重啟時 session 會自動恢復。
第二層:Bot 程序持久化
Bot 程序本身需要在重啟和崩潰後存活。以下是三種主要方式:
systemd(Linux —— 推薦):
# /etc/systemd/system/claude-bot.service
[Unit]
Description=Claude Code Discord Bot
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=yourname
WorkingDirectory=/home/yourname/claudecode-discord
ExecStart=/usr/bin/node dist/index.js
Restart=always
RestartSec=10
EnvironmentFile=/home/yourname/claudecode-discord/.env
# 資源限制(選用但推薦)
MemoryMax=2G
CPUQuota=80%
[Install]
WantedBy=multi-user.target重要 systemd 命令:
# 啟用開機自動啟動
sudo systemctl enable claude-bot
# 啟動服務
sudo systemctl start claude-bot
# 檢查狀態
sudo systemctl status claude-bot
# 查看日誌
journalctl -u claude-bot -f
# 設定變更後重啟
sudo systemctl restart claude-botlaunchd(macOS —— 推薦):
# ~/Library/LaunchAgents/com.claude.bot.plist
# (完整範例見上方 claudecode-discord 章節)重要 launchd 命令:
# 載入(啟動 + 啟用自動啟動)
launchctl load ~/Library/LaunchAgents/com.claude.bot.plist
# 卸載(停止 + 停用自動啟動)
launchctl unload ~/Library/LaunchAgents/com.claude.bot.plist
# 檢查是否運行中
launchctl list | grep claudepm2(跨平台替代方案):
# 全域安裝 pm2
npm install -g pm2
# 啟動 bot
pm2 start npm --name claude-bot -- start
# 或指定腳本
pm2 start dist/index.js --name claude-bot
# 儲存程序清單(讓 pm2 知道要重啟什麼)
pm2 save
# 生成啟動腳本(開機時自動啟動 pm2)
pm2 startup
# 這會輸出一個命令 —— 複製並執行它
# 查看日誌
pm2 logs claude-bot
# 監控
pm2 monit崩潰後 Session 恢復
出問題時會發生什麼?
claudecode-discord: Session 儲存在資料庫中。Daemon 重啟時會檢查活躍的 session 並恢復它們。這是最穩健的方式。
disco-demon: tmux session 在 bot 崩潰後存活。Bot 重啟時會透過名稱重新連接到現有的 tmux session。如果 tmux session 死了(例如因為 OOM),你需要透過 /disco new 建立新的。
disclaude: 如果 bot 崩潰,tmux session 繼續運行但不再從 Discord 接收新訊息。重啟 disclaude.sh 即可重新連接。
推薦的持久化方案組合
對於生產級多主機設定:
| 元件 | Machine A(macOS) | Machine B(Linux) |
|---|---|---|
| Bot 程序管理器 | launchd | systemd |
| Session 持久化 | Agent SDK DB | Agent SDK DB |
| 自動重啟 | KeepAlive=true | Restart=always |
| 日誌管理 | /tmp/ 或 Console.app | journalctl |
| 開機啟動 | RunAtLoad=true | WantedBy=multi-user |
Troubleshooting Common Issues
Bot Shows Offline in Discord
Symptoms: The bot appears gray (offline) in the Discord member list.
Causes and fixes:
Bot process is not running
bash# Check if process is alive ps aux | grep claudecode-discord # or systemctl status claude-bot # or pm2 statusInvalid bot token
- Double-check the token in
.env - Regenerate the token in the Discord Developer Portal
- Make sure there are no trailing whitespace or newline characters
- Double-check the token in
MESSAGE CONTENT INTENT not enabled
- Go to Discord Developer Portal → Your App → Bot
- Enable "MESSAGE CONTENT INTENT" under Privileged Gateway Intents
- This is required for bots in servers with 100+ members
Network issues
- The bot needs outbound HTTPS/WSS access to
discord.comandgateway.discord.gg - Check if a firewall or proxy is blocking these connections
- The bot needs outbound HTTPS/WSS access to
Bot is Online But Does Not Respond
Symptoms: The bot shows green (online) but ignores your messages.
Causes and fixes:
Your user ID is not in the allowlist
bash# Verify your user ID is in .env grep ALLOWED .envChannel not registered (claudecode-discord)
- Run
/register path:your-projectin the channel - Check bot logs for registration errors
- Run
Claude Code CLI not authenticated
bash# Test Claude Code directly claude --version claude "hello"Wrong channel — make sure you are messaging in a channel that the correct bot is monitoring
tmux Session Not Found (disco-demon / disclaude)
Symptoms: Bot says it cannot find the tmux session, or commands are not being sent.
Causes and fixes:
Session was killed
bash# List all tmux sessions tmux ls # If the session is gone, recreate it # disco-demon: /disco new myproject ~/projects/myproject # disclaude: ./disclaude.shSession name mismatch
bash# disco-demon sessions are named: disco_{last4}_{channel} tmux ls | grep disco_ # disclaude sessions have a fixed name configured in the scripttmux not installed
bash# macOS brew install tmux # Ubuntu/Debian sudo apt install tmux
Messages Are Truncated or Missing
Symptoms: Long Claude responses are cut off in Discord.
Causes and fixes:
Discord message length limit — Discord messages max out at 2000 characters. Most solutions handle this by splitting long messages, but some may truncate.
Rate limiting — Discord rate-limits bots. If Claude generates output faster than the bot can send, messages may be dropped. claudecode-discord handles this with 1.5-second message edit batching.
Bot restart during response — If the bot restarts while Claude is generating a response, the partial response may be lost.
High Memory Usage
Symptoms: The bot process consumes excessive memory over time.
Causes and fixes:
Many active sessions — Each session consumes memory. Close unused sessions.
bash# claudecode-discord: check active sessions via tray app or logs # disco-demon: /disco listMemory leak — Restart the bot periodically as a workaround.
bash# systemd sudo systemctl restart claude-bot # pm2 pm2 restart claude-botSet memory limits
bash# systemd MemoryMax=2G # pm2 pm2 start dist/index.js --max-memory-restart 2G
Two Bots Responding to the Same Channel
Symptoms: Both Bot A and Bot B respond to messages in the same channel.
Causes and fixes:
This happens when both bots have access to the same channel and both have registered it.
- Remove channel permissions — Use Discord channel permissions to restrict which bot can see which channels
- Unregister from the wrong bot — Check bot-specific settings to remove the channel registration
- Use separate categories — Create Discord channel categories with permissions scoped to each bot
Claude Code Errors Inside tmux
Symptoms: Claude Code crashes or produces errors inside the tmux session.
Causes and fixes:
Authentication expired
bash# Attach to the session tmux attach -t your-session # Re-authenticate claude auth loginRate limit hit
- Claude Code may hit API rate limits during heavy use
- Wait and retry, or check your plan's rate limits
Working directory deleted or moved
- If the project directory was moved or deleted, Claude Code will error
- Create a new session pointing to the correct directory
常見問題排除
Bot 在 Discord 中顯示離線
症狀: Bot 在 Discord 成員列表中顯示灰色(離線)。
原因與修復:
Bot 程序未運行
bash# 檢查程序是否存活 ps aux | grep claudecode-discord # 或 systemctl status claude-bot # 或 pm2 status無效的 bot token
- 再次檢查
.env中的 token - 在 Discord Developer Portal 中重新產生 token
- 確保沒有尾隨的空白或換行字元
- 再次檢查
MESSAGE CONTENT INTENT 未啟用
- 前往 Discord Developer Portal → Your App → Bot
- 在 Privileged Gateway Intents 下啟用「MESSAGE CONTENT INTENT」
- 對於超過 100 位成員的 server 中的 bot,這是必要的
網路問題
- Bot 需要到
discord.com和gateway.discord.gg的出站 HTTPS/WSS 存取 - 檢查防火牆或代理是否阻擋了這些連線
- Bot 需要到
Bot 上線但不回應
症狀: Bot 顯示綠色(上線)但忽略你的訊息。
原因與修復:
你的 user ID 不在允許清單中
bash# 驗證你的 user ID 是否在 .env 中 grep ALLOWED .envChannel 未註冊(claudecode-discord)
- 在 channel 中執行
/register path:your-project - 檢查 bot 日誌中的註冊錯誤
- 在 channel 中執行
Claude Code CLI 未認證
bash# 直接測試 Claude Code claude --version claude "hello"錯誤的 channel —— 確保你是在正確 bot 監控的 channel 中發送訊息
找不到 tmux Session(disco-demon / disclaude)
症狀: Bot 表示找不到 tmux session,或命令未被發送。
原因與修復:
Session 被殺死了
bash# 列出所有 tmux session tmux ls # 如果 session 不見了,重新建立 # disco-demon: /disco new myproject ~/projects/myproject # disclaude: ./disclaude.shSession 名稱不匹配
bash# disco-demon 的 session 命名為:disco_{後4碼}_{channel} tmux ls | grep disco_ # disclaude 的 session 有在腳本中設定的固定名稱tmux 未安裝
bash# macOS brew install tmux # Ubuntu/Debian sudo apt install tmux
訊息被截斷或遺失
症狀: 長的 Claude 回應在 Discord 中被截斷。
原因與修復:
Discord 訊息長度限制 —— Discord 訊息上限為 2000 個字元。大部分方案會分割長訊息來處理,但有些可能會截斷。
速率限制 —— Discord 對 bot 有速率限制。如果 Claude 產生輸出的速度快於 bot 能發送的速度,訊息可能被丟棄。claudecode-discord 用 1.5 秒訊息編輯批次處理來解決這個問題。
回應期間 bot 重啟 —— 如果 bot 在 Claude 產生回應時重啟,部分回應可能會遺失。
高記憶體使用量
症狀: Bot 程序隨時間消耗過多記憶體。
原因與修復:
太多活躍 session —— 每個 session 都消耗記憶體。關閉不用的 session。
bash# claudecode-discord:透過 tray 應用或日誌檢查活躍 session # disco-demon: /disco list記憶體洩漏 —— 定期重啟 bot 作為暫時解決方案。
bash# systemd sudo systemctl restart claude-bot # pm2 pm2 restart claude-bot設定記憶體限制
bash# systemd MemoryMax=2G # pm2 pm2 start dist/index.js --max-memory-restart 2G
兩個 Bot 回應同一個 Channel
症狀: Bot A 和 Bot B 都回應同一個 channel 中的訊息。
原因與修復:
當兩個 bot 都有同一個 channel 的存取權且都註冊了它時,就會發生這種情況。
- 移除 channel 權限 —— 使用 Discord channel 權限來限制哪個 bot 可以看到哪些 channel
- 從錯誤的 bot 取消註冊 —— 檢查 bot 特定的設定來移除 channel 註冊
- 使用分開的分類 —— 建立 Discord channel 分類,權限範圍設定為各自的 bot
tmux 中的 Claude Code 錯誤
症狀: Claude Code 在 tmux session 中崩潰或產生錯誤。
原因與修復:
認證過期
bash# Attach 到 session tmux attach -t your-session # 重新認證 claude auth login觸及速率限制
- Claude Code 在大量使用時可能觸及 API 速率限制
- 等待後重試,或檢查你的方案的速率限制
工作目錄被刪除或移動
- 如果專案目錄被移動或刪除,Claude Code 會出錯
- 建立一個指向正確目錄的新 session
Summary: Decision Matrix
Choose Your Solution Based on Your Priorities
| Priority | Best Choice | Why |
|---|---|---|
| Most polished experience | claudecode-discord | Agent SDK, streaming, tray app, tool approval buttons |
| Real tmux sessions | disco-demon | Full tmux integration, local attach, bidirectional |
| Learning / hacking | disclaude | Simple Python scripts, easy to understand and modify |
| Passive monitoring only | discord-agent-bridge | One-directional, low setup effort |
| Thread-per-session | tmuxcord | Clean thread model, ANSI colors, auto-cleanup |
| Centralized orchestration | cc-conductor | One control channel, session resumability |
The Recommended Multi-Machine Stack
For most developers with two machines, here is the recommended setup:
- Use claudecode-discord as your primary solution
- Create one Discord bot per machine — both in the same server
- Map channels to projects — each channel controls one project on one machine
- Enable auto-start — launchd on macOS, systemd on Linux
- Lock down security — user allowlists, path restrictions, private server, 2FA
This gives you:
- A single Discord server as your unified command center
- Real-time streaming output from both machines
- Tool approval via buttons (no auto-execution of dangerous operations)
- File attachments in both directions
- Session persistence across reboots
- A tray app for quick status checks
If You Need tmux
If you specifically need tmux sessions (perhaps for local attach, or because your workflow depends on terminal-level visibility):
- Use disco-demon as your primary solution
- Follow the same multi-bot pattern
- Add systemd/launchd for bot persistence
- Use pm2 if you want cross-platform consistency
- Remember to configure
ALLOWED_USERSandALLOWED_PATHS
Key Takeaways
- One bot per machine is the universal pattern across all solutions
- Outbound-only connections mean no firewall headaches
- Private Discord servers are non-negotiable for security
- User allowlists must always be configured — never leave them empty
- Persistence requires two layers: session persistence (tmux or DB) and bot persistence (systemd/launchd/pm2)
- Tool approval buttons (claudecode-discord, tmuxcord) are the strongest security feature — prefer solutions that offer them
The Discord-as-command-center pattern transforms multi-machine Claude Code management from a juggling act into a streamlined workflow. Set it up once, and you will wonder how you ever managed without it.
總結:決策矩陣
根據你的優先順序選擇方案
| 優先順序 | 最佳選擇 | 原因 |
|---|---|---|
| 最完善的體驗 | claudecode-discord | Agent SDK、串流、tray 應用、工具核准按鈕 |
| 真正的 tmux session | disco-demon | 完整 tmux 整合、本地 attach、雙向通訊 |
| 學習 / 改造 | disclaude | 簡單的 Python 腳本,容易理解和修改 |
| 僅被動監控 | discord-agent-bridge | 單向、低設定門檻 |
| 每 session 一個 thread | tmuxcord | 乾淨的 thread 模式、ANSI 色彩、自動清理 |
| 集中化編排 | cc-conductor | 一個控制 channel、session 可恢復性 |
推薦的多主機方案組合
對於擁有兩台機器的大多數開發者,這是推薦的設定:
- 使用 claudecode-discord 作為主要方案
- 每台機器建立一個 Discord bot —— 都在同一個 server 中
- 將 channel 對應到專案 —— 每個 channel 控制一台機器上的一個專案
- 啟用自動啟動 —— macOS 上用 launchd,Linux 上用 systemd
- 鎖定安全配置 —— 使用者允許清單、路徑限制、私人 server、雙因素驗證
這給你:
- 一個 Discord server 作為統一控制中心
- 來自兩台機器的即時串流輸出
- 透過按鈕進行工具核准(不自動執行危險操作)
- 雙向檔案附件
- 跨重啟的 session 持久化
- 快速查看狀態的 tray 應用
如果你需要 tmux
如果你特別需要 tmux session(也許是為了本地 attach,或因為你的工作流程依賴終端級的可見性):
- 使用 disco-demon 作為主要方案
- 遵循相同的多 bot 模式
- 加上 systemd/launchd 實現 bot 持久化
- 使用 pm2 如果你想要跨平台一致性
- 記得設定
ALLOWED_USERS和ALLOWED_PATHS
關鍵要點
- 每台機器一個 bot 是所有方案的通用模式
- 僅出站連線意味著沒有防火牆頭痛問題
- 私人 Discord server 在安全性上是不可妥協的
- 使用者允許清單必須始終設定——永遠不要留空
- 持久化需要兩層:session 持久化(tmux 或 DB)和 bot 持久化(systemd/launchd/pm2)
- 工具核准按鈕(claudecode-discord、tmuxcord)是最強的安全功能——優先選擇提供它們的方案
Discord 作為控制中心的模式將多主機 Claude Code 管理從一種雜耍變成了流暢的工作流程。設定一次,你會想不通以前是怎麼過來的。