Project website · Telegram CLI documentation · Telegram group · 简体中文 README
Telegram CLI is a TypeScript command-line interface (CLI) for live Telegram data, local SQLite search, and remote management. It aims to be the most capable Telegram CLI for people and artificial intelligence (AI) agents that need dependable Telegram access from one tg command. Account sessions and synced messages stay on your machine.
Telegram CLI combines online reads, local persistence, file archives, live listeners, remote writes, group administration, account isolation, a local web UI, and structured output in one tool.
It is designed for AI agents:
- Stable command contracts: finite commands support JSON, YAML, Markdown, exit statuses, and stable error codes
- Local-first data access: synced messages stay in SQLite so agents can search and analyze Telegram history without repeated network reads
- Explicit account control:
--accountselects the intended session for one command - Write safety: a write-access gate separates read-only automation from commands that modify Telegram
- Agent skill support: the
using-telegram-cliskill teaches supported agents how to authenticate, sync, query, and avoid unsafe writes
Read the complete Telegram CLI documentation for installation, workflows, every command, automation, safety, and troubleshooting.
Choose a workflow by the data freshness you need, where the result should go, and whether the command changes Telegram.
Use online commands when you need the latest server state. These commands do not add returned messages to SQLite.
tg inbox
tg read @team --since 2h
tg search-online "incident" --chat @team --jsonYou can also inspect contacts, notification settings, folders, and group details without importing messages.
Sync one chat or many chats into the selected account’s SQLite database. Search and analyze the stored copy without reconnecting to Telegram.
tg sync @team
tg search "release" --chat @team
tg recent --chat @team --hours 24Local commands can also filter, summarize, and export stored messages.
Run a local-only management UI for stored messages:
tg webThe server binds to 127.0.0.1, has no login screen, and is intended for local use only. It can browse local SQLite data and trigger read-only sync for the selected chat.
The listen command streams new messages from one chat or many chats without inserting them into the local message database. It can download incoming primary media and run interactive reply or group actions. --no-media only hides rendered media rows; --auto-download still uses the live normalized attachment data.
tg listen @team --auto-downloadUse download for existing messages: a single message, a specific attachment, a grouped album, an inclusive message range, one local date, or a whole chat from newest to oldest. Without --attachment, a single message downloads every downloadable item. --attachment N is one-based and message-local; for --grouped-id, numbering is flattened by message ID and then message-local attachment index. Each transfer refetches the fresh Telegram message and matches the stored descriptor before downloading, so stable errors include attachment_not_found, attachment_not_downloadable, attachment_changed, and media_access_denied.
Downloaded attachments are remembered in the local account database. By default, later tg download runs skip attachments that were already downloaded and print an already downloaded notice in plain output. Use --force to download them again and refresh the saved status. Use --ext jpg,png or repeated --ext options to download only matching file extensions; matching is case-insensitive and accepts values with or without a leading dot.
tg download --chat @team --msg-id 814 --output ./media
tg download @channel 42 --attachment 2
tg download --chat @team --date 2026-07-15 --concurrency 2
tg download --chat @channel --grouped-id 2637798265 --output ./album-media
tg download --chat @channel --all --ext jpg,png --output ./channel-mediaThe archive command writes incremental Markdown and optional media files. It tracks archive progress separately from message sync; when --download-media saves or reuses a media file, it also records that attachment as downloaded in the local account database. Default account archives are reset by tg data reset; custom --output directories are never deleted automatically, so remove old custom archives manually or choose an empty directory after breaking upgrades.
tg archive @team --download-mediaLater runs append new messages and retry referenced media that is still missing.
This release uses a fresh message schema and structured output schema version 2. Old SQLite databases are intentionally not migrated. Reset local data, then re-sync or rebuild archives:
tg data reset --yes
tg data reset --all-accounts --yes
tg sync-allStructured message rows expose content, reply_to_msg_id, media_group_id, and ordered lowercase attachments[].
Send text, files, or captioned media groups from the terminal. Inspect and manage group members, administrators, invites, forum topics, and messages.
tg send @team "Release is ready" --file ./report.pdf
tg group members @team --type admins
tg group member mute @team @alice 2h --yesTelegram CLI also manages contacts, notification settings, and chat folders. The write-access gate covers commands that change Telegram.
Each registered account has a separate session and SQLite database. Select an account for one command without changing the default.
tg stats --account work --jsonFinite commands support JSON, YAML, and Markdown output. Failures return nonzero exit statuses and stable error codes.
Install Node.js 22.12.0 or later, then install Telegram CLI from npm:
npm install -g @will-17173/telegram-cliAuthenticate one account, list its chats, sync one chat, and search the local copy:
tg account add
tg status
tg chats
tg sync @team
tg search "release" --chat @teamReplace @team with a chat name, username, or numeric identifier (ID). Run tg --help or a command such as tg sync --help to inspect available options.
Check a command’s execution scope before you run it:
| Scope | Commands | Effect |
|---|---|---|
| Online read | inbox, read, search-online |
Queries Telegram without storing returned messages. |
| Local persistence | history, sync, sync-all, refresh |
Stores fetched messages in the selected account’s SQLite database. |
| Local read | search, recent, stats, export, web |
Reads local SQLite data without connecting to Telegram. |
| File archive | archive |
Reads Telegram and writes Markdown or media files; --download-media also updates attachment download status in SQLite. |
| Remote write | send, edit, delete, notification, folder, and group actions |
Changes Telegram messages or settings. |
Each account has a separate session and SQLite database. Add --account work to select an account for one command without changing the default.
Use sync <chat> to update a chat from the newest locally stored message. Use history <chat> to continue backfilling older messages from the oldest locally stored message; if the chat has no local rows yet, history starts from the newest Telegram messages.
Disable remote writes before read-only workflows or automation:
tg config write-access off
tg config write-access statusRun tg config write-access on when you intend to modify Telegram again. Enabling the gate does not authorize a specific write.
Keep Telegram application programming interface (API) credentials, proxy credentials, session files, SQLite databases, exports, and archives private.
Use JSON or YAML when a script or coding agent needs structured output:
tg search "release" --account work --jsonFailures return a nonzero exit status and a stable error code. The explicit --account option keeps automation on the intended account.
Install the using-telegram-cli agent skill in a supported coding agent:
npx skills add https://github.com/will-17173/telegram-cli \
--skill using-telegram-cliThe skill covers authentication, synchronization, queries, and write safety.
Use pnpm with Node.js 22.12.0 or later:
pnpm install
pnpm dev --help
pnpm test
pnpm typecheck
pnpm buildLicensed under GPL-3.0-only.