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.1.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.1-py3-none-any.whl (29.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: teleclaude-0.3.1.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.1.tar.gz
Algorithm Hash digest
SHA256 a2c8f093e0dc12315ca70d191a6db77da916d3ea1746830bb8b36776531e0ac4
MD5 f075614dc7d23bc4f0f44ec38df103ec
BLAKE2b-256 94048670011dd04eedc077917de797b75af72ab7e47aa191c4bd816c58da773d

See more details on using hashes here.

Provenance

The following attestation bundles were made for teleclaude-0.3.1.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.1-py3-none-any.whl.

File metadata

  • Download URL: teleclaude-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 29.7 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9fe6a88e4bf0c51e3ff0c5c63c95f6cb5fa96b862ad76f4fdbf9090d50cae4e3
MD5 6ec32fa9c7efd96d37b573aadb176e0e
BLAKE2b-256 a4d8268e40b57c4cb955390448a3d7c377656085e233627499eedf9475d69c48

See more details on using hashes here.

Provenance

The following attestation bundles were made for teleclaude-0.3.1-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