Telegram

The first provider and the default. Native buttons, reactions, and edits.

Setup

Telegram setup is the quickstart: token from @BotFather, .env, .mcp.json, the channel flag, pair. This page covers how the provider behaves once it's running.

The texting experience

Claude replies in bubbles, one thought each, delivered with a typing indicator and a natural pause between them. It reacts with an emoji when a 👍 says it, edits its own messages to show progress, and offers inline buttons when it wants you to pick one thing. You tap a button, the choice lands back in the session as if you had typed it, and the keyboard clears so it can't be answered twice.

Inbound works the same way. You text in bursts, so hotline buffers consecutive messages per chat (1.2s window, 8s max wait) and delivers them as one coherent turn instead of interrupting Claude three times.

Attachments

Photos are downloaded eagerly and handed to Claude as a local path. Documents, voice notes, video, and stickers are surfaced as metadata and fetched on demand with download_attachment (Telegram's 20MB download cap applies). Outbound files go up to 50MB each: images inline, everything else as documents.

Message plumbing

Groups

Groups are opt-in per group ID, with optional requireMention (deliver only when the bot is mentioned, replied to, or a mentionPatterns regex matches) and an optional per-group sender allowlist. The inbound gate always decides on the sender, never the chat: a stranger in an allowed group is still dropped. Full model on Access & permissions.

Operational notes

Telegram allows one getUpdates consumer per token, so a PID guard SIGTERMs a stale poller before starting. The poll loop backs off exponentially and honors 429s, and shutdown is unified across stdin EOF, signals, and an orphan watchdog. One bot token allows exactly one poller: to run several concurrent sessions, give each its own bot via named instances.

next: Signal →