Telegram bot bridge for local coding agents (Codex/Copilot CLI)
Project description
coding-agent-telegram
A Telegram bot bridge for local coding agents such as Codex CLI and Copilot CLI. It lets you manage multiple project sessions from Telegram while keeping execution on your own machine.
The bot accepts private chats only.
✨ What It Does
- Connect one Telegram account to multiple Telegram bots.
- Keep sessions isolated per bot and per chat.
- Bind each session to one project folder and one provider.
- Run local coding agents inside your workspace.
- Show Codex output and file changes back in Telegram.
- Accept text messages and photos as task input.
- Auto-create missing project folders with
/project <folder>.
✅ Requirements
Before starting the server, make sure you have:
- Python 3.9 or newer
- A Telegram bot token from BotFather
- Your Telegram chat ID
- Codex CLI and/or Copilot CLI installed locally
- A workspace directory that contains your projects
🔑 Telegram Setup
Get a Bot Token
- Open Telegram and start a chat with
@BotFather. - Send
/newbot. - Follow the prompts to choose:
- a display name
- a bot username ending in
bot
- BotFather will return an HTTP API token.
- Put that token into
TELEGRAM_BOT_TOKENSin your.env.
Get Your Chat ID
The most reliable way is to use Telegram's getUpdates API with your own bot token.
- Start a chat with your bot and send it a message such as
/start. - Open this URL in your browser, replacing
<BOT_TOKEN>:
https://api.telegram.org/bot<BOT_TOKEN>/getUpdates
- Find the
chatobject in the JSON response. - Copy the numeric
idfield from that object. - Put that value into
ALLOWED_CHAT_IDSin your.env.
Notes:
- For private chats, the chat ID is usually a positive integer.
- If
getUpdatesreturns an empty result, send another message to the bot and try again.
🚀 Quick Start
Option A: Run from a cloned repository
1. Clone the repository
git clone https://github.com/daocha/coding-agent-telegram
cd coding-agent-telegram
2. Start with the bootstrap script
./startup.sh
What startup.sh does:
- creates
.env_coding_agent_telegramfromsrc/coding_agent_telegram/resources/.env.exampleif missing - falls back to legacy
.envif it already exists - creates the state files if missing
- creates
.venvif missing - installs the package into the virtual environment
- starts the Telegram bot server
3. Update The Env File
On first run, update the required fields in .env_coding_agent_telegram:
WORKSPACE_ROOTTELEGRAM_BOT_TOKENSALLOWED_CHAT_IDS
Then run again:
./startup.sh
Option B: Install from PyPI with pip
pip install coding-agent-telegram
coding-agent-telegram
What happens on first run:
- the command creates
.env_coding_agent_telegramin your current working directory if missing - if legacy
.envalready exists, it reuses that instead - it tells you which required fields to update
- after updating the env file, run
coding-agent-telegramagain
Recommended flow:
mkdir -p ~/my-coding-agent-bot
cd ~/my-coding-agent-bot
pip install coding-agent-telegram
coding-agent-telegram
Then update .env_coding_agent_telegram and run:
coding-agent-telegram
📨 Supported Message Types
The bot currently accepts:
- plain text messages
- photos
Current media behavior:
- photos are supported for Codex sessions
- videos are not supported
- video notes are not supported
- animations are not supported
- audio and voice messages are not supported
- documents and stickers are not supported
If an unsupported message type is sent, the bot replies with a short error instead of silently ignoring it.
⚙️ Environment Variables
These are the main fields in the resolved env file, which defaults to .env_coding_agent_telegram and falls back to legacy .env.
Required
-
WORKSPACE_ROOTParent folder that contains your project directories. Example:WORKSPACE_ROOT=~/git -
TELEGRAM_BOT_TOKENSComma-separated Telegram bot tokens. Example:TELEGRAM_BOT_TOKENS=token_one,token_two -
ALLOWED_CHAT_IDSComma-separated Telegram private chat IDs allowed to use the bot. Example:ALLOWED_CHAT_IDS=123456789,987654321
State and Logging
-
STATE_FILEJSON file used to store session state. Default:./state.json -
STATE_BACKUP_FILEBackup copy of the state file. Default:./state.json.bak -
LOG_LEVELPython app log level. Default:INFO -
LOG_DIRDirectory for application logs. Default:./logs
Agent Configuration
-
DEFAULT_AGENT_PROVIDERDefault provider for/newwhen none is specified. Supported values:codex,copilot -
CODEX_BINCommand used to launch Codex CLI. Default:codex -
COPILOT_BINCommand used to launch Copilot CLI. Default:copilot -
CODEX_MODELOptional Codex model override. Leave empty to use the Codex CLI default model. Example:CODEX_MODEL=gpt-5.4 -
COPILOT_MODELOptional Copilot model override. Leave empty to use the Copilot CLI default model. Examples:COPILOT_MODEL=gpt-5.4,COPILOT_MODEL=claude-sonnet-4.6
Use the official model references before setting these values:
-
OpenAI Codex/OpenAI models:
https://developers.openai.com/codex/models -
GitHub Copilot supported models:
https://docs.github.com/en/copilot/reference/ai-models/supported-models -
COPILOT_AUTOPILOTDefault:trueRuns Copilot CLI in autopilot mode by default. -
COPILOT_NO_ASK_USERDefault:trueTells Copilot CLI not to stop and ask the user interactive follow-up questions. -
COPILOT_ALLOW_ALLDefault:truePasses--allow-all, which enables tools, paths, and URLs without confirmation. This is the default here so Copilot CLI can continue non-interactively inside the Telegram bot flow. -
COPILOT_ALLOW_ALL_TOOLSIftrue, pass--allow-all-toolsto Copilot CLI. Use this only if you are comfortable letting Copilot run tools without approval prompts. -
COPILOT_ALLOW_TOOLSComma-separated list of tools to allow without prompting. Example:COPILOT_ALLOW_TOOLS=shell(git),shell(npm) -
COPILOT_DENY_TOOLSComma-separated list of tools to explicitly deny. Example:COPILOT_DENY_TOOLS=shell(rm),shell(chmod) -
COPILOT_AVAILABLE_TOOLSOptional comma-separated allowlist of tools Copilot may use at all. Example:COPILOT_AVAILABLE_TOOLS=shell,apply_patch
GitHub documents these Copilot CLI approval controls here:
-
https://docs.github.com/en/copilot/concepts/about-github-copilot-cli -
https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-command-reference -
CODEX_APPROVAL_POLICYApproval mode passed to Codex. Default:never -
CODEX_SANDBOX_MODESandbox mode passed to Codex. Default:workspace-write -
CODEX_SKIP_GIT_REPO_CHECKIftrue, always bypass Codex's trusted-repo check. Iffalse, existing third-party folders stay protected unless trusted by this app. -
ENABLE_COMMIT_COMMANDIftrue, enable the/commitTelegram command. Default:false
Telegram Behavior
-
SNAPSHOT_TEXT_FILE_MAX_BYTESMaximum file size the bot will read as text when building the before/after snapshot for per-run diffs. Default:200000bytes, about 200 KB -
MAX_TELEGRAM_MESSAGE_LENGTHMax message size used before the app splits responses. -
ENABLE_SENSITIVE_DIFF_FILTERHide diffs for sensitive paths.
Example Env Snippet
WORKSPACE_ROOT=~/git
TELEGRAM_BOT_TOKENS=bot_token_one,bot_token_two
ALLOWED_CHAT_IDS=123456789
CODEX_BIN=codex
COPILOT_BIN=copilot
CODEX_MODEL=gpt-5.4
COPILOT_MODEL=claude-sonnet-4.6
COPILOT_AUTOPILOT=true
COPILOT_NO_ASK_USER=true
COPILOT_ALLOW_ALL=true
COPILOT_ALLOW_ALL_TOOLS=false
COPILOT_ALLOW_TOOLS=shell(git),shell(npm)
COPILOT_DENY_TOOLS=shell(rm)
COPILOT_AVAILABLE_TOOLS=shell,apply_patch
CODEX_APPROVAL_POLICY=never
CODEX_SANDBOX_MODE=workspace-write
CODEX_SKIP_GIT_REPO_CHECK=false
ENABLE_COMMIT_COMMAND=false
SNAPSHOT_TEXT_FILE_MAX_BYTES=200000
LOG_LEVEL=INFO
LOG_DIR=./logs
🤖 Telegram Commands
-
/project <project_folder>Set the current project folder. If the folder does not exist, the app creates it and marks it trusted. If the folder already exists and is still untrusted, the app reminds you to trust it explicitly. -
/new <session_name> [provider]Create a new session for the current project. -
/branch <new_branch>Create a new branch from the repository default branch, after fetching and pulling first. -
/branch <origin_branch> <new_branch>Create a new branch from a specific base branch, after fetching and pulling first. -
/switchShow the latest 10 sessions, newest first. -
/switch page <number>Show another page of stored sessions. -
/switch <session_id>Switch to a specific session by ID. -
/currentShow the active session for the current bot and chat. -
/commit <git commands>Run validated git commit-related commands inside the active session project. This command is available only whenENABLE_COMMIT_COMMAND=true. The app splits chained input such asgit add ... && git commit ..., executes only allowedgitcommands, and ignores non-git segments instead of shelling the raw message. Mutating git commands such asadd,restore, andrmrequire the project to be trusted. -
/pushPushorigin <branch>for the current active session. The branch comes from the active session record, or from the current repository branch if the session does not have one stored.
🧠 Session Model
Sessions are scoped by:
- Telegram bot
- Telegram chat
That means the same Telegram account can use multiple bots without mixing sessions.
Example:
- Bot A + your chat -> backend work
- Bot B + your chat -> frontend work
- Bot C + your chat -> infra work
Each session stores:
- session name
- project folder
- branch name
- provider
- timestamps
- active session selection for that bot/chat scope
⚠️ Diff (file changes)
During each agent run, the bot also takes a lightweight before/after project snapshot so it can summarize changed files and send diffs back to Telegram. This snapshot is taken by the bot app itself, not by Codex or Copilot.
Snapshot notes:
- the app walks the project directory before and after the run
- for normal text files, the app prefers the per-run snapshot diff rather than a git-head diff
- common dependency, cache, and runtime directories are also skipped
- binary files and files larger than
SNAPSHOT_TEXT_FILE_MAX_BYTESare not loaded as text - for huge projects, this extra scan can add noticeable I/O and memory overhead
- if the snapshot cannot represent a file as text, the app falls back to git diff when possible
- for large or non-text files, the diff may still be omitted and replaced with a short unavailable message
Snapshot exclusion rules live in package resource files:
src/coding_agent_telegram/resources/snapshot_excluded_dir_names.txtsrc/coding_agent_telegram/resources/snapshot_excluded_dir_globs.txtsrc/coding_agent_telegram/resources/snapshot_excluded_file_globs.txt
You can override those defaults in the env file without editing the installed package:
-
SNAPSHOT_INCLUDE_PATH_GLOBSForce-include matching paths in diffs. Example:.github/*,.profile.test,.profile.prod -
SNAPSHOT_EXCLUDE_PATH_GLOBSAdd extra diff exclusions on top of the packaged defaults. Example:.*,personal/*,sensitive*.txtNote:.*matches hidden paths, including files inside hidden directories.
If both include and exclude rules match, the include rule wins.
🌿 Branch Workflow
If the selected project is a Git repository, /project reports the current branch and reminds you that:
- you can keep working on the current branch
- or create a dedicated work branch with
/branch
When you run /branch, the app:
- requires
/projectto be set first - detects the default branch if you do not specify one
- runs
git fetch origin - checks out the base branch
- runs
git pull --ff-only origin <base-branch> - creates and switches to the new branch
The chosen branch is stored with the session, so switching sessions restores the expected branch before the agent continues work.
🔐 Git Trust Behavior
- Existing folders follow
CODEX_SKIP_GIT_REPO_CHECK - Folders created through
/project <name>are marked as trusted by this app - Existing folders selected through
/project <name>remain untrusted until you confirm trust in the Telegram prompt - That means newly created project folders can be used immediately
/commitcan be disabled entirely withENABLE_COMMIT_COMMAND- Mutating
/commitoperations are allowed only for trusted projects
🪵 Logs
Logs are written under LOG_DIR.
Main log file:
coding-agent-telegram.log
Typical logged events:
- bot startup and polling start
- project selection
- session creation
- session switching
- active session reporting
- normal run execution
- session replacement after resume failure
- warnings and runtime errors
🗂️ Project Structure
-
src/coding_agent_telegram/Main application code -
tests/Test suite -
startup.shLocal bootstrap and startup entrypoint -
src/coding_agent_telegram/resources/.env.exampleCanonical environment template used by both repo startup and packaged installs -
pyproject.tomlPackaging and dependency configuration
📦 Release Versioning
Package versions are derived from Git tags.
- TestPyPI/testing:
v2026.3.26.dev1 - PyPI prerelease:
v2026.3.26rc1 - PyPI stable:
v2026.3.26
🛠️ Typical Local Flow
./startup.sh
Then in Telegram:
/project my-project
/new my-session
Fix the failing API test in the current project
📌 Notes
- This project is designed for users running the agents locally on their own machine.
- The Telegram bot is a control surface, not the execution environment itself.
- If you run multiple bots, all of them can be managed by one server process.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file coding_agent_telegram-2026.3.27.tar.gz.
File metadata
- Download URL: coding_agent_telegram-2026.3.27.tar.gz
- Upload date:
- Size: 71.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
999ef6ab12beb2c8b85417a80277b2a5f795e09b222f870a0689ec4cae40463b
|
|
| MD5 |
3fee20565f07800c01453c535fbf5960
|
|
| BLAKE2b-256 |
d59380280be4b3c42cabbec2466fd06bc8816425738c770f4c33d3e864df37a6
|
Provenance
The following attestation bundles were made for coding_agent_telegram-2026.3.27.tar.gz:
Publisher:
python-publish.yml on daocha/coding-agent-telegram
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
coding_agent_telegram-2026.3.27.tar.gz -
Subject digest:
999ef6ab12beb2c8b85417a80277b2a5f795e09b222f870a0689ec4cae40463b - Sigstore transparency entry: 1186461497
- Sigstore integration time:
-
Permalink:
daocha/coding-agent-telegram@dfc4edbe1292916d0b9878f85e663d2b312adf74 -
Branch / Tag:
refs/tags/v2026.3.27 - Owner: https://github.com/daocha
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@dfc4edbe1292916d0b9878f85e663d2b312adf74 -
Trigger Event:
release
-
Statement type:
File details
Details for the file coding_agent_telegram-2026.3.27-py3-none-any.whl.
File metadata
- Download URL: coding_agent_telegram-2026.3.27-py3-none-any.whl
- Upload date:
- Size: 55.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
20262c82d46fd42ab07970efe81ffb9642c66955d6113c77cb1f82f7bd087c79
|
|
| MD5 |
a690b294e402bfde855233c7cb83aa5c
|
|
| BLAKE2b-256 |
b9d45691d573604ad0510261a1bf384ac358ac6a4c0100988ab5bb1c44c3edce
|
Provenance
The following attestation bundles were made for coding_agent_telegram-2026.3.27-py3-none-any.whl:
Publisher:
python-publish.yml on daocha/coding-agent-telegram
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
coding_agent_telegram-2026.3.27-py3-none-any.whl -
Subject digest:
20262c82d46fd42ab07970efe81ffb9642c66955d6113c77cb1f82f7bd087c79 - Sigstore transparency entry: 1186461505
- Sigstore integration time:
-
Permalink:
daocha/coding-agent-telegram@dfc4edbe1292916d0b9878f85e663d2b312adf74 -
Branch / Tag:
refs/tags/v2026.3.27 - Owner: https://github.com/daocha
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@dfc4edbe1292916d0b9878f85e663d2b312adf74 -
Trigger Event:
release
-
Statement type: