Control any coding agent through Telegram.
What you get
- 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
Instalation
todo: Setup cargo-binstall todo: Package with nix
Hacking
How it works
CLI ──(Unix socket IPC)──> Daemon ──> ACP Agent subprocesses (stdin/stdout)
│
└──> Telegram Bot API (topics, messages)
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
Quick start
1. Configure
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" [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_DEFAULT_AGENTTELEGRAM_ACP_TELEGRAPH_AUTHOR
2. Build
3. Run daemon
4. Create a session
cargo run -- new /path/to/project cargo run -- new /path/to/project --agent codex
Mock agent testing
Use the included mock ACP binary to test Telegram/IPC plumbing without a real coding agent:
Configure it as an agent in your config:
default_agent = "mock" [mock] cmd = "./target/debug/mock_agent"
Telegram requirements
- Bot must be added to the target chat
- For private chats using topics, enable Threaded Mode in BotFather
- For supergroups, forum topics should be enabled
Notes
- IPC uses newline-delimited JSON over a Unix socket
- Designed for long-running daemon operation
- Current Telegraph support is present but not fully wired into the runtime flow
Architecture highlights
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
- 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
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
formatting.rs Telegram HTML escaping + message splitting
bin/mock_agent.rs Mock ACP agent for local testing
License
GPL v3


