Personal project · self-hosted Telegram agent
Pocket Ops
A Telegram-controlled AI agent for my own machine: a self-hosted Node.js bridge that turns Telegram into a full remote-operations console for a personal Linux workstation, with streaming LLM agent sessions, voice commands, desktop control and a self-healing proxy mesh that keeps everything running without a VPN on hostile networks. About 1,100 lines of Node.js, zero cloud dependencies.
Role
Designer & Systems Engineer
Stack
- Node.js · Bridge core, ~1,100 LOC
- Telegram Bot API · Streaming edit-in-place UX
- Multi-CLI agent layer · OpenCode, Claude Code, Codex, Gemini
- SOCKS5 / HTTP tunnels · VPN-free failover egress
- whisper.cpp · Local voice transcription (fa/en)
AI's role in this project AI-assisted
This project is the philosophy itself: AI agents run on my machine with full access, gated behind an owner-only trust model. The bot is the control plane; the agents do the work.
High-level architecture
02 · Pocket Ops · © 2026
THE PROBLEM
- My workstation holds the real environment; the phone should just be its terminal.
- Public networks and censorship make reaching Telegram itself unreliable, and VPNs drain batteries and fail.
THE APPROACH
- A capability-based adapter contract normalizes five agent CLIs (OpenCode, Claude Code, Codex, Gemini, any OpenAI-compatible endpoint) into one interface, with per-backend JSONL event parsing and model catalogs.
- Streaming output renders into a single Telegram bubble that edits in place: one edit per 2 seconds, rotation past the 4k character limit, and inline Stop / Retry / New-session controls on every reply.
THE ARCHITECTURE
- Owner → Telegram → proxy mesh → Pocket Ops bridge → agent CLIs → full machine.
- A local HTTP-CONNECT forwarder makes spawned processes ride the same failover chain via HTTPS_PROXY; certificate verification is never relaxed.
THE TECHNOLOGY
- Node.js
- Telegram Bot API
- SOCKS5 / HTTP tunnels
- whisper.cpp
- Hyprland / systemd
THE CHALLENGES
- Egress under censorship: harvesting public proxy lists from multiple sources, race-testing candidates with real TLS handshakes, and keeping a sticky failover chain alive when the whole chain burns.
- Never leaking secrets: sudo credentials live in tmpfs for 15 minutes and are injected through an askpass shim, so the password never reaches prompts, logs or model context.
THE RESULT
- My daily-driver console: streaming agent sessions, bilingual voice commands, Hyprland screen and desktop control, file transfer and a restart-persistent prompt scheduler.
- Reliability by design: an 8-minute watchdog on hung agents, pre-flight tunnel checks before polling, and a proxy pool cached to disk that survives restarts even when GitHub is unreachable.