A Telegram client that lives in your terminal. Keyboard-first, vi-shaped, borderless — and the same account exposed to your agents over MCP and REST.
tg │ 1:all 2:unread 3:work 4:channels 5:archive ● connected · 1 device │ 21:04 / filter chats… 9/9 │ # infra-oncall │ group · … buf 1 │ ln 44/44 bot │ PINNED ▌# infra-oncall 2m │ 09:16 nadia ↳ you Taking 4412. Backoff c… │ ▪ Deploy window 14:00–1… ivo ▌ nadia: rebased, CI green [4] │ Yes, jittered. Full ±20%. │ ▪ Runbook: auth p95 s… nadia @ Nadia Feld 6m │ TODAY ────────────────────────────────────────── │ you: pushing the tag now │ 20:41 ivo Rollout paused — session hits │ MEMBERS · 24 # relay-protocol 14m │ spiked on the auth path. │ ● ivo admin ivo: the 429 is upstream [2] │ @nadia can you look? │ ● nadia ~ wire notes 1h │ ▣ auth-p95-260… 184 KB · png │ ● sam draft: saved locally │ [👀 5] [🔥 2] │ ○ mira 4h ! ops-alerts muted 2h │ 20:44 sam The offending query, for the │ ○ jonas 2d p95 back under 400ms (31) │ record: │ · +19 more @ Mira Okonkwo 4h │ ┌ sql ───────────── 4 lines ┐ │ sounds good — thurs then │ │1 SELECT s.* FROM session…│ │ FILES # design-crit yd │ │2 JOIN devices d ON d.s…│ │ ▣ auth-p95-2608.png 184K you: left comments on 3 │ │3 - WHERE s.touched > now…│ │ ▤ incident-0812.md 6K ! tape/changelog muted yd │ │4 + WHERE s.touched > now…│ │ ▤ backoff.patch 2K v0.4.1 — keymap overhaul │ └───────────────────────────┘ │ @ Jonas Vik 2d │ 20:47 nadia That is the migration │ thanks, that unblocked me │ backfill, not the rollout. It │ │ drains in ~20 min. │ │ 20:52 you Confirmed from the queue │ │ dashboard. Resuming. ✓✓ │ │ 4 NEW ────────────────────────────────────────── │ │ 20:58 ivo Resumed. Canary at 5%. │ │ 21:01 nadia ↳ ivo Resumed. Canary at 5%. │ │ Rebased onto main, CI is │ │ green now. 4412 ready for the │ │ second approval. │ │ 21:02 sam Approved. Merging behind the │ │ flag. │ │ [🚀 4] │ │ ▌ 21:03 ivo Good. I will write the │ │ ▌ incident note either way — │ │ ▌ cheap to have, expensive to │ │ ▌ reconstruct. │ │ ··· nadia is typing… │ │ reply ↳ nadia: Rebased onto main, C… esc to drop │ │ NORMAL › i to compose · : for commands md │ j/k move l open / filter [/] folder u unread i compose q quit ? keymap idx 12 msgs · 9 buffers · 37 unread
Not a screenshot — this is the renderer's own output, the same 120×40 golden fixture the test suite asserts against cell for cell, with its real colours. Every row is exactly 120 display cells wide; the suite fails if one is not. Sample data, no real conversations.
Most terminal chat clients draw a desktop app with ASCII. This one does not. There are no bubbles, no avatars, no rounded boxes — panels are divided by single-cell rules, messages sit on a fixed time / sender / body grid so the whole conversation aligns to one column, and every row is exactly the width of your terminal.
Graphics are opt-in. Media normally appears as a metadata card; a photo is drawn in the pane only when
you open it. Code fences are framed and line-numbered, quotes get a rule, spoilers stay hidden until
you press x.
It is modal, and it says so: the composer carries a NORMAL / INSERT / VI / COMMAND badge, so one glance answers whether the next letter types, navigates, or runs a command.
Telegram's own folder filters as numbered tabs, with pinned/include/exclude semantics. u jumps to the next chat with something in it.
+ opens a one-row picker of the twelve defaults and opens on the one you already left, so pressing it again takes it off. p pins.
f opens a searchable destination picker — your chats first, then anything the server matches — and confirms before it sends.
A channel post with comments says so, and t opens the discussion in the linked group at the post's own copy.
Thirty cells beside the thread: pinned messages, members, shared files and links — chosen by chat type, fetched only when you open it.
Per-chat drafts, emacs or vi line editing, Ctrl+O to finish the message in $EDITOR, clipboard image paste, optional Markdown.
Motions are vi's and are not configurable — j/k move by message,
Ctrl+E/Ctrl+Y scroll the buffer, and a count prefix works
(9k moves nine messages back). The action keys are mnemonics and every one of them can be
rebound; a binding that collides with something already claimed is refused and reported at
startup rather than silently shadowing it.
| Key | Does |
|---|---|
j / k | Cursor to the next / previous message |
h / l | Move between panels — they are edges, not a cycle |
[ / ] | Previous / next folder, from either browsing panel |
i | Open the cursored chat and start composing |
r / e / d | Reply, edit, delete — d asks, and says for whom |
f | Forward to another chat |
+ / p | React / pin |
/ · Ctrl+G | Search this buffer · search every chat |
: | Command palette |
? | Context-sensitive help, built from the bindings actually in force |
The same Telegram layer ships as three binaries: tele-tui (the client above), telegram-mcp (an MCP server over stdio) and telegram-api (a JSON REST API, standard library only).
The service front ends are built for being pointed at an agent, which is a threat model rather than a feature list. The REST API is loopback-only and bearer-authenticated by default, and refuses to start unauthenticated unless you say so explicitly. Sending a file is limited to an allowlist of directories you choose — logged at startup — so a message from a stranger cannot talk a model into mailing out your SSH key.
🍺 Homebrew — macOS and Linux, Intel and ARM. Installs all three binaries.
🐹 Go toolchain — if you already have Go 1.25 or newer.
Two things to know about this route. The binary lands in $GOPATH/bin as
teletui, not tele-tui — go install names it after its
directory, while the release archives and make build both call it
tele-tui. And it reports its version as dev, because the version is
stamped in at link time by the Makefile and go install does not run it.
Neither affects what the program does.
Or build from source. Whichever route you take you need your own
api_id / api_hash from
my.telegram.org/apps — the
client talks to Telegram as your account, not through a bot.
Pure Go, no CGO, no native dependencies. Cross-compiled builds for macOS, Linux, Windows and Android are published on the releases page.
This is a fork, not a from-scratch project. It began as imtaqin/telegram-cli — excellent work, and the foundation everything here is built on.
It has since diverged substantially. The interface was rebuilt around a terminal-native design rather than a chat GUI drawn in ASCII, and the client gained update-sequence persistence, chat folders, reactions, pinning, channel discussions, a context rail, per-chat drafts, message forwarding, and a good deal more — along with the MCP and REST front ends. Enough has changed that calling it the same program would be misleading in the other direction.
Upstream is not responsible for anything here. The project stays MIT-licensed, and the original copyright notice travels with it.