Anthropic's official Telegram plugin silently fails on headless Linux servers. Here's how we diagnosed the bug, built a workaround, and now run Claude Code as a Telegram bot that never sleeps.
Claude Code v2.1.81 ships with an official Telegram channel plugin. On Windows and macOS, it works beautifully:
We wanted to run this on a free Oracle Cloud VM so Claude is available 24/7 — not just when a laptop is open. The setup was straightforward:
claude --channels plugin:telegram@claude-plugins-official \
--model sonnet --permission-mode bypassPermissions
Everything looked correct. The MCP server connected. Grammy started polling. The bot received messages. But Claude never responded.
mcp.notification({method: 'notifications/claude/channel'}) is sent by the plugin but never reaches Claude Code on headless Linux. Grammy receives the message, gate() passes it, the notification fires into the void. Zero errors in logs. Complete silence.
~/.claude/plugins/cache/enabledPlugins in settings.jsonaccess.json with correct allowlistThe MCP stdio transport layer on Linux doesn't properly handle async notifications when Claude Code is idle at the prompt. This likely works on desktop because the GUI has a different event loop. On headless Linux, the notification gets written to stdout but Claude Code doesn't read it until the next user input.
This is a known architectural limitation, not a simple config issue. We reported it — no fix yet.
Instead of waiting for Anthropic to fix the plugin, we built an alternative using ccgram and Claude Code's hook system:
Instead of relying on MCP notifications (broken on Linux), ccgram injects messages directly into Claude Code's terminal via tmux send-keys. Hooks fire on real Claude Code events (task completion, permission requests) and trigger notification scripts. No MCP notification layer needed.
# On Oracle VM (free tier: 1 core, 1GB RAM, 45GB disk)
npm install -g @jsayubi/ccgram
ccgram init # Interactive setup: bot token + chat ID
Add to ~/.claude/settings.json:
{
"hooks": {
"PermissionRequest": [{
"hooks": [{
"type": "command",
"command": "node ~/.ccgram/dist/permission-hook.js",
"timeout": 120
}]
}],
"Stop": [{
"hooks": [{
"type": "command",
"command": "node ~/.ccgram/dist/enhanced-hook-notify.js completed",
"timeout": 5
}]
}]
}
}
# Terminal 1: ccgram bot
tmux new-session -d -s ccgram \
'cd ~/.ccgram && node dist/workspace-telegram-bot.js'
# Terminal 2: Claude Code
tmux new-session -d -s claude \
'claude --model sonnet --dangerously-skip-permissions'
That's it. Claude Code is now a 24/7 Telegram bot running on a free VM.
| Feature | Official Plugin | ccgram + Hooks |
|---|---|---|
| Windows/Mac | Works | Works |
| Headless Linux | Broken | Works |
| Photo support | Yes | No |
| Permission approval | Via MCP | Via Telegram buttons |
| Task notifications | Limited | Full (hooks) |
| Requires tmux | No | Yes |
| Setup complexity | Low | Medium |
| 24/7 on free VM | No | Yes |
With this setup, we run Claude Code as a permanent agent on an Oracle Cloud free-tier VM. From Telegram, we can:
Total cost: $0/month. Oracle free tier gives you 2 VMs with 1GB RAM each — more than enough for Claude Code + ccgram.
send-keys.MindSwarm orchestrates Claude, Gemini, and Codex across multiple VMs with self-healing infrastructure, persistent memory, and Telegram control.
Learn More About MindSwarm