tgcli
Telegram CLI tool in pure Rust using grammers (MTProto). No TDLib, no C/C++ dependencies. cargo build and done.
Quick Install
Homebrew (macOS/Linux)
Shell Script
|
Build from Source
Features
- Auth: Phone → code → 2FA authentication
- Sync: Incremental sync with checkpoints, stored in libSQL (turso) with FTS5
- Chats: List, search, create, join/leave, archive, pin, mute
- Messages: List, search (FTS5 + global API), send, edit, delete, forward, download
- Contacts: List and search from local DB
- Admin: Ban, kick, promote, demote group members
- Read: Mark messages as read
- Stickers: List, search, send stickers
- Polls: Create polls
- Profile: Show and update your profile
- Folders: Create and manage chat folders
- Output: Human-readable tables or
--json
Quick Start
# Authenticate
# Sync messages (incremental by default)
# Full sync (first time or refresh)
# List chats
# Search messages locally (FTS5)
# Search messages globally (Telegram API)
# Send a message
# Download media from a message
Sync Behavior
- First run: Fetches all chats + last 50 messages per chat (configurable with
--messages-per-chat) - Subsequent runs: Pure incremental sync — only fetches new messages since last checkpoint
--full: Forces a full sync, ignoring checkpoints
# Default incremental sync
# Full sync with 100 messages per chat
# Sync with progress suppressed
# Output as JSONL stream
Daemon (Optional)
The daemon command is optional and only needed for real-time message capture.
When to use sync (most use cases):
- Periodic message fetching (cron, on-demand)
- Catching up on missed messages
- One-time data export
- CLI workflows and scripts
When to use daemon:
- Instant notifications as messages arrive
- Real-time message processing pipelines
- Live message streaming to external systems
- Continuous monitoring of specific chats
# Start daemon (listens for real-time updates)
# Daemon with JSONL output (for pipelines)
# Skip background sync (pure real-time only)
# Ignore specific chats or all channels
The daemon maintains a persistent connection to Telegram and stores messages instantly as they arrive. By default, it also runs a background incremental sync to catch any messages that arrived while offline.
Architecture
src/
main.rs CLI entry point (clap)
cmd/ Command handlers
auth.rs Phone → code → 2FA
sync.rs Incremental/full sync
chats.rs List/search/create/join/leave/archive/pin/mute
messages.rs List/search/send/edit/delete/forward/download
send.rs Send text/files/voice/video
contacts.rs List/search contacts
read.rs Mark as read
stickers.rs List/search/send stickers
polls.rs Create polls
profile.rs Show/update profile
folders.rs Create/delete folders
users.rs Show/block/unblock users
typing.rs Send typing indicator
completions.rs Shell completions
store/ turso (libSQL) + FTS5 storage
tg/ grammers client wrapper
app/ App struct + business logic
out/ Output formatting
Storage
- Session:
~/.tgcli/session.db(grammers SqliteSession) - Data:
~/.tgcli/tgcli.db(chats, contacts, messages + FTS5)
Multi-account support via --store:
Reset local database (keeps session):
Shell Completions
# Bash
# Zsh
# Fish
Why Rust?
The Go version (tgcli-go) uses TDLib (C++), requiring complex cross-compilation and system dependencies. tgcli is pure Rust — zero C/C++ deps, single cargo build, tiny binary.
Uses turso for database storage — a pure Rust libSQL implementation with no native compilation required.
License
MIT