by alexei-led
Telegram ↔ tmux bridge for Claude Code, Codex CLI, and Gemini CLI. Monitor output, respond to prompts, manage parallel sessions. Control AI coding agents from your phone.
# Add to your Claude Code skills
git clone https://github.com/alexei-led/ccgramControl AI coding agents from your phone. CCGram bridges Telegram to tmux — monitor output, respond to prompts, and manage multiple sessions without touching your computer. Supports Claude Code, Codex CLI, Gemini CLI, Pi, and plain shell sessions.
AI coding agents run in your terminal. When you step away — commuting, on the couch, or just away from your desk — the session keeps working, but you lose visibility and control.
CCGram fixes this. It operates on tmux, not any agent SDK. Your agent process stays exactly where it is, in a tmux window on your machine. CCGram reads its output and sends keystrokes to it. This means:
tmux attach and you're back with full scrollbackOther Telegram bots wrap agent SDKs into isolated API sessions that can't be resumed in your terminal. CCGram is a thin control layer over tmux — the terminal stays the source of truth.
graph LR
subgraph phone["📱 Telegram Group (Forum Topics)"]
direction TB
T1["💬 api — Claude"]
T2["💬 ui — Codex"]
T3["💬 data — Gemini"]
T4["💬 ops — Shell"]
T5["💬 lab — Pi"]
end
subgraph bridge["⚡ CCGram"]
direction TB
B1["read output\n(transcripts + terminal)"]
B2["send keystrokes\n(tmux send-keys)"]
B3["instant notifications\n(Claude hooks)"]
end
subgraph machine["🖥️ Your Machine — tmux session"]
direction TB
W1["window @0 · claude"]
W2["window @1 · codex"]
W3["window @2 · gemini"]
W4["window @3 · bash"]
W5["window @4 · pi"]
end
phone -- "messages / voice" --> bridge
bridge -- "responses / live view" --> phone
bridge <--> machine
style phone fill:#e8f4fd,stroke:#0088cc,stroke-width:2px,color:#333
style bridge fill:#fff8e1,stroke:#f9a825,stroke-width:2px,color:#333
style machine fill:#f0faf0,stroke:#2ea44f,stroke-width:2px,color:#333
Each Telegram Forum topic binds to one tmux window. Messages you type are sent as keystrokes to the pane; responses are parsed from session transcripts and delivered back as Telegram messages.
/cost, Codex /status, Gemini /chat, Pi /compact, etc.); mismatched commands report errors/panes for overview/live command; content-hash gating skips edits when nothing changed; auto-stops after timeout (configurable)/send) — send workspace files to Telegram: exact path (/send docs/arch.png), glob (/send *.png), substring search (/send arch), or interactive browser (/send). Project-scoped with security filtering (hidden files, credentials, gitignored, >50 MB denied)/toolbar) — provider-specific inline buttons. Universal row: Screenshot, Ctrl-C, Live, Send. Provider row varies: Claude (Mode, Think, Esc), Codex (Esc, Enter, Tab), Gemini (Mode, YOLO, Esc), Pi (Esc, Enter, Tab), Shell (Enter, EOF, Suspend)CCGRAM_STATUS_MODE=system (default, green = agent working) or user (green = idle, ready for input) — pick the convention that matches how you scan the topic listCCGRAM_HIDE_TOOL_CALLS=true globally hides tool_use/tool_result messages; /toolcalls cycles per-window (default → shown → hidden). Hook events (Stop, errors, subagent updates) bypass the gate/history/sessions shows all active sessions with status and kill buttonsgraph TB
subgraph providers["Agent Providers"]
direction LR
C["🟠 Claude Code\nhook events · resume · JSONL"]
X["🧩 Codex CLI\nresume · continue · JSONL"]
G["♊ Gemini CLI\nresume · continue · JSONL"]
P["🥧 Pi\nresume · continue · JSONL"]
S["🐚 Shell\nnl→command · raw mode"]
end
subgraph detection["Auto-Detection"]
D1["process name\n(fast path)"]
D2["ps -t tty\n(JS runtime fallback)"]
D3["pane title symbols\n(Gemini fallback)"]
end
providers --> detection
style providers fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px,color:#333
style detection fill:#e8f4fd,stroke:#0088cc,stroke-width:2px,color:#333
ps -t TTY fallback for JS runtime wrappers (node/bun)! to bypass the LLM and send commands directlygraph LR
subgraph agents["Agent Windows"]
A1["claude · api"]
A2["codex · ui"]
A3["shell · ops"]
end
subgraph mailbox["~/.ccgram/mailbox/"]
M["file-based\nper-window inboxes\nJSON messages · TTL"]
end
subgraph telegram["Telegram"]
N["silent notifications\nin sender + recipient topics"]
S["spawn approval\ninline keyboard"]
end
A1 -- "ccgram msg send" --> mailbox
mailbox -- "broker injects\nvia send-keys" --> A2
A3 -- "ccgram msg spawn" --> S
mailbox --> N
style agents fill:#f0faf0,stroke:#2ea44f,stroke-width:2px,color:#333
style mailbox fill:#fce4ec,stroke:#c62828,stroke-width:2px,color:#333
style telegram fill:#e8f4fd,stroke:#0088cc,stroke-width:2px,color:#333
~/.ccgram/mailbox/) — no database, no daemonclaude (default), codex, gemini, or pi installed and authenticated (or use shell with no extra install)uv tool install ccgram # recommended
pipx install ccgram # pipx
brew install alexei-led/tap/ccgram # Homebrew (macOS)
No comments yet. Be the first to share your thoughts!