Skip to main content

Drive Claude Code from Telegram: live session cards, policy-gated auto-approval, remote approve/deny, mid-run questions, resume, and a Mini App dashboard.

Project description

Claude Code Telegram Bridge

tests PyPI

Drive Claude Code from your phone.

A Claude Code session driven from Telegram: live card updates, an approval prompt, and the final result.

The bridge runs real Claude Code agent sessions on your machine (through the official claude-agent-sdk, reusing your local claude CLI login) and puts you in control from Telegram:

  • Live session cards. Each session renders as a single self-editing message: state, elapsed time, turn/tool counters, files touched, cost, and the agent's latest line — throttled to respect Telegram's edit rate limits.
  • Mission Control. Run several sessions at once; a pinned panel lists them all with per-session stop / pause / focus / log buttons.
  • A real permission policy, not a YOLO flag. Every tool call the agent makes is classified by a pure, unit-tested policy module: auto-approve, escalate to you as approve/deny buttons, or hard-deny. Three postures (guarded, trusted, yolo) trade convenience against control — and even yolo keeps a catastrophic denylist (rm -rf, git push, disk writes, shutdown).
  • The agent can ask you questions. A built-in ask_owner MCP tool lets the agent pause mid-run and ask a clarifying question in Telegram — tap an option or reply in your own words, and the answer lands in the run as the tool result. One good question beats a confident wrong guess.
  • Conversation resume. /resume fix the failing test too continues the last session's conversation — across bridge restarts, because conversation ids persist in a local SQLite event store.
  • Full transcripts. Every assistant line, tool call (with inputs), tool result, and approval decision is recorded and browsable via /log or the dashboard.
  • Optional Mini App dashboard. A Telegram Mini App streams the transcript live over SSE with inline approve/deny and new-task controls, authenticated with Telegram's signed initData — no separate login.
  • Optional Cloudflare integration. Attach Cloudflare's official MCP servers and headless wrangler credentials so sessions can deploy Workers and Pages — with every deploy going through the approval flow.
  • Bills your Claude subscription, not API credit. By default the spawned CLI's ANTHROPIC_API_KEY is blanked so it falls back to your stored subscription login (CLAUDE_CODE_FORCE_LOGIN).

Single-user by design: the bridge answers to exactly one Telegram account (OWNER_ID) and silently ignores everyone else.

Quickstart

Prerequisites: Python 3.10+, the Claude Code CLI installed and logged in (claude runs in your terminal), and a Telegram bot token from @BotFather.

pip install claude-code-telegram-bridge

# in the directory you want Claude Code to work on:
cp .env.example .env      # or export the variables directly
# set BOT_TOKEN and OWNER_ID (your numeric user id — ask @userinfobot)

ccbridge

Then message your bot:

add dark mode to the settings page and run the tests

A live card appears, updates as the agent works, escalations arrive as approve/deny buttons, and the final summary (with files touched and cost) is posted when the run completes.

Commands

Command Effect
any plain message start a new session on it
/new <task> same, explicit
/resume <task> continue the last conversation with a new task
/resume <sid> <task> continue a specific session's conversation
/status list sessions
/stop <sid> / /stop all stop sessions
/pause <sid> hold at the next non-read action; repeat to resume
/log <sid> recent transcript for a session

Security model

You are handing a coding agent a remote control — the policy layer is the product. It lives in ccbridge/policy.py as pure logic with no I/O, and it is the single gate every tool call passes through (the SDK is always run with a can_use_tool callback; the bridge never uses the SDK's bypassPermissions mode, in any posture).

guarded trusted (default) yolo
Read-only tools (Read, Grep, ...) allow allow allow
Writes inside the workspace ask allow allow
Writes outside the workspace ask ask allow
Shell inside the workspace ask allow allow
Destructive/network shell (rm -r, git push, curl, pip install, ...) ask ask allow
Catastrophic (rm -rf, git reset --hard, shutdown, disk writes) ask ask ask
Writes to the bridge's own code, state, or .env ask ask ask
CLAUDE_CODE_FORBIDDEN_PATTERNS matches deny deny deny

"Ask" means an approve/deny button pair in Telegram; no answer within CLAUDE_CODE_APPROVAL_TIMEOUT_SEC is a deny. The bridge also protects itself: writes to its installed package, its data directory, or a .env file escalate in every posture, because a session that can rewrite its own policy can disarm its own leash.

Honest limitations, stated plainly:

  • Shell-command classification is regex-based, not a shell parser. An interpreter invocation (python -c ...) can write anywhere without tripping the write heuristics. If that matters for your threat model, run guarded, where every shell command asks.
  • CLAUDE_CODE_LOAD_PROJECT_SETTINGS=true (the default) loads the workspace's .claude settings, whose allow-rules are honored by the CLI before the bridge's callback runs. Set it to false to make the bridge's policy the only authority.
  • This is a power tool for your own machine and your own repos. Do not point it at untrusted code or expose the bot to accounts you do not control.

Mini App dashboard (optional)

pip install 'claude-code-telegram-bridge[miniapp]'

Set CLAUDE_CODE_MINIAPP_ENABLED=true. The bridge then serves the dashboard in-process (default 127.0.0.1:8722). Telegram only loads Mini Apps over public https, so put a TLS proxy or tunnel in front (Cloudflare Tunnel, ngrok, Tailscale Funnel) and set CLAUDE_CODE_MINIAPP_BASE_URL=https://your-host. Session cards then grow an "Open dashboard" button.

The API authenticates every request by validating Telegram's HMAC-signed initData against your bot token and checking the user is OWNER_ID — the dashboard is useless to anyone else even if they find the URL.

Configuration

Everything is an environment variable (a .env in the launch directory is read automatically). See .env.example for the full annotated list. The interesting ones:

Variable Default Meaning
BOT_TOKEN bot token from @BotFather (required)
OWNER_ID your numeric Telegram user id (required)
CLAUDE_CODE_WORKSPACE launch dir directory sessions work in
CLAUDE_CODE_PERMISSION_POSTURE trusted guarded / trusted / yolo
CLAUDE_CODE_APPROVAL_TIMEOUT_SEC 300 approval wait before auto-deny
CLAUDE_CODE_MAX_CONCURRENT 3 concurrent session cap
CLAUDE_CODE_MODEL CLI default model override
CLAUDE_CODE_FORCE_LOGIN true bill subscription login, not API key
CLAUDE_CODE_FORUM_MODE false one forum topic per session
CLAUDE_CODE_MINIAPP_ENABLED false serve the dashboard
CCBRIDGE_DATA_DIR ~/.ccbridge event store + state location

How it works

you (Telegram) ──── python-telegram-bot ────┐
     ▲                                      ▼
     │                              ClaudeCodeManager
 live cards,                        one asyncio task per session
 buttons, questions                         │
     ▲                                      ▼
     │                              claude-agent-sdk ──> claude CLI
     │                                      │  can_use_tool callback
     └── policy.decide() ── allow / escalate / deny
                                            │
                    SQLite event store (transcripts, resume, controls)
                                            ▲
                    Mini App (FastAPI + SSE) ┘
  • One process runs everything by default. The SQLite event store makes the Mini App separable (run it elsewhere, point both at the same CCBRIDGE_DATA_DIR) and doubles as transcript persistence and resume-after-restart.
  • Sessions are steered to finish everything in a single turn (the driver is fire-and-forget), and scheduler-shaped tools are removed from the agent's context so it cannot promise background work that would never run.
  • The ask_owner tool is an in-process MCP server injected per session; the policy auto-approves it in every posture because asking is always safer than guessing.

Development

git clone https://github.com/rsprowler/claude-code-telegram-bridge
cd claude-code-telegram-bridge
pip install -e '.[dev,miniapp]'
pytest

The policy module is deliberately dependency-free — if you extend it, add a test next to the existing ones in tests/test_policy.py.

Origins

Extracted from a larger private personal-AI stack, where this bridge has been daily-driven for real work: multi-hour refactors approved from a phone, parallel sessions, deploys to Cloudflare, and an agent that asks before it guesses.

License

MIT

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

claude_code_telegram_bridge-0.1.0.tar.gz (10.0 MB view details)

Uploaded Source

Built Distribution

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

claude_code_telegram_bridge-0.1.0-py3-none-any.whl (48.4 kB view details)

Uploaded Python 3

File details

Details for the file claude_code_telegram_bridge-0.1.0.tar.gz.

File metadata

File hashes

Hashes for claude_code_telegram_bridge-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9c85f11d5b7a76ff24300c34f71bbe30022bc7104a01f18b4490139e83e3bff5
MD5 b4bec502d3bb05fffaf353dd01626b1c
BLAKE2b-256 afcb40a7a6fd66902aeb908eada279d802fa6bab89188be6e34229c18307a13c

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_code_telegram_bridge-0.1.0.tar.gz:

Publisher: publish.yml on rsprowler/claude-code-telegram-bridge

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

File details

Details for the file claude_code_telegram_bridge-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for claude_code_telegram_bridge-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2e88afb7452bf9b3103181d6baa30d3ee7ae10abde511f7e51aa8d76980b5335
MD5 e13cf66077b29575bbab0766d998402e
BLAKE2b-256 8ea2d503304e07e329dd4039c9f3459c4d5b61cbd6d7103de0ac381b4b203eab

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_code_telegram_bridge-0.1.0-py3-none-any.whl:

Publisher: publish.yml on rsprowler/claude-code-telegram-bridge

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