Skip to main content
Glama
Swigler

Claude Code Telegram Bridge

by Swigler

Claude Code ↔ Telegram Bridge

Мост для Telegram, привязанный к сессии, для Claude Code. Бот живёт ровно столько, сколько длится ваша терминальная сессия — запустили, пользуетесь, закрыли. Никакого постоянно работающего демона.

Это форк официального плагина канала Claude Code для Telegram с патчем безопасности и переносимым развёртыванием на базе tmux + Tailscale.


Как это работает

Phone (Telegram)
  │
  ▼
┌─────────────────────┐
│  server.ts           │  Standalone MCP HTTP server
│  Polls Telegram      │  Runs as a systemd user unit
│  Queues messages     │  Starts/stops with the pin
└──────────┬──────────┘
           │ SSE (/events)
           ▼
┌─────────────────────┐
│  proxy.ts            │  Stdio MCP proxy
│  Bridges to Claude   │  Spawned by Claude Code
│  Owns the pin lock   │  One session at a time
└──────────┬──────────┘
           │ stdio
           ▼
┌─────────────────────┐
│  Claude Code         │  Your session
│  Reads messages      │  Calls reply/react/edit
│  Full tool access    │  Permission buttons in TG
└─────────────────────┘

Конструкция пина: Только одна сессия Claude может владеть ботом одновременно. tgpin захватывает файл блокировки, запускает поллер и освобождает оба, когда сессия завершается. Это предотвращает ошибку 409 Conflict, которая возникает, когда два поллера борются за один и тот же токен Telegram.


Related MCP server: tsgram-mcp

Патч безопасности

В вышестоящем плагине есть проблема раскрытия информации: команды /start, /help и /status регистрируются до того, как срабатывает шлюз доступа. При dmPolicy: "allowlist" посторонний, нашедший бота, получает полезный ответ, объясняющий, что это мост Claude Code — тем самым раскрывается, что бот существует и что он делает.

Патч добавляет защиту commandMuted(): в режиме allowlist или disabled команды от пользователей, не входящих в список разрешённых, молча игнорируются. В режиме pairing они работают нормально (поскольку /start — это то, как новые пользователи узнают о возможности сопряжения).

Это +15 строк, без удалений, видно в git diff.


Настройка

Предварительные требования

  • Установленный CLI Claude Code

  • Среда выполнения Bun

  • Токен бота Telegram от @BotFather

1. Установите сервер

mkdir -p ~/.claude/telegram-server
cp server.ts proxy.ts package.json ~/.claude/telegram-server/
cd ~/.claude/telegram-server && bun install

2. Настройте токен бота

mkdir -p ~/.claude/channels/telegram
echo "TELEGRAM_BOT_TOKEN=YOUR_TOKEN_HERE" > ~/.claude/channels/telegram/.env
chmod 600 ~/.claude/channels/telegram/.env

3. Установите пользовательский юнит systemd

mkdir -p ~/.config/systemd/user
cp telegram-mcp.service ~/.config/systemd/user/
systemctl --user daemon-reload

Не включайте службуtgpin запускает и останавливает её автоматически. Включение сделало бы бота бессмертным и конфликтовало бы с конструкцией пина.

4. Установите лаунчер

cp tgpin ~/bin/tgpin
chmod +x ~/bin/tgpin

# Optional: alias in your .bashrc
echo 'alias tg="~/bin/tgpin"' >> ~/.bashrc

5. Ограничьте доступ (рекомендуется)

По умолчанию бот находится в режиме pairing — любой, кто напишет ему в личку, получит код сопряжения. Чтобы привязать его к вашему ID пользователя Telegram:

cat > ~/.claude/channels/telegram/access.json << 'EOF'
{
  "dmPolicy": "allowlist",
  "allowFrom": ["YOUR_TELEGRAM_USER_ID"],
  "groups": {},
  "pending": {}
}
EOF

Узнайте свой ID, отправив сообщение @userinfobot в Telegram.


Использование

Запуск сессии

tg              # start Claude with Telegram bridge
tg --continue   # resume the last conversation

Портативный доступ (tmux + Tailscale + Termius)

Настоящая мощь — запуск этого по SSH с телефона. Стек:

  • Tailscale — mesh-VPN. Ваш телефон и машина видят друг друга в частной сети, без проброса портов и публичного IP. Личный план включён.

  • Termius — SSH-клиент для Android/iOS. Поддерживает ключевую аутентификацию, постоянные сессии и адреса Tailscale. Стартового плана достаточно.

  • tmux — терминальный мультиплексор. Сессия переживает обрывы SSH.

# On your machine (once):
tmux new -s claude
tg

# Detach: Ctrl+B, then D

# From your phone (Termius → Tailscale IP):
ssh your-machine
tmux attach -t claude

Бот остаётся живым, пока существует сессия tmux. Обрывы SSH его не убивают. Закрываете сессию tmux — бот умирает, как и задумано.

Рабочий процесс: Вы в автобусе, открываете Termius на телефоне, подключаетесь по SSH к своей машине через Tailscale, подключаетесь к сессии tmux — Claude живёт в Telegram. Закрываете Termius, сессия tmux сохраняется, бот продолжает работать. Вы возвращаетесь к нему позже откуда угодно.

Обработка разрешений

Вызовы инструментов отображаются в Telegram как кнопки approve/deny. Сессия работает в --permission-mode default, поэтому опасные операции (запись файлов, shell-команды) требуют вашего явного нажатия перед выполнением.


Архитектурные решения

Почему привязка к сессии?

Постоянно работающий бот означает постоянно работающую сессию Claude, потребляющую ресурсы и потенциально действующую на основе устаревшего контекста. Конструкция пина означает, что бот жив, когда вы этого хотите, и мёртв, когда не хотите. Это фича, а не ограничение.

Почему два файла (server.ts + proxy.ts)?

Сервер работает как юнит systemd и удерживает соединение поллинга Telegram. Прокси запускается Claude как stdio MCP-транспорт. Их разделение означает:

  • Сервер может перезапускаться независимо от Claude

  • Прокси может переподключаться к работающему серверу

  • Состояние поллинга не теряется при перезапуске сессии Claude

Почему не вебхук?

Вебхукам нужен публичный URL, TLS и проброс портов. Длинный поллинг работает где угодно — за NAT, на ноутбуке, на VPS. Ноль инфраструктуры, кроме самой машины.

Один поллер на токен

Bot API Telegram возвращает 409 Conflict, если два процесса опрашивают один и тот же токен. Файл блокировки (pinned.lock) обеспечивает ровно один поллер. Если сессия падает без очистки, следующий tgpin обнаруживает устаревший PID и возвращает блокировку.


Файлы

Файл

Назначение

server.ts

Автономный MCP HTTP-сервер — опрашивает Telegram, ставит сообщения в очередь, обслуживает инструменты

proxy.ts

Stdio MCP-прокси — мост между сервером и Claude, управляет жизненным циклом пина

package.json

Зависимости: grammy, MCP SDK, express, zod

tgpin

Скрипт-лаунчер — захватывает пин, запускает Claude с загруженным каналом

telegram-mcp.service

Пользовательский юнит systemd для сервера


Лицензия

Apache-2.0 (такая же, как у вышестоящего плагина Claude Code для Telegram).


Контакты

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables remote control of AI coding assistants (Claude Code/Codex) via Telegram, allowing you to manage long-running tasks, send commands, and receive notifications from anywhere. Supports unattended mode with smart polling for up to 7 days and multi-session management.
    8
    30
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Connects Claude Code sessions to Telegram, enabling AI-powered code assistance and file management directly from Telegram chats.
    89
    MIT