Telegram Control
An agent gets blocked on a permission prompt. Your phone buzzes. You tap
Approve — or just reply y. You’re back to whatever you were doing.
No attach, no Mosh, no leaving the chat.
That’s the whole point of the Telegram bridge. ccmux already knows the moment an agent needs you; this turns that into something you can act on from anywhere, including a watch.
The bot reaches out to Telegram (long polling), so there’s no open port, no public URL, nothing inbound. It works behind NAT, on a laptop, on a home Mac mini — same posture as the rest of ccmux.
Setup
Make a bot with @BotFather (/newbot, copy the
token). Then:
ccmux telegram register --token <token> # or CCMUX_TELEGRAM_BOT_TOKEN=…
ccmux daemon restart
ccmux telegram pair # prints a one-time code
Send the code to your bot:
/start ABC123
Done. Only chats you pair can drive the bot — the token alone can’t do
anything. ccmux telegram status and ccmux doctor confirm it’s wired.
(Or run ccmux setup — the wizard has a Telegram step.)
Approve from your wrist
When an agent hits a permission prompt, the bot sends you the pane tail
plus Approve / Deny buttons. Tap one. Or — because a watch can’t
always tap inline buttons — reply y / n / approve / deny. Both
land the same keystroke in the pane.
Drive the agent, not just the session
This is the part most remote-control tools miss. You’re not limited to
“send text.” The bot surfaces the agent’s own commands as
autocomplete and tappable buttons — /model, /compact, /clear,
whatever that agent has — and that list is real: for Claude it’s the
built-in slash-commands plus your own ~/.claude commands and skills,
read from whichever machine runs the session. Tap one to send it. Or just
type a prompt and it goes to the session you last touched.
One bot, the whole tailnet
Run it on your always-on machine. It addresses sessions as
host:session and reaches every peer’s daemon over the same tailnet API
the dashboard uses. So /sessions shows local and remote, and
/preview mini:build previews the pane on mini. One token, one daemon.
| Command | What |
|---|---|
/sessions | every session, this host + tailnet peers |
/preview <host:session> [lines] | peek at a pane |
/agent [host:session] | the agent’s commands, as buttons |
/say <host:session> <text> | send a prompt |
/new <project> [agent] | start a session |
/kill <host:session> | end one (asks first) |
/notes <project> [search] | browse notes — Telegram renders the .md inline |
/usage | token / cost summary |
Tiers
The allowlist is the real lock. On top of it: read commands are
always on, control (approve/deny, drive the agent, spawn/kill) is for
paired chats, and a raw exec tier (/run) is opt-in and off by
default. Driving the agent is control, not exec — it’s the agent’s
own commands, so you never need to open a shell to use it.
Privacy
Pane tails and notes you fetch go through Telegram’s servers, like any message — it’s opt-in and off by default, and the pane tail is line-capped before it leaves the machine. Don’t point it at panes with secrets you wouldn’t paste into a chat.
Full setup, config reference, and the optional tailnet notes viewer: Telegram_Setup.md.
Spotted an error or something out of date? Edit this page on GitHub.