β—† works with any agent that can shell out

Your agent texts you.
Then waits for an answer.

Globally-installed CLI commands that let Claude Code, opencode, gemini-cli β€” anything with a terminal β€” message you on Telegram and block until you reply. Approve a deploy from your phone. Get a voice note when the build lands, in a voice that sounds human β€” and answer it by holding the mic, transcribed on your own CPU.

~/Repos/my-bot
$ telegram-wait "ready to push to prod?"
πŸ“€ sending [d-repos-my-bot] prompt...
⏳ [d-repos-my-bot] waiting for reply (timeout 36000s, poll 2s)...
   β€” you tap Reply on your phone and just hold the mic β€”
πŸ“₯ received at 4/29/2026, 12:34:56 AM
🎧 voice note (4s) β€” transcribing locally (0 VRAM)...
yes go ahead and push the changes to production

$ git push origin main && telegram-voice "deployed, all green"
πŸ—£οΈ Synthesizing speech (kokoro)...
πŸ“€ Sending voice note as [d-repos-my-bot]...
[+] Voice message sent. 

The toolkit

A handful of commands. That's the whole API.

Every one works from any directory once installed. They're shell commands, not MCP tools β€” your agent just runs them.

telegram-sendSend a message, or a message plus a file attachment.
telegram-waitSend a prompt and block until you reply. The reply lands on stdout.
telegram-voiceSpeak the text and deliver it as a real Telegram voice note.
telegram-transcribeTurn any audio file into text, locally and offline.
telegram-scheduleFire a future or recurring reminder from Convex Cloud.
telegram-listList everything currently scheduled.
telegram-cancelCancel a scheduled message by id.
telegram-historyShow recent messages, both directions.
telegram-setupOne-time install: deploy backend, register webhook, write config.
telegram-setup-sttOne-time: fetch the local, CPU-only speech-to-text engine.
telegram-setup-ttsOne-time: fetch the local Kokoro-82M voice, so the agent sounds human.

Why it's not just a webhook

Built for many agents, one phone.

🎯

Agent-aware routing

Each agent derives an id from its working directory β€” D:\Repos\my-bot becomes [d-repos-my-bot]. Ten agents, one chat, zero crossed wires.

β†©οΈŽ

Reply however you like

Prefix the agent id, or just tap-and-Reply on its message in the Telegram client. Both routes unblock the right waiter.

πŸ—£οΈ

Voice, both directions

Agent speaks as a real voice note in a human-sounding local voice (Kokoro-82M). You reply by holding the mic β€” whisper.cpp turns it into text. Both directions offline, zero VRAM, no API key.

πŸ“Œ

Sticky Telegram mode

Say β€œtelegram mode on” and every reply for the rest of the session routes to your phone. The IDE becomes a worker pane. Say β€œvoice mode on” and it goes hands-free β€” it speaks, you hold the mic, neither side types.

⏰

Reminders that outlive the session

A Convex cron fires scheduled and recurring messages 24/7 β€” long after the agent that queued them exited.

πŸ“œ

No message too long

Pipe anything on stdin. Past Telegram's 4096-char ceiling it auto-splits on sentence boundaries, prefix intact on every chunk.

Talk, don’t type

It speaks. It listens. Neither leaves your machine.

Two local models, no API key on either side: Kokoro-82M reads your agent’s message out loud, whisper.cpp turns your held-mic reply back into text. Both run on the CPU.

bash
$ telegram-setup-tts
   βœ“ kokoro-onnx already available in python
   βœ“ kokoro-v0_19.onnx already present (310 MB)
πŸ—£οΈ Test synthesis with voice af_bella...
[+] Local voice ready.

$ telegram-voice "the build is green, nothing needs you"
πŸ—£οΈ Synthesizing speech (kokoro)...
[+] Voice message sent. 
πŸŽ™οΈ

A voice, not a robot

Kokoro-82M through ONNX runtime β€” 82 million parameters, about a second per sentence on the CPU. Pick a voice with TELEGRAM_TTS_VOICE: af_bella, af_sarah, am_adam, bf_emma.

Say β€œvoice mode on” and the whole session goes hands-free: the agent speaks every turn, you answer by holding the mic.

πŸ”Œ

Nothing installed? Still speaks.

With no model on disk it falls back to the Windows built-in voice β€” sounds like 2003, needs zero setup. Force either engine with TELEGRAM_TTS=kokoro|sapi.

🀝

Shares its model

The model lands in the same directory mcp-server-notify uses for its desktop voice. Set up either tool and the other is already done β€” 331 MB once, not twice.

Setup

Four commands, once per machine.

Setup also drops the skill into ~/.claude/skills/telegram/, so every Claude Code instance on the box picks it up automatically.

bash
$ git clone https://github.com/qxZap/telegram-bro.git
$ cd telegram-bro
$ bun install && bun link
$ telegram-setup "<bot_token>" "<user_id>" "<convex_deploy_key>"
01

Bot token

Message @BotFather, send /newbot, copy the token.

02

User id

Message @userinfobot, copy the numeric id.

03

Convex deploy key

New project at dashboard.convex.dev β†’ Settings β†’ Deploy Keys. The free tier covers personal use.

+

Optional: telegram-setup-tts

Fetches the Kokoro-82M voice so your agent stops sounding like a screen reader. ~331 MB, CPU-only.

+

Optional: telegram-setup-stt

Fetches whisper.cpp so the voice notes you send back get transcribed. ~160 MB, zero VRAM.

Then open your bot in Telegram and press Start once. Telegram refuses to deliver messages to anyone who has never initiated the conversation β€” this trips up almost everyone exactly once.

Under the hood

How a reply finds its way home.

Outbound

telegram-send POSTs to Convex, which calls the Telegram Bot API and stores the resulting message_id for later reply-matching.

Inbound

Telegram's webhook hits a Convex HTTP action, which records the message along with its reply_to chain.

Routing

telegram-wait polls getInboundForAgent, which returns only messages addressed to this agent β€” by prefix or by reply chain.