claude-telegram-mirror
v0.1.27
Published
Bidirectional Telegram integration for Claude Code CLI - monitor and control your Claude Code sessions from Telegram
Maintainers
Readme
Claude Code Telegram Mirror
Bidirectional communication between Claude Code CLI and Telegram. Control your Claude Code sessions from your phone.
Supported platforms: Linux, macOS
Installation
npm install -g claude-telegram-mirror
ctm setup # Interactive setup wizardThe setup wizard guides you through:
- Creating a Telegram bot via @BotFather
- Disabling privacy mode (critical for group messages)
- Setting up a supergroup with Topics
- Verifying bot permissions
- Installing hooks and the system service
Features
- CLI to Telegram: Mirror Claude's responses, tool usage, and notifications
- Telegram to CLI: Send prompts from Telegram directly to Claude Code
- Stop/Interrupt: Type
stopin Telegram to send Ctrl+C and halt Claude mid-process - Session Threading: Each Claude session gets its own Forum Topic
- Multi-System Support: Run separate daemons on multiple machines
- Compaction Notifications: Get notified when Claude summarizes context
Quick Start
# 1. Install globally
npm install -g claude-telegram-mirror
# 2. Run interactive setup (creates bot, configures everything)
ctm setup
# 3. Start the daemon
ctm start
# 4. Run Claude in tmux
tmux new -s claude
claudeCLI Commands
# Setup & diagnostics
ctm setup # Interactive setup wizard
ctm doctor # Diagnose configuration issues
# Daemon control
ctm start # Start daemon (foreground mode)
ctm stop # Stop running daemon
ctm stop --force # Force stop if graceful shutdown fails
ctm restart # Restart daemon
ctm status # Show daemon status, config, and hooks
ctm config --test # Test Telegram connection
# Hook management
ctm install-hooks # Install global hooks
ctm install-hooks -p # Install to current project's .claude/
ctm uninstall-hooks # Remove hooks
ctm hooks # Show hook status
# OS service management (optional, for auto-start on boot)
ctm service install # Install as systemd/launchd service
ctm service uninstall # Remove system service
ctm service start # Start via service manager
ctm service stop # Stop via service manager
ctm service restart # Restart via service manager
ctm service status # Show service statusNote: The top-level ctm stop and ctm restart commands work for both direct daemon mode and OS service mode. They automatically detect how the daemon is running and use the appropriate method.
Telegram Commands
Once connected, you can control Claude from Telegram:
| Command | Action |
|---------|--------|
| Any text | Sends to Claude as input |
| stop | Sends Escape to pause Claude |
| kill | Sends Ctrl-C to exit Claude entirely |
See docs/ARCHITECTURE.md for additional command aliases.
Tool Approval Buttons
When Claude requests to use a tool that requires permission (Write, Edit, Bash with non-safe commands), you'll see approval buttons in Telegram:
| Button | Action | |--------|--------| | Approve | Allow the tool to execute | | Reject | Deny this specific tool execution | | Abort | Stop the entire Claude session | | Details | View full tool input parameters |
Note: Approval buttons only appear when running Claude in normal mode. They do not appear when using --dangerously-skip-permissions mode. If you don't respond within 5 minutes, Claude will fall back to asking for approval in the CLI terminal.
Architecture
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Claude Code │────▶│ Bridge Daemon │────▶│ Telegram │
│ CLI │◀────│ │◀────│ Bot │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │
│ hooks │ Unix socket
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ PreToolUse: │────▶│ Socket Server │
│ Node.js handler│◀────│ (bidirectional)│
│ (with approval)│ │ │
├─────────────────┤ │ │
│ Other hooks: │────▶│ │
│ Bash script │ │ │
│ (fire & forget)│ │ │
└─────────────────┘ └─────────────────┘Flow:
- Claude Code hooks capture events (prompts, responses, tool use)
- PreToolUse: Node.js handler sends approval request, waits for Telegram response
- Other hooks: Bash script sends JSON and exits immediately (faster)
- Bridge forwards messages to Telegram Forum Topic
- Telegram replies are injected into CLI via
tmux send-keys - Stop commands send
Ctrl-Cto interrupt Claude
Multi-System Architecture
When running Claude Code on multiple machines, each system needs its own bot to avoid Telegram API conflicts (error 409: only one polling connection per bot token is allowed).
The model:
- One daemon per host - Each machine runs its own bridge daemon
- One bot per daemon - Each daemon uses a unique Telegram bot
- Multiple sessions per host - One daemon handles all Claude sessions on that machine
- Shared supergroup - All bots post to the same Telegram supergroup
Setup for Multiple Systems
Create one bot per system via @BotFather
- System A:
@claude_mirror_system_a_bot - System B:
@claude_mirror_system_b_bot
- System A:
Add all bots to the same supergroup with admin permissions
Configure each system with its own bot token:
# On System A (~/.telegram-env) export TELEGRAM_BOT_TOKEN="token-for-system-a-bot" export TELEGRAM_CHAT_ID="-100shared-group-id" # On System B (~/.telegram-env) export TELEGRAM_BOT_TOKEN="token-for-system-b-bot" export TELEGRAM_CHAT_ID="-100shared-group-id" # Same group!Each daemon creates topics for its sessions - Messages route correctly because each daemon only processes topics it created.
Prerequisites
- Node.js 18+
- Claude Code CLI
- tmux (for bidirectional communication)
- jq (JSON processing)
- nc (netcat, for socket communication)
- Telegram account
Telegram Setup
1. Create a Bot
- Message @BotFather →
/newbot - Choose name and username (must end in
bot) - Save the API token
2. Create Supergroup with Topics
- Create a new group in Telegram
- Add your bot to the group
- Group Settings → Enable Topics
3. Make Bot an Admin
- Group Settings → Administrators → Add your bot
- Enable: Manage Topics, Post Messages
4. Get Chat ID
- Send any message in the group
- Run the helper script:
Or manually:./scripts/get-chat-id.sh YOUR_BOT_TOKENhttps://api.telegram.org/botYOUR_TOKEN/getUpdates - Copy the chat ID (supergroups start with
-100)
5. Disable Privacy Mode
- @BotFather →
/mybots→ Select bot - Bot Settings → Group Privacy → Turn off
Configuration
Environment Variables
Create ~/.telegram-env:
export TELEGRAM_BOT_TOKEN="123456789:ABCdefGHIjklMNOpqrsTUVwxyz"
export TELEGRAM_CHAT_ID="-1001234567890"
export TELEGRAM_MIRROR=true
# Optional:
# export TELEGRAM_MIRROR_VERBOSE=true
# export TELEGRAM_BRIDGE_SOCKET=~/.config/claude-telegram-mirror/bridge.sock
# export TELEGRAM_STALE_SESSION_TIMEOUT_HOURS=72 # Auto-cleanup dead sessions (default: 72)Source in your shell profile (~/.bashrc or ~/.zshrc):
[[ -f ~/.telegram-env ]] && source ~/.telegram-envConfig File (Alternative)
The ctm setup wizard creates ~/.config/claude-telegram-mirror/config.json:
{
"botToken": "your-token",
"chatId": -1001234567890,
"enabled": true,
"verbose": true
}Environment variables take precedence over config file values.
Test Connection
ctm doctor
# Checks: Node.js, config, hooks, socket, tmux, systemd, Telegram APIProject-Level Hooks
If your project has .claude/settings.json with custom hooks, global hooks are ignored. Install hooks to the project:
cd /path/to/your/project
ctm install-hooks --project
# or shorthand:
ctm install-hooks -pThe installer will prompt you to set up project-level hooks during installation. You can also add them later to any project.
How Messages Flow
| Direction | Event | Display | |-----------|-------|---------| | CLI → Telegram | User types | 👤 User (cli): ... | | CLI → Telegram | Tool starts | 🔧 Running: Bash | | CLI → Telegram | Claude responds | 🤖 Claude: ... | | CLI → Telegram | Session starts | New Forum Topic created | | CLI → Telegram | Context compacting | ⏳ Notification sent | | Telegram → CLI | User sends message | Injected via tmux | | Telegram → CLI | User types "stop" | Sends Ctrl+C interrupt |
Technical Details
- Session storage: SQLite at
~/.config/claude-telegram-mirror/sessions.db - Socket path:
~/.config/claude-telegram-mirror/bridge.sock - Response extraction: Reads Claude's transcript
.jsonlon Stop event - Deduplication: Telegram-originated messages tracked to prevent echo
- Topic routing: Each daemon only processes topics it created (multi-bot safe)
- Compaction alerts: PreCompact hook sends notification before context summarization
Troubleshooting
Run the diagnostic tool first:
ctm doctorThis checks all common issues and provides fix suggestions.
Common Issues
Hooks not firing?
- Check if project has local
.claude/settings.jsonoverriding globals - Run
ctm install-hooks -pfrom project directory - Restart Claude Code after installing hooks
409 Conflict error?
- Only one polling connection per bot token is allowed
- If running multiple systems, each needs its own bot (see Multi-System Architecture)
- Kill duplicate daemons:
pkill -f "claude-telegram-mirror"
Bridge not receiving events?
- Check socket:
ls -la ~/.config/claude-telegram-mirror/bridge.sock - Enable debug:
export TELEGRAM_HOOK_DEBUG=1then retry - Check debug log:
cat ~/.config/claude-telegram-mirror/hook-debug.log
tmux injection not working?
- Verify tmux session:
tmux list-sessions - Check daemon logs for "Session tmux target stored"
Messages going to wrong topic?
- Clear session DB:
rm ~/.config/claude-telegram-mirror/sessions.db
Service not starting (Linux)?
- Check status:
systemctl --user status claude-telegram-mirror - View logs:
journalctl --user -u claude-telegram-mirror -f - Enable linger:
loginctl enable-linger $USER
Service not starting (macOS)?
- Check status:
launchctl list | grep claude - View logs:
cat ~/Library/Logs/claude-telegram-mirror.*.log - Check permissions: Ensure Terminal has Accessibility access
Manual Setup (for developers)
For developers who want to work on the source code:
# 1. Clone and build
git clone https://github.com/robertelee78/claude-telegram-mirror.git
cd claude-telegram-mirror && npm install && npm run build
# 2. Create a Telegram bot via @BotFather, get the token
# 3. Create a supergroup with Topics enabled, add your bot as admin
# 4. Get your chat ID
./scripts/get-chat-id.sh YOUR_BOT_TOKEN
# 5. Configure environment
cat > ~/.telegram-env << 'EOF'
export TELEGRAM_BOT_TOKEN="your-token-here"
export TELEGRAM_CHAT_ID="-100your-chat-id"
export TELEGRAM_MIRROR=true
EOF
# 6. Install hooks
node dist/cli.js install-hooks # Global install
# OR for projects with custom .claude/settings.json:
cd /path/to/project && node dist/cli.js install-hooks --project
# 7. Start daemon (choose one)
node dist/cli.js start # Foreground (for testing)
node dist/cli.js service install && \
node dist/cli.js service start # As system service (recommended)Note: When using npm install, use ctm instead of node dist/cli.js.
License
MIT
Credits
Built for remote Claude Code interaction from mobile devices.
