{"id":"d9e25b81-8405-4a98-936d-6e36aff42441","slug":"simply-telegram-bridge","kind":"mcp","name":"simply-telegram-bridge","summary":"Control Claude Code from Telegram with an allowlisted local bot.","owner":"nardovibecoding","repoUrl":"https://github.com/nardovibecoding/simply-telegram-bridge","license":"AGPL-3.0","licenseTier":"strong-copyleft","trust":"community","stars":1,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-03-26T10:01:03.000Z","addedAt":"2026-10-21T08:34:58.925Z","logoUrl":"https://avatars.githubusercontent.com/u/121169412?u=1eac81e404330f5538d96f58319f2f9e16e456a8&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["communication","developer-tools"],"tags":["claude-agent-sdk","claude-code","developer-tools","python","remote-coding","telegram","telegram-bot","vibecoding"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-23T12:31:04.493Z","sample":false,"url":"https://conduits.dev/tools/simply-telegram-bridge","language":"Python","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"<p align=\"center\">\n  <h1 align=\"center\">simply-telegram-bridge</h1>\n  <p align=\"center\"><strong>Control Claude Code from Telegram with an allowlisted local bot.</strong></p>\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/nardovibecoding/simply-telegram-bridge/stargazers\">\n    <img src=\"https://img.shields.io/github/stars/nardovibecoding/simply-telegram-bridge?style=for-the-badge&color=orange\" alt=\"Stars\">\n  </a>\n  <img src=\"https://img.shields.io/badge/Python-3.10%2B-blue?style=for-the-badge&logo=python&logoColor=white\" alt=\"Python 3.10+\">\n  <img src=\"https://img.shields.io/badge/Platform-macOS%20%7C%20Linux-lightgrey?style=for-the-badge\" alt=\"Platform\">\n  <img src=\"https://img.shields.io/badge/Model-Haiku%20%7C%20Sonnet%20%7C%20Opus-purple?style=for-the-badge\" alt=\"Models\">\n  <a href=\"LICENSE\">\n    <img src=\"https://img.shields.io/badge/License-AGPL--3.0-red?style=for-the-badge\" alt=\"License\">\n  </a>\n</p>\n\n<p align=\"center\">\n  <img src=\"demo.gif\" alt=\"Telegram bridge receiving command and streaming Claude Code response\" width=\"700\">\n</p>\n\n---\n\n## Problem\n\nYou want to check on Claude Code from your phone without exposing a full remote\nshell or copying your private automation stack into a public repo.\n\nThis template gives you a small local Telegram control surface for Claude Code.\nIt keeps the bot local, requires an explicit allowlist by default, and leaves\ndeployment choices to you.\n\n## Install\n\nOne command. Takes 60 seconds.\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/nardovibecoding/simply-telegram-bridge/main/install.sh | bash\n```\n\nClones the repo, installs dependencies, prompts for bot token + settings, writes `.env`. Just run `python3 bot.py` after. The installer requires `ALLOWED_USERS` unless you explicitly opt into `ALLOW_ALL_USERS=true`.\n\n**Prerequisites:**\n- Python 3.10+\n- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) installed and authenticated\n- A Telegram bot token (from [@BotFather](https://t.me/BotFather))\n\n---\n\n## Quickstart\n\n```bash\nexport BOT_TOKEN=\"000000000:FAKE_TELEGRAM_BOT_TOKEN_FOR_LOCAL_TESTS\"\nexport ALLOWED_USERS=\"123456789\"   # your Telegram user ID\nexport WORKING_DIR=\"/path/to/project\"\nexport MODEL=\"sonnet\"              # haiku | sonnet | opus\n\npython bot.py\n```\n\nThen open your bot in Telegram and start messaging:\n\n```\nYou:  What's the git status?\n\nBot:  Working...\n        $ git status\n        Read README.md\n\nBot:  Clean — on branch main, 3 commits ahead of origin.\n      Last commit: \"fix: handle edge case in parser\"\n      (4.2s, 2 tool calls)\n```\n\n---\n\n## How It Works\n\n```\nTelegram message\n      │\n      ▼\n  Bot (bot.py)\n      │   auth check → allowed users only\n      │\n      ▼\nClaude Code SDK (sdk_client.py)\n      │   persistent connection, auto-reconnect\n      │\n      ├──▶ Bash      $ git status, pytest, npm run build …\n      ├──▶ Read      open any file in the working directory\n      ├──▶ Write     create new files\n      ├──▶ Edit      patch existing files\n      ├──▶ Grep      search file contents\n      ├──▶ Glob      find files by pattern\n      ├──▶ WebSearch research from the web\n      ├──▶ WebFetch  fetch a URL\n      └──▶ Agent     spawn sub-agents for complex tasks\n             │\n             ▼\n      streaming response\n      (tool calls shown live as they happen)\n             │\n             ▼\n      Telegram reply with timing stats\n```\n\nCold start: ~6 s once. Subsequent messages: 2–3 s.\n\n---\n\n## Features\n\n| Capability | Detail |\n|---|---|\n| Full tool access | Bash, Read, Write, Edit, Grep, Glob, WebSearch, WebFetch, Agent |\n| Live tool progress | Each tool call shown in real-time as Claude works |\n| Streaming text | Response text updates as it arrives, not just at the end |\n| Long message splitting | Responses >4096 chars split automatically |\n| Task cancellation | `/cancel` stops a running task mid-execution |\n| Auto-reconnect | Persistent SDK connection restarts transparently on crash |\n| Multi-model | Switch between Haiku, Sonnet, and Opus via env var |\n| Allowlist auth | Restrict access to specific Telegram user IDs |\n| Custom working dir | Point Claude at any directory on the host machine |\n| Custom system prompt | Override the default assistant persona |\n| Markdown rendering | Bot responses rendered as HTML — bold, code, links preserved |\n| Rate limiting | Configurable per-user message rate limit (default: 5 req/min) |\n| File/image input | Send photos or documents — bot passes them to Claude as input |\n| Multi-session | Per-chat working directories via JSON mapping |\n| 3-file footprint | `bot.py` + `sdk_client.py` + `requirements.txt` — ~300 lines total |\n\n---\n\n## Setup Guide\n\n### 1. Create a Telegram Bot\n\n1. Open [@BotFather](https://t.me/BotFather) in Telegram\n2. Send `/newbot` and follow the prompts\n3. Copy the token. Public examples in this repo use fake token placeholders.\n\n### 2. Find Your Telegram User ID\n\nMessage [@userinfobot](https://t.me/userinfobot) — it replies with your numeric user ID.\n\n### 3. Configure Environment\n\n```bash\nexport BOT_TOKEN=\"000000000:FAKE_TELEGRAM_BOT_TOKEN_FOR_LOCAL_TESTS\"\nexport ALLOWED_USERS=\"111222333\"          # your user ID (comma-separated for multiple)\nexport WORKING_DIR=\"$HOME/myproject\"      # directory Claude operates in\nexport MODEL=\"sonnet\"                     # haiku | sonnet | opus\nexport SYSTEM_PROMPT=\"You are a helpful coding assistant.\"  # optional\n```\n\n### 4. Run\n\n```bash\npython bot.py\n```\n\nTo keep it running in the background:\n\n```bash\nnohup python bot.py > bridge.log 2>&1 &\n```\n\nOr as a systemd service (Linux):\n\n```ini\n[Unit]\nDescription=Claude Telegram Bridge\n\n[Service]\nExecStart=/usr/bin/python3 /opt/simply-telegram-bridge/bot.py\nEnvironmentFile=/opt/simply-telegram-bridge/.env\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\n```\n\n---\n\n## Configuration Reference\n\n| Variable | Required | Default | Description |\n|---|---|---|---|\n| `BOT_TOKEN` | Yes | — | Telegram bot token from BotFather |\n| `ALLOWED_USERS` | Yes by default | empty | Comma-separated Telegram user IDs |\n| `ALLOW_ALL_USERS` | No | `false` | Set `true` only for a private test bot |\n| `WORKING_DIR` | No | `~` | Directory Claude operates in |\n| `MODEL` | No | `sonnet` | `haiku`, `sonnet`, or `opus` |\n| `SYSTEM_PROMPT` | No | `\"You are a helpful coding assistant.\"` | System prompt for the session |\n| `RATE_LIMIT` | No | `5` | Max messages per user per minute |\n| `CHAT_DIRS` | No | — | JSON mapping of chat ID → working dir, e.g. `{\"123456\": \"/projects/foo\"}` |\n\n---\n\n## Commands\n\n| Command | What it does |\n|---|---|\n| (any text) | Sent to Claude Code — full tool access |\n| `/cancel` | Cancel the currently running task |\n\n---\n\n## Security\n\n**ALLOWED_USERS is your first line of defense.** Set it to your Telegram user ID. If it is empty, this template denies all users unless `ALLOW_ALL_USERS=true`.\n\n```bash\n# Single user\nexport ALLOWED_USERS=\"111222333\"\n\n# Multiple users\nexport ALLOWED_USERS=\"111222333,444555666\"\n```\n\n**What Claude can do:** The bot can execute Claude Code tools from the configured working directory. Only grant access to users you trust completely.\n\n**Credentials:** `BOT_TOKEN` and `ALLOWED_USERS` are env vars — never committed to git. Use a `.env` file locally and `EnvironmentFile` in systemd.\n\n---\n\n## Architecture\n\n3 files, ~300 lines:\n\n| File | Lines | Responsibility |\n|---|---|---|\n| `bot.py` | ~160 | Telegram bot — auth, message handling, progress display, cancellation |\n| `sdk_client.py` | ~130 | Claude SDK wrapper — persistent connection, streaming, auto-reconnect |\n| `requirements.txt` | 2 | `python-telegram-bot` + `claude-agent-sdk` |\n\nThe SDK client maintains a single persistent connection per process. On disconnect or crash, it reconnects transparently before the next query. The lock ensures concurrent Telegram messages are serialized to the same session.\n\n---\n\n## Battle-Tested\n\nThis public template is intentionally smaller than a private production bot stack. It omits private deployment wiring, logs, runtime state, and operational workflows.\n\n---\n\n## Star History\n\n[![Star History Chart](https://api.star-history.com/svg?repos=nardovibecoding/simply-telegram-bridge&type=Date)](https://star-history.com/#nardovibecoding/simply-telegram-bridge&Date)\n\n---\n\n## License\n\n[AGPL-3.0](LICENSE) — see [NOTICE](NOTICE) for attribution.\n"}