| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Control Claude Code sessions remotely via Telegram — monitor, interact, and manage AI coding sessions running in tmux.
Jietu20260207-final.mp4Claude Code runs in your terminal. When you step away from your computer — commuting, on the couch, or just away from your desk — the session keeps working, but you lose visibility and control.
CCBot solves this by letting you seamlessly continue the same session from Telegram. The key insight is that it operates on tmux, not the Claude Code SDK. Your Claude Code process stays exactly where it is, in a tmux window on your machine. CCBot simply reads its output and sends keystrokes to it. This means:
Other Telegram bots for Claude Code typically wrap the Claude Code SDK to create separate API sessions. Those sessions are isolated — you can't resume them in your terminal. CCBot takes a different approach: it's just a thin control layer over tmux, so the terminal remains the source of truth and you never lose the ability to switch back.
In fact, CCBot itself was built this way — iterating on itself through Claude Code sessions monitored and driven from Telegram via CCBot.
# Using uv (recommended)
uv tool install git+https://github.com/six-ddc/ccmux.git
# Or using pipx
pipx install git+https://github.com/six-ddc/ccmux.gitgit clone https://github.com/six-ddc/ccmux.git
cd ccmux
uv sync1. Create a Telegram bot and enable Threaded Mode:
2. Configure environment variables:
Create ~/.ccbot/.env:
TELEGRAM_BOT_TOKEN=your_bot_token_here
ALLOWED_USERS=your_telegram_user_idRequired:
| Variable | Description |
|---|---|
| TELEGRAM_BOT_TOKEN | Bot token from @BotFather |
| ALLOWED_USERS | Comma-separated Telegram user IDs |
Optional:
| Variable | Default | Description |
|---|---|---|
| CCBOT_DIR | ~/.ccbot | Config/state directory (.env loaded from here) |
| TMUX_SESSION_NAME | ccbot | Tmux session name |
| CLAUDE_COMMAND | claude | Command to run in new windows |
| MONITOR_POLL_INTERVAL | 2.0 | Polling interval in seconds |
| CCBOT_SHOW_HIDDEN_DIRS | false | Show hidden (dot) directories in directory browser |
| OPENAI_API_KEY | (none) | OpenAI API key for voice message transcription |
| OPENAI_BASE_URL | https://api.openai.com/v1 | OpenAI API base URL (for proxies or compatible APIs) |
Message formatting is always HTML via chatgpt-md-converter (chatgpt_md_converter package). There is no runtime formatter switch to MarkdownV2.
If running on a VPS where there's no interactive terminal to approve permissions, consider:
CLAUDE_COMMAND=IS_SANDBOX=1 claude --dangerously-skip-permissions
Auto-install via CLI:
ccbot hook --installOr manually add to ~/.claude/settings.json:
{
"hooks": {
"SessionStart": [
{
"hooks": [{ "type": "command", "command": "ccbot hook", "timeout": 5 }]
}
]
}
}This writes window-session mappings to $CCBOT_DIR/session_map.json (~/.ccbot/ by default), so the bot automatically tracks which Claude session is running in each tmux window — even after /clear or session restarts.
# If installed via uv tool / pipx
ccbot
# If installed from source
uv run ccbotBot commands:
| Command | Description |
|---|---|
| /start | Show welcome message |
| /history | Message history for this topic |
| /screenshot | Capture terminal screenshot |
| /esc | Send Escape to interrupt Claude |
Claude Code commands (forwarded via tmux):
| Command | Description |
|---|---|
| /clear | Clear conversation history |
| /compact | Compact conversation context |
| /cost | Show token/cost usage |
| /help | Show Claude Code help |
| /memory | Edit CLAUDE.md |
Any unrecognized /command is also forwarded to Claude Code as-is (e.g. /review, /doctor, /init).
1 Topic = 1 Window = 1 Session. The bot runs in Telegram Forum (topics) mode.
Creating a new session:
Sending messages:
Once a topic is bound to a session, just send text or voice messages in that topic — text gets forwarded to Claude Code via tmux keystrokes, and voice messages are automatically transcribed and forwarded as text.
Killing a session:
Close (or delete) the topic in Telegram. The associated tmux window is automatically killed and the binding is removed.
Navigate with inline buttons:
📋 [project-name] Messages (42 total) ───── 14:32 ───── 👤 fix the login bug ───── 14:33 ───── I'll look into the login bug... [◀ Older] [2/9] [Newer ▶]
The monitor polls session JSONL files every 2 seconds and sends notifications for:
Notifications are delivered to the topic bound to the session's window.
Formatting note:
tmux attach -t ccbot
tmux new-window -n myproject -c ~/Code/myproject
# Then start Claude Code in the new window
claudeThe window must be in the ccbot tmux session (configurable via TMUX_SESSION_NAME). The hook will automatically register it in session_map.json when Claude starts.
| Path | Description |
|---|---|
| $CCBOT_DIR/state.json | Thread bindings, window states, display names, and per-user read offsets |
| $CCBOT_DIR/session_map.json | Hook-generated {tmux_session:window_id: {session_id, cwd, window_name}} mappings |
| $CCBOT_DIR/monitor_state.json | Monitor byte offsets per session (prevents duplicate notifications) |
| ~/.claude/projects/ | Claude Code session data (read-only) |
src/ccbot/
├── __init__.py # Package entry point
├── main.py # CLI dispatcher (hook subcommand + bot bootstrap)
├── hook.py # Hook subcommand for session tracking (+ --install)
├── config.py # Configuration from environment variables
├── bot.py # Telegram bot setup, command handlers, topic routing
├── session.py # Session management, state persistence, message history
├── session_monitor.py # JSONL file monitoring (polling + change detection)
├── monitor_state.py # Monitor state persistence (byte offsets)
├── transcript_parser.py # Claude Code JSONL transcript parsing
├── terminal_parser.py # Terminal pane parsing (interactive UI + status line)
├── html_converter.py # Markdown → Telegram HTML conversion + HTML-aware splitting
├── screenshot.py # Terminal text → PNG image with ANSI color support
├── transcribe.py # Voice-to-text transcription via OpenAI API
├── utils.py # Shared utilities (atomic JSON writes, JSONL helpers)
├── tmux_manager.py # Tmux window management (list, create, send keys, kill)
├── fonts/ # Bundled fonts for screenshot rendering
└── handlers/
├── __init__.py # Handler module exports
├── callback_data.py # Callback data constants (CB_* prefixes)
├── directory_browser.py # Directory browser inline keyboard UI
├── history.py # Message history pagination
├── interactive_ui.py # Interactive UI handling (AskUser, ExitPlan, Permissions)
├── message_queue.py # Per-user message queue + worker (merge, rate limit)
├── message_sender.py # safe_reply / safe_edit / safe_send helpers
├── response_builder.py # Response message building (format tool_use, thinking, etc.)
└── status_polling.py # Terminal status line polling
Thanks to all the people who contribute! We encourage using Claude Code to collaborate on contributions.
| Back | FazBrowse Home | New Git URL |