The missing Telegram superpowers for Claude Code
The official Claude Code Telegram plugin gives you 3 tools: reply, react, edit_message.
This plugin gives you 15 tools, a built-in task scheduler, and handles documents, voice, and interactive buttons β all in a single process with zero polling conflicts.
- See It In Action
- What You Get
- Built-in Scheduler
- Quick Start
- Configuration
- Comparison
- Architecture
- Security
- Contributing
- Credits
Inline keyboard for approvals:
Claude β Telegram:
βββββββββββββββββββββββββββββββββββββββββββ
β Deploy gitintel v0.1.1 to production? β
β β
β Changes: 3 files, bug fix for scan cmd β
β Tests: 76/76 passing β
β β
β [ β
Deploy ] [ β Cancel ] β
βββββββββββββββββββββββββββββββββββββββββββ
CEO taps "Deploy" β
Claude receives: callback_query with data "deploy_approved"
Claude: executes deployment, replies with result
Scheduled morning brief (fires automatically at 9 AM):
Claude β Telegram (9:00 AM IST):
βββββββββββββββββββββββββββββββββββββββββββ
β π
Morning Brief β March 22 β
β β
β βΈ GitIntel: v0.1.0 live, 8 downloads β
β βΈ CI: all green β
β βΈ Pending: HN launch post ready β
β βΈ Today: deploy blog, prep launch day β
βββββββββββββββββββββββββββββββββββββββββββ
Document handling:
CEO sends: quarterly_report.pdf
Claude receives: file downloaded to inbox/
Claude: reads PDF, extracts key metrics, responds with summary
Messaging
| Tool | What it does | Example |
|---|---|---|
reply |
Send with MarkdownV2/HTML formatting | reply(chat_id, "<b>Done</b>", parse_mode: "HTML") |
react |
Emoji reaction | react(chat_id, msg_id, "π₯") |
edit_message |
Update sent messages | edit_message(chat_id, msg_id, "Updated text") |
download_attachment |
Lazy file download from Telegram | download_attachment(file_id) β local path |
send_keyboard |
Inline buttons | send_keyboard(chat_id, "Approve?", [[{label: "Yes", callback_data: "yes"}]]) |
answer_callback |
Acknowledge button tap | answer_callback(query_id, "Approved!") |
pin_message |
Pin important updates | pin_message(chat_id, msg_id) |
unpin_message |
Unpin | unpin_message(chat_id, msg_id) |
set_commands |
Register /commands menu |
set_commands([{command: "status", description: "System status"}]) |
delete_message |
Clean up messages | delete_message(chat_id, msg_id) |
forward_message |
Forward between chats | forward_message(from, to, msg_id) |
Scheduling
| Tool | What it does | Example |
|---|---|---|
schedule_task |
Cron-based recurring/one-shot | schedule_task(id, "0 9 * * *", "Morning brief", chat_id) |
schedule_delay |
Human-readable delay | schedule_delay(id, "30m", "Check CI status", chat_id) |
unschedule_task |
Remove task | unschedule_task("flight_ai302") |
update_task |
Pause/resume/modify | update_task(id, {enabled: false}) |
list_scheduled |
View all tasks | list_scheduled() or list_scheduled(tag: "ops") |
Official Plugin This Plugin
βββββββββββββββ βββββββββββ
Text messages β β
Photos β β
Documents/PDFs β β β downloaded, path sent to Claude
Voice messages β β β saved as .ogg, path sent
Button callbacks β β β routed as channel notification
A cron engine that runs inside the plugin β same process as the Telegram bot. No separate daemon, no polling conflicts, no infrastructure.
schedule.json defines tasks with cron expressions
β
Plugin checks every 30 seconds
β
When a task is due β sends MCP notification to Claude
β
Claude processes it like any message
β
Claude calls reply/send_keyboard/etc to deliver results
{
"tasks": [
{
"id": "morning_brief",
"cron": "57 8 * * *",
"prompt": "Generate the morning brief. Include: venture status, pending items, today's plan.",
"chat_id": "YOUR_CHAT_ID",
"enabled": true,
"recurring": true,
"description": "Daily brief at ~9 AM"
},
{
"id": "flight_check",
"cron": "*/30 15-20 * * *",
"prompt": "Check flight AI-302 status. Alert on delays or gate changes.",
"chat_id": "YOUR_CHAT_ID",
"enabled": true,
"recurring": true,
"urgent": true,
"expires_at": "2026-03-22T20:00:00+05:30",
"tags": ["travel"],
"description": "Track flight AI-302 until 8 PM IST"
}
],
"timezone": "Asia/Kolkata",
"quiet_hours": { "start": 1, "end": 7 }
}| Feature | Description |
|---|---|
| Cron expressions | Standard 5-field: M H DoM Mon DoW |
| Timezone | IANA timezone string (e.g., Asia/Kolkata, America/New_York) |
| Quiet hours | Non-urgent tasks pause during specified hours |
| Expiry | expires_at β task auto-disables after a timestamp |
| Max runs | max_runs: 6 β fire 6 times then stop |
| Tags | Categorize and filter: list_scheduled(tag: "ops") |
| Urgent | urgent: true β bypasses quiet hours |
| Human delays | schedule_delay("2h") instead of computing cron |
| One-shot | recurring: false β fire once, auto-delete |
| Debouncing | Won't fire twice in the same minute |
| Scenario | Cron | Options |
|---|---|---|
| Daily morning brief | 57 8 * * * |
recurring |
| Flight delay alerts | */30 15-20 * * * |
expires_at, urgent |
| "Remind me in 2 hours" | β | schedule_delay("2h") |
| Watch CI pipeline | */5 * * * * |
max_runs: 30 |
| Weekly news digest | 3 9 * * 6 |
recurring, tags: ["research"] |
| Website uptime | 17 * * * * |
recurring, tags: ["ops"] |
| Post-launch monitoring | 0 */2 * * * |
expires_at: 3 days |
| Monthly billing reminder | 0 10 1 * * |
recurring, tags: ["finance"] |
Prerequisites: Bun runtime, a Telegram bot token, Claude Code.
git clone https://github.com/gitintel-ai/awesome-claude-code-telegram.git
cd awesome-claude-code-telegram
bun installmkdir -p ~/.claude/channels/telegram
echo "TELEGRAM_BOT_TOKEN=123456789:AAH..." > ~/.claude/channels/telegram/.env
chmod 600 ~/.claude/channels/telegram/.envcat > ~/.claude/channels/telegram/schedule.json << 'EOF'
{
"tasks": [],
"timezone": "Asia/Kolkata",
"quiet_hours": { "start": 1, "end": 7 }
}
EOFAdd to your Claude Code MCP config (~/.claude/mcp.json or project .mcp.json):
{
"mcpServers": {
"telegram": {
"command": "bun",
"args": ["/path/to/awesome-claude-code-telegram/server.ts"]
}
}
}Or run directly: bun server.ts
Managed via ~/.claude/channels/telegram/access.json:
{
"dmPolicy": "pairing",
"allowFrom": ["123456789"],
"groups": {},
"ackReaction": "β‘",
"replyToMode": "first",
"chunkMode": "newline"
}| Field | Options | Default |
|---|---|---|
dmPolicy |
"pairing", "allowlist", "disabled" |
"pairing" |
ackReaction |
Any Telegram-whitelisted emoji | none |
replyToMode |
"first", "all", "off" |
"first" |
chunkMode |
"length", "newline" |
"length" |
textChunkLimit |
1β4096 | 4096 |
Official This Plugin
ββββββββ βββββββββββ
Tools 3 14
Message handlers 2 5
Messaging
Text + photos β β
MarkdownV2 / HTML formatting β β
Inline keyboards β β
Document / PDF handling β β
Voice messages β β
Pin / unpin β β
Delete messages β β
Forward messages β β
Bot commands menu β β
Scheduling
Recurring tasks β β
One-shot reminders β β
Quiet hours β β
Task expiry β β
Human delay syntax β β
Security
Pairing + allowlist β β
Outbound chat gating β β
Path traversal protection β β (enhanced)
Callback query validation n/a β
File permission hardening partial β
ββββββββββββββββββββββββ
β Claude Code β
β (your session) β
ββββββββββββ¬ββββββββββββ
β stdio (MCP protocol)
ββββββββββββΌββββββββββββ
β awesome-claude- β
β code-telegram β
β β
β ββ Messaging β reply, keyboard, pin, delete, forward
β ββ Scheduler β cron eval, timezone, quiet hours
β ββ Handlers β text, photo, doc, voice, callback
β β
ββββββββββββ¬ββββββββββββ
β Grammy (Telegram Bot API)
ββββββββββββΌββββββββββββ
β Telegram β
ββββββββββββββββββββββββ
Single process. The plugin is both the messaging bridge and the scheduler. No separate bot = no 409 Conflict polling errors.
Inherits the official plugin's security model with additional hardening:
| Layer | Protection |
|---|---|
| Access control | Pairing mode, allowlist, group @mention gating |
| Outbound gating | All tools validate chat_id against allowlist before sending |
| Path traversal | Document filenames sanitized (strips /, \, ..), state files blocked |
| Callback validation | Only callback queries received in this session can be answered |
| File permissions | access.json 0o600, schedule.json 0o600, inbox/ 0o700 |
| Token isolation | .env file with 0o600 permissions, never in git |
| Prompt injection | Scheduler content treated as untrusted (same as user messages) |
| Approved ID validation | Pairing approval files validated as numeric Telegram IDs |
Contributions welcome. This is a fork of Anthropic's official plugin β the goal is to upstream the best features.
- Fork the repo
- Create a feature branch (
git checkout -b feat/my-feature) - Make changes to
server.ts - Test with
bun server.tsconnected to a test bot - Verify build:
bun build --target=bun server.ts --outfile=/dev/null - Submit a PR
Areas that need help:
- Demo GIF showing inline keyboards in action
- Windows-specific token security (NTFS ACLs)
- Inbox file cleanup (TTL-based eviction)
- More message type handlers (stickers, location, contacts)
Forked from Anthropic's official Claude Code Telegram plugin. Copyright 2024-2026 Anthropic, PBC. Original licensed under Apache License 2.0.
See NOTICE for full attribution.
Apache License 2.0 β see LICENSE