telegram-acp (0.2.0)
Installation
[registry]
default = "gitea"
[registries.gitea]
index = "sparse+https://git.k6n.net/api/packages/mats/cargo/" # Sparse index
# index = "https://git.k6n.net/mats/_cargo-index.git" # Git
[net]
git-fetch-with-cli = truecargo add telegram-acp@0.2.0About this package
Telegram-ACP
Control any coding agent through Telegram.
Features
- Get notifications and view real-time progress on your phone
- Give new tasks to agent even you're away from computer
- Works with any agent that supports ACP. This is almost any agent, including claude code, codex, opencode and cursor.
- Handle multiple sessions simutaniously, in different telegram tabs
Installation
Method 1: Use cargo binstall (not recommended)
cargo binstall requires me to manually bump version numbers and do a release, and there's no way to upload a binary on push.
Therefore, the version on binstall can be quite old.
cargo binstall telegram-acp
telegram-acp
Method 2: Use via nix
nix run github:SuperKenVery/Telegram-ACP
Method 3: Compile from source
git clone https://github.com/SuperKenVery/Telegram-ACP.git
cd Telegram-ACP
./dev-loop.fish
Configuration
On Telegram, use @botfather to create a new bot and get your bot token. You should also enable threaded mode in bot settings.
Create ~/.config/telegram-acp/config.toml:
bot_token = "<telegram-bot-token>"
chat_id = 123456789
default_agent = "claude"
# websocket_bind = "127.0.0.1:9001"
[claude]
cmd = "claude-agent-acp"
[codex]
cmd = "codex --acp"
# socket_path = "/tmp/telegram-acp.sock"
# telegraph_author = "Your Name"
Env overrides are also supported:
TELEGRAM_ACP_BOT_TOKENTELEGRAM_ACP_CHAT_IDTELEGRAM_ACP_SOCKET_PATHTELEGRAM_ACP_WEBSOCKET_BINDTELEGRAM_ACP_DEFAULT_AGENTTELEGRAM_ACP_TELEGRAPH_AUTHOR
When websocket_bind is set, the daemon starts a websocket listener and broadcasts each SessionEvent as a JSON text frame. The stream includes user prompts, agent updates, and session lifecycle events for every thread.
Hacking
How it works
CLI ──(Unix socket IPC)──> Daemon ──> ACP Agent subprocesses (stdin/stdout)
│
├──> Telegram Bot API (topics, messages)
└──> Websocket listeners (session event stream)
Per session:
- Creates/uses a Telegram forum topic (or threaded private chat topic)
- Spawns an ACP agent subprocess
- Routes user messages -> agent and agent events -> Telegram
- Optionally broadcasts the same session activity to websocket listeners
Mock agent testing
Use the included mock ACP binary to test Telegram/IPC plumbing without a real coding agent:
cargo run -- daemon
Configure it as an agent in your config:
default_agent = "mock"
[mock]
cmd = "./target/debug/mock_agent"
Then you can send some ACP updates as text via telegram, and it would send those updates to our daemon.
Telegram requirements
- Enable Threaded Mode in BotFather
- For supergroups, forum topics should be enabled
Some design decisions
agent-client-protocoltypes are!Send, so ACP work is pinned to atokio::task::LocalSet- Telegram dispatcher + IPC server run with
tokio::spawnand communicate through channels - Each session has two unbounded channel pairs:
user_tx/user_rx: user text into prompt loopevent_tx/event_rx: agent output back to Telegram consumer
- A daemon-scoped
SessionEventrelay fans out session activity to optional websocket listeners - Notification behavior is intentional:
- first and final message notify
- intermediate streaming messages are silent
- Permission prompts are auto-approved by choosing the first allow option
Project layout
src/
main.rs CLI entrypoint (`daemon`, `new`, `status`)
config.rs Config loading (TOML + env overrides)
daemon.rs Daemon state, session lifecycle, LocalSet bridge
session.rs Prompt loop (PromptRequest orchestration)
acp.rs ACP client integration + subprocess handling
relay.rs SessionEvent model and fan-out sinks
telegram.rs Bot dispatcher, topic routing, event consumer
telegraph.rs Telegraph helpers (account/page publishing)
ipc.rs Unix socket NDJSON daemon/client protocol
types.rs Shared command/response/event types
websocket.rs Websocket broadcaster for SessionEvent listeners
formatting.rs Telegram HTML escaping + message splitting
bin/mock_agent.rs Mock ACP agent for local testing
License
GPL v3
Dependencies
| ID | Version |
|---|---|
| agent-client-protocol | ^0.10 |
| anyhow | ^1 |
| async-trait | ^0.1 |
| base64 | ^0.22 |
| chrono | ^0.4 |
| clap | ^4 |
| dashmap | ^6 |
| dirs | ^5 |
| futures | ^0.3 |
| if-addrs | ^0.13 |
| mdns-sd | ^0.13 |
| platform-dirs | ^0.3 |
| pulldown-cmark | ^0.10 |
| reqwest | ^0.12 |
| rmcp | ^1.2 |
| rolling-file | ^0.2 |
| schemars | ^1 |
| serde | ^1 |
| serde_json | ^1 |
| similar | ^2 |
| telegram-markdown-v2 | ^0.2 |
| telegraph-rs | ^0.6 |
| teloxide | ^0.17 |
| thiserror | ^2 |
| tokio | ^1 |
| tokio-tungstenite | ^0.24 |
| tokio-util | ^0.7 |
| toml | ^1.0 |
| tracing | ^0.1 |
| tracing-subscriber | ^0.3 |
| uuid | ^1 |