Operate Claude Code from your phone via Telegram.
Read replies, send prompts, approve tool calls — without touching your laptop.
Installation · Commands · Architecture · 中文
You leave the desk. Claude is mid-task. You want to nudge it, approve a git push, or kick off a new conversation — from your phone. This bridge gives you a small Telegram channel into every running Claude Code session: each session is its own forum topic; what you type goes back to the terminal; tool calls ask for approval inline.
- Bidirectional chat — assistant replies push to your phone; messages typed in a topic are injected back into the matching
tmuxpane via bracketed-paste. - Per-session topics — each
claudeprocess gets its own Telegram forum topic. Multiple sessions in parallel, no crosstalk. - Inline approvals — sensitive tool calls (Bash by default) surface ✅ Allow / ❌ Deny buttons on your phone. Configurable auto-allow regex list. Timeout falls back to deny.
- Result echo — Bash
stdout/stderris pushed to the topic after the tool runs. Long output is head/tail trimmed. - Remote launch —
/new [path]opens a freshclaudesession in a whitelisted directory. - History resume —
/listshows recent sessions; tap a button or use/resume <uuid>to continue. - Graceful exit —
/exitwalks Claude through/exit→Ctrl-D→SIGTERMand cleans up the window. - Fail-open hooks — daemon down? Claude keeps running unimpeded.
- Cursor support — works the same: open Cursor's integrated terminal,
tmux attach, thenclaude.
| Command | What it does |
|---|---|
/new [path] |
Open a new claude session in a whitelisted directory. |
/list [N=10] |
Show recent sessions as tappable buttons. |
/resume <uuid> |
Resume a past session in a new topic. |
/exit |
Cleanly terminate the session bound to the current topic. |
| (plain text) | Anything else in a session topic is sent to that Claude pane. |
iPhone Telegram
│
│ long-poll (SOCKS5)
▼
┌────────────────────────────────────────────┐
│ bridge daemon (single asyncio loop) │
│ ├─ python-telegram-bot │
│ ├─ FastAPI on 127.0.0.1 │
│ └─ tmux send-keys │
└─────────▲──────────────────────────┬───────┘
loopback HTTP │
X-Bridge-Secret │ tmux send-keys
│ ▼
┌─────────┴──────┐ ┌────────────────────────────┐
│ hook scripts │◄────────┤ tmux pane → claude TUI │
│ Stop / Notif │ invoke └────────────────────────────┘
│ Pre/PostTool │
└────────────────┘
Outbound (terminal → phone) flows through Claude Code hooks. Inbound (phone → terminal) flows through tmux send-keys with bracketed paste so multi-line prompts stay atomic. Approvals are a synchronous PreToolUse hook that blocks the agent loop on an asyncio.Future until you tap a button.
# 1. clone and install
git clone https://github.com/HuberyGG/claude-tg-bridge.git ~/claude-tg-bridge
cd ~/claude-tg-bridge
# 2. dependencies (tmux + python venv)
brew install tmux
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
# 3. config
cp config.toml.example config.toml
chmod 600 config.toml
# edit config.toml — see "Telegram setup" below
# 4. register hooks into ~/.claude/settings.json (preserves existing env)
.venv/bin/python scripts/install_hooks.py
# 5. enable the bridge gate in tmux
echo 'set-environment -g CLAUDE_TG_BRIDGE 1' >> ~/.tmux.conf
tmux kill-server # if a server is already running- Talk to @BotFather →
/newbot→ save the token. /mybots→ your bot → Bot Settings → Group Privacy → Turn off. (Bots see only @-mentions otherwise.)- Create a private group, enable Topics in group settings.
- Add the bot, promote to admin with Manage Topics.
- Send any message in the group, then fetch the chat id:
Look for
https://api.telegram.org/bot<TOKEN>/getUpdates"chat":{"id":-100…}— that negative number is yourchat_id.
Edit config.toml:
[telegram]
bot_token = "1234567:AA…"
chat_id = -100… # supergroup id from getUpdates
proxy = "socks5://127.0.0.1:1080" # or "" for direct
[ipc]
shared_secret = "long-random-string" # used between hooks and daemon
[approval]
tools = ["Bash"]
auto_allow_bash = ["^ls( |$)", "^pwd$", "^cat ", "^grep ", "^git (status|diff|log|show)( |$)"]
on_timeout = "deny"
timeout_seconds = 240
[launcher]
default_cwd = "~"
allowed_cwds = ["~"] # /new and /resume restricted to these roots
tmux_session = "bridge"
claude_command = "claude"# inside a tmux session named the same as `launcher.tmux_session`
.venv/bin/python -m bridge.daemonThen in another tmux window: claude — your phone gets a new topic on the first reply. Or /new from your phone and the daemon opens the window for you.
- Anyone with access to the Telegram account can drive Claude — and thus your shell. Enable two-factor auth on your Telegram.
config.tomlcontains the bot token. Alwayschmod 600.- The daemon rejects any update whose
chat_iddoesn't match the configured one. - Loopback HTTP is authenticated by a shared secret header. Bind only to
127.0.0.1. - Whitelisted
allowed_cwdsis enforced on/newand/resume. Choose narrowly.
claude-tg-bridge/
├── bridge/ daemon: tg client, http server, registry, tmux glue
│ ├── daemon.py entry point (single asyncio loop)
│ ├── telegram_client.py PTB Application + command/callback handlers
│ ├── http_server.py /event /approve over 127.0.0.1
│ ├── registry.py session ↔ topic ↔ pane mapping (JSON, atomic)
│ ├── sessions.py scan ~/.claude/projects for /list and /resume
│ ├── tmux.py send-keys, pane probing, new-window
│ ├── outbound.py transcript → HTML, chunking, Bash result render
│ ├── approvals.py tool_use_id → asyncio.Future
│ └── config.py TOML loader
├── hooks/ short-lived scripts invoked by Claude Code
│ ├── stop.py
│ ├── notification.py
│ ├── pretooluse.py
│ ├── posttooluse.py
│ └── _common.py
├── scripts/
│ └── install_hooks.py
├── config.toml.example
└── requirements.txt
MVP. Used daily by the author; not battle-tested. Pull requests welcome.
Roadmap:
launchdautostart- "Allow + remember" approval button
- Cross-tool approvals beyond Bash (Edit, Write, WebFetch)
- Pagination for
/list> 50 entries
MIT — see LICENSE.
把 Mac 终端里跑的 Claude Code 镜像到手机 Telegram。每个 claude 进程对应一个 Telegram 论坛 topic;手机上输入的消息回传给终端;Bash 调用通过手机点按钮审批;离开电脑也能继续工作。
- 双向对话:助手回复推到手机;topic 里的消息通过
tmux send-keys注入回对应 pane,多行用 bracketed paste 保证原子。 - 多会话:每个
claude一个 topic,互不串扰。 - 行内审批:Bash(默认)调用时手机出现 ✅ Allow / ❌ Deny;可配自动放行正则;超时回退 deny。
- 结果回推:Bash
stdout/stderr跑完后推到 topic,过长首尾截断。 - 远程拉起:
/new [path]在白名单目录内新开会话;daemon 自动开 tmux window。 - 历史恢复:
/list列出最近会话(带按钮),/resume <uuid>接续。 - 优雅退出:
/exit走/exit→Ctrl-D→SIGTERM递进式终止。 - fail-open:daemon 挂掉时 hook 静默放行,不会卡 Claude。
- Cursor 兼容:在 Cursor 集成终端
tmux attach后跑claude即可。
| 命令 | 说明 |
|---|---|
/new [path] |
在白名单目录内新开一个 claude 会话。 |
/list [N=10] |
列出最近会话,按钮可点击恢复。 |
/resume <uuid> |
在新 topic 恢复历史会话。 |
/exit |
优雅退出当前 topic 绑定的会话。 |
| (普通文本) | 在 session topic 里发的消息会注入到对应 pane。 |
完整步骤同上方英文版。要点:
brew install tmux+ 建 venv 装requirements.txt- BotFather 建 bot、关掉 Group Privacy
- 建私有 supergroup、启用 Topics、把 bot 设为可管 topic 的管理员
- 在群里发消息,
getUpdates拿chat_id cp config.toml.example config.toml后填好;chmod 600 config.toml.venv/bin/python scripts/install_hooks.py注册 4 个 hook 到~/.claude/settings.json~/.tmux.conf加set-environment -g CLAUDE_TG_BRIDGE 1,tmux kill-server重开- 在叫
bridge的 tmux session 里:.venv/bin/python -m bridge.daemon
- 拿到 Telegram 账号 = 拿到你的 shell。Telegram 必须开两步验证。
config.toml含 bot token,chmod 600保管。- daemon 只信任配置的
chat_id,其它消息直接丢。 - Loopback HTTP 用 shared secret 认证,绑
127.0.0.1。 allowed_cwds白名单控制/new和/resume能进哪些目录,按需收紧。