Remote control Claude Code from your phone via Telegram.
A lightweight single-file Python bot that bridges Telegram messages to claude -p with real-time streaming output.
Phone (Telegram) → Bot script (your Mac) → claude -p → response streamed back
- Streaming output — responses update in real-time as Claude generates them, powered by
--output-format stream-json - Tool visibility — see which tools Claude is using (Read, Edit, Bash, etc.) with live status indicators
- Multi-turn conversations — maintain context across messages with
--session-id - Session resume — continue terminal sessions or resume specific sessions by ID
- Permission modes — switch between default/acceptEdits/plan/bypassPermissions via inline buttons
- File uploads — send files to the bot, they're saved to your working directory
- Auto-start — runs as a macOS launchd service, survives reboots and crashes
- Security — only responds to your Telegram user ID, others are silently ignored
- Single file — the entire bot is one Python file, easy to understand and modify
- Python 3.12+
- Claude Code CLI installed and authenticated (
claude --versionshould work) - A Telegram Bot Token (from @BotFather)
- Your Telegram User ID (from @userinfobot)
git clone https://github.com/YOUR_USERNAME/claude-telegram-bot.git
cd claude-telegram-bot
chmod +x install.sh
./install.shThen edit ~/.claude/telegram-bot/config.json:
{
"bot_token": "123456789:AABbCcDdEeFf...",
"allowed_user_ids": [your_telegram_user_id],
"working_directory": "/path/to/your/project"
}Start the service:
# macOS
launchctl load ~/Library/LaunchAgents/com.claude-telegram-bot.plist
# Linux / manual
~/.claude/telegram-bot/venv/bin/python3 ~/.claude/telegram-bot/bot.py| Command | Description |
|---|---|
/start |
Confirm bot is online |
/status |
View current status |
/chat |
Start multi-turn conversation (preserves context) |
/endchat |
End multi-turn conversation |
/continue |
Continue the most recent terminal session |
/resume <id> |
Resume a specific session by ID |
/mode |
Switch Claude permission mode |
/reload |
Reload config without restart |
Any regular text message is sent directly to claude -p for execution.
File uploads are saved to {working_directory}/inbox/. Add a caption to include instructions.
| Field | Default | Description |
|---|---|---|
bot_token |
(required) | Telegram Bot API token |
allowed_user_ids |
(required) | Array of authorized Telegram user IDs |
claude_path |
auto-detect | Path to claude CLI binary |
working_directory |
current dir | Working directory for Claude execution |
timeout_seconds |
600 | Max execution time per message |
permission_mode |
"default" | Claude permission mode |
system_prompt |
"Keep responses concise..." | Appended to Claude's system prompt |
stream_update_interval |
2.0 | Seconds between Telegram message updates |
1. You send a message in Telegram
2. Bot receives it via long-polling
3. Bot spawns: claude -p --output-format stream-json --verbose "your message"
4. Bot reads JSON events line by line from stdout
5. Bot edits the Telegram message in real-time with new content
6. When done, the final message replaces the streaming preview
The --output-format stream-json flag gives us structured events for text deltas, tool usage, and results — similar to what Claude-to-IM achieves with the Agent SDK, but without the Node.js dependency.
Create ~/.config/systemd/user/claude-telegram-bot.service:
[Unit]
Description=Claude Code Telegram Bot
[Service]
ExecStart=%h/.claude/telegram-bot/venv/bin/python3 %h/.claude/telegram-bot/bot.py
WorkingDirectory=%h
Restart=on-failure
RestartSec=10
[Install]
WantedBy=default.targetsystemctl --user enable --now claude-telegram-bot- Mac must be on — the bot runs locally, no cloud component
- No permission interaction — can't approve/deny tool use from Telegram (use
/mode acceptEditsfor trusted tasks). For interactive permissions, see Claude-to-IM which uses the Agent SDK. - No real-time progress for long tasks — streaming shows text output, but long silent operations (file downloads, builds) appear idle until they produce output
- Each message costs API credits — same as using Claude Code normally
Inspired by Claude-to-IM by @op7418, which provides a full-featured IM bridge using the Claude Agent SDK with interactive permissions, Discord, and Feishu support.
This project takes a simpler approach: single Python file, CLI-based (claude -p), zero Node.js dependencies.
MIT