Skip to main content

Telegram bot framework with Claude Code session integration

Project description

Telegram      Claude Code

TeleClaude

A Python framework for building Telegram bots that use Claude Code to read, plan, and edit their own codebase - with human-in-the-loop approval, voice transcription via OpenAI Whisper, and self-restarting deployment.

anthropic claude-code claude-code-channels telegram-bot ai-agent self-improving-software whisper voice-to-code agentic-coding python

PyPI Python License


The idea: let Claude Code edit itself through Telegram

Your bot is a thin Telegram relay. Claude Code is the agentic part - it reads the codebase, proposes changes, and writes files when you approve. The bot just forwards your messages to Claude Code and sends back the response.

The result is a closed-loop development cycle: chat -> analyze -> plan -> approve -> edit -> restart. No IDE, no SSH, no deploy pipeline. Just a conversation with your running application from your phone - or even a voice message transcribed via Whisper.

What about Claude Code Channels? Anthropic's official Telegram/Discord/iMessage channels are a promising direction, but they're still in research preview - when we last tested them, the experience wasn't stable enough for production use. TeleClaude was built to fill that gap: your bot runs Claude Code as a subprocess on the server where it's deployed, with a plan/approve workflow and self-restart baked in. No local machine needed, no --channels flag, no Bun dependency - just pip install and go. If Channels matures into a solid production path, we'd love to add it as an alternative backend - contributions welcome.

Claude Bot

How it works

+----------------+        +-----------------+        +--------------------+
|   Telegram     |  msg   |   TeleClaude    | stdin  |    Claude Code     |
|   (phone)      |------->|   (Python bot)  |------->|    (subprocess)    |
|                |<-------|                 |<-------|                    |
|                | reply  |  plan/approve   | stdout |   reads/edits      |
|                |        |  workflow       |        |   your codebase    |
+----------------+        +-----------------+        +--------------------+

Claude control example from PolyBot

  1. You send a message in Telegram
  2. TeleClaude routes it to Claude Code in read-only plan mode
  3. Claude analyzes your codebase and proposes a plan
  4. You /approve or /reject from Telegram
  5. On approve, Claude executes with file-edit permissions
  6. /restart reloads the bot to pick up code changes
  7. The application is now running its improved version of itself

Quickstart

Prerequisites

Install

pip install teleclaude

Create your bot

import os, time
from dotenv import load_dotenv
from teleclaude import ClaudeSession, TeleClaudeBot, kill_previous

load_dotenv()

kill_previous("bot.pid")
session = ClaudeSession(project_dir=".")
bot = TeleClaudeBot(
    token=os.environ["TELEGRAM_BOT_TOKEN"],
    chat_id=os.environ["TELEGRAM_CHAT_ID"],
    claude_session=session,
)
bot.start_polling()

try:
    while bot.running:
        time.sleep(1)
except KeyboardInterrupt:
    bot.stop_polling()

That's it. Send any message in Telegram and Claude Code responds. Built-in commands:

Command What it does
Free text Chat with Claude Code (read-only mode)
Voice msg Transcribed via Whisper, then routed to Claude
/claude Interactive menu: model switcher, session info, flush, approve/reject
/approve Execute Claude's pending plan (allows file edits)
/reject Discard the pending plan
/session Session management (/session pin <id>, /session clear)
/context Check Claude Code availability (rate-limit detection)
/restart Restart the bot process (picks up code changes)
/help Show all available commands

Add your own commands

Subclass TeleClaudeBot and override domain_commands() to register custom /commands:

import subprocess
from teleclaude import ClaudeSession, TeleClaudeBot, kill_previous

class MyBot(TeleClaudeBot):
    def domain_commands(self):
        return {
            "/status": (self.cmd_status, "Show git status"),
        }

    def cmd_status(self):
        result = subprocess.run(
            ["git", "log", "--oneline", "-5"],
            capture_output=True, text=True, cwd=self._project_dir,
        )
        self.send(f"<pre>{result.stdout or 'No git history.'}</pre>")

Other hooks you can override:

Hook Purpose
on_domain_callback(data, message_id) Handle inline keyboard callbacks
help_text() Customize /help output
on_restart() Customize restart behavior
plan_prompt_wrapper(text) Customize the prompt sent to Claude in plan mode

Features

Voice messages

Send a voice message in Telegram and it gets auto-transcribed via OpenAI Whisper, then routed to Claude. Install the optional dependency:

pip install openai-whisper

The Whisper model (base) is lazy-loaded on first voice message. If not installed, the bot replies with install instructions.

Session handoff

The /claude menu includes Flush & New Session, which:

  1. Asks Claude to write a .handoff.md summary of the current session context
  2. Clears the session pin
  3. On the next message, a new session bootstraps from .handoff.md automatically

To enable automatic handoff bootstrap, pass bootstrap_file to ClaudeSession:

session = ClaudeSession(project_dir=".", bootstrap_file=".handoff.md")

Rate-limit detection

When Claude returns a rate-limit error, the bot automatically starts background polling (every 5 min, up to 12 h) and notifies you when Claude is back online. You can also manually check via /context or the /claude menu.

Configuration reference

ClaudeSession options

session = ClaudeSession(
    project_dir=".",              # repo root (resolved to absolute path)
    model="opus",                 # "opus", "sonnet", or "haiku"
    output_format="json",         # "json" or "stream-json"
    bootstrap_file=".handoff.md", # auto-inject on new sessions (None to disable)
    auto_pin=True,                # auto-save session ID on first use
    session_name_prefix="mybot",  # generates mybot-1, mybot-2, etc.
    plan_max_turns=25,            # max turns in plan (read-only) mode
    edit_max_turns=25,            # max turns in edit mode
    plan_tools=["Read", "Grep"], # override default plan-mode tools
    edit_tools=["Read", "Edit"], # override default edit-mode tools
    on_session_fallback=callback, # called when pinned session expires
)

Development

git clone https://github.com/ofir5300/teleclaude.git
cd teleclaude
pip install -e .
cd example && cp .env.example .env  # fill in your tokens
python main.py

Contributing

Contributions welcome! Open an issue or PR on GitHub.

License

MIT - Ofir Cohen

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

teleclaude-0.3.0.tar.gz (1.0 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

teleclaude-0.3.0-py3-none-any.whl (29.4 kB view details)

Uploaded Python 3

File details

Details for the file teleclaude-0.3.0.tar.gz.

File metadata

  • Download URL: teleclaude-0.3.0.tar.gz
  • Upload date:
  • Size: 1.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for teleclaude-0.3.0.tar.gz
Algorithm Hash digest
SHA256 72a8dc87bfef77f60d3442c9d6fe8f71906b959c3d3798950c35d7b4c3217227
MD5 d8a1d4ff459c66abaf56fa340e29ef02
BLAKE2b-256 9d104edfacf5daf249d1e35e0ef37661cba731f49cf1ada3b035130d31bc865b

See more details on using hashes here.

Provenance

The following attestation bundles were made for teleclaude-0.3.0.tar.gz:

Publisher: publish.yml on ofir5300/teleclaude

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file teleclaude-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: teleclaude-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 29.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for teleclaude-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3970230f3ce7ccdefe544bf010c5a1cbe2a5ea8cbfcb18777e4be23b8d381057
MD5 7fcb0ea8de6d99c8f2e721538810cca8
BLAKE2b-256 d140906a3655b7db758a434d2c545b5c9a95b78c9b7d84c5782564b14ca424a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for teleclaude-0.3.0-py3-none-any.whl:

Publisher: publish.yml on ofir5300/teleclaude

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page