Skip to main content

tcli · Telegram in your terminal

Read chats, send messages, and follow conversations with your personal Telegram account.

Python 3.10+ Telethon CLI GitHub stars

English · Русский

Features · Installation · Quick start · Commands · AI agents

tcli                          # Show help and setup steps
tcli chats                    # Find a chat
tcli read "Work chat"         # Read recent messages
tcli send me "Remember the meeting"
tcli watch "Work chat"        # Follow new messages

tcli is a local Python CLI built with Telethon. It uses the Telegram API and acts as your personal account. You need your own API_ID and API_HASH; no bot token is used.

Features

  • Chat list: IDs, names, and unread counts.
  • Message history: recent messages, oldest first, with timestamps and sender IDs.
  • Text messages: send to Saved Messages, usernames, or chats where you can post.
  • Live updates: follow new messages in one chat until Ctrl+C.
  • Local configuration: enter API credentials once using tcli config.
  • Saved login: reuse your local session on later runs.
  • Built-in help: tcli, tcli help, and tcli help <command> work without an account.
  • AI agent skills: project instructions for Codex and Claude Code.

Reading history does not mark messages as read. Outgoing text is literal by default; use --format markdown or --format html for formatting. Terminal control characters are removed from displayed messages.

Current scope

One local account session, text messages, human-readable output, and optional JSON. Media is shown as a placeholder; uploading and downloading attachments are not implemented. Message editing, deletion, and a full-screen interface are not available.

Installation

Requires Python 3.10+, pip, and access to Telegram.

Published package and updates

Install the isolated CLI and its user skills:

pipx install telegram-cli-local
tcli skills install
tcli --version

Update the CLI, then refresh the bundled skills:

pipx upgrade telegram-cli-local
tcli skills install

For an existing Python virtual environment, use python -m pip install --upgrade telegram-cli-local instead. Install pipx using its official instructions. GitHub source installations are also supported:

Clone the repository, or download and extract Code → Download ZIP on GitHub:

git clone https://github.com/BYxarek/telegram-cli.git
cd telegram-cli

Windows · PowerShell

Install for your user:

py -m pip install --user -e .
tcli

If pip is missing, first run py -m ensurepip --upgrade --user.

PowerShell cannot find tcli

Add the user Python scripts directory to PATH:

$tcliScriptsDir = (py -c "import sysconfig; print(sysconfig.get_path('scripts', scheme='nt_user'))").Trim()
$tcliUserPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (($tcliUserPath -split ';') -notcontains $tcliScriptsDir) {
    $tcliUpdatedPath = (($tcliUserPath + ';' + $tcliScriptsDir).Trim(';'))
    [Environment]::SetEnvironmentVariable('Path', $tcliUpdatedPath, 'User')
}
$env:Path = $tcliScriptsDir + ';' + $env:Path
tcli

New terminals receive the saved PATH. Restart an existing terminal or its parent application if needed.

The installed command works from any directory. Editable installation (-e) uses this source folder; if you move it, reinstall from its new location.

Linux / macOS · bash or zsh

Use a virtual environment:

python3 -m venv .venv
.venv/bin/python -m pip install -e .
source .venv/bin/activate
tcli

After activation, tcli works from any directory in that terminal. In a new terminal, activate the environment again using its full path, or run /path/to/telegram-cli/.venv/bin/tcli directly. Some Linux distributions require installing the venv component separately through the OS package manager.

Quick start

1. Get your API credentials

Sign in at my.telegram.org, open API development tools, and create an application. Follow the official Telegram guide to obtain api_id and api_hash.

2. Configure and sign in

tcli config
tcli login

config asks for your API credentials and saves them locally. API hash input is hidden. It does not connect to Telegram. Run it again to replace credentials; invalid input leaves existing settings intact.

login asks for your international phone number, Telegram login code, and 2FA password if enabled. Code and password input is hidden. The session is saved for later commands.

3. Read and send

tcli chats
tcli read "Chat name" --limit 10
tcli send me "Hello from tcli!"

me means your own Saved Messages. Messages are sent from your personal account.

Help

tcli                   # General help, setup steps, and examples
tcli help              # Same general help
tcli help send         # How to send a message
tcli read --help       # Read options and examples

Help does not load configuration, create a session, or connect to Telegram. In an interactive terminal, tcli, tcli help, tcli --help, and tcli -h also check PyPI for a newer stable release. The check uses a one-second network timeout and caches results (including failed checks) for 24 hours in the data directory's cache/update-check.json. Available updates are reported on stderr with upgrade instructions; no update is installed automatically. Network/cache errors are silent. Piped output, command-specific help, and --version skip the check. Set TCLI_NO_UPDATE_CHECK=1 to disable it entirely. Running tcli without a command succeeds instead of showing a missing-command error. Unknown commands and invalid arguments still return an error.

Commands

Command Purpose
tcli config Save or replace API credentials
tcli login Sign in to your personal account
tcli chats --limit 100 List up to 100 chats; default: 50
tcli read "Chat" --limit 20 Read recent messages; default: 20
tcli send "Chat" "Text" Send one plain-text message
tcli watch "Chat" Follow new messages until Ctrl+C
tcli logout Revoke this CLI session, keeping API credentials
tcli help [COMMAND] Show general or command-specific help
tcli doctor [--connect] Check local configuration/session; optionally test connectivity and authorization
tcli skills install [--agent auto|all|codex|claude] Install/update bundled user skills without Telegram access
tcli --version Show the installed CLI version

JSON, search, pagination, and replies

tcli chats --json
tcli read "Chat" --json --limit 20
tcli watch "Chat" --json
tcli read "Chat" --search "meeting" --before 12345 --limit 20
tcli send "Chat" "Reply text" --reply-to 12345
tcli send me --file message.txt

chats --json and read --json return JSON arrays, including [] for empty results. Chat objects contain id, name, and unread_count. Message objects contain id, chat_id, date (ISO 8601 with offset), sender_id (nullable), out, text, and has_media. JSON preserves original text, including Unicode and control characters as escaped sequences; human-readable output removes terminal controls. Media-only messages have empty JSON text. watch --json emits one message object per line (JSONL), flushing immediately. Watch status and errors go to stderr, keeping stdout machine-readable.

--search uses Telegram's text search within the selected chat. Results remain oldest first within each returned page. --before ID excludes that ID and returns older messages; use the smallest returned message ID for the next page. It can be combined with search. --before and --reply-to require positive message IDs from the same chat.

send requires exactly one text source: a positional text argument, --stdin, or --file PATH. Files and stdin use UTF-8 (an optional BOM is accepted). Stdin is read until EOF; empty or whitespace-only input is rejected before connecting. Line breaks and surrounding whitespace are kept in plain mode. --file sends the file's text, not an attachment. All text sources support --reply-to and --format.

Text formatting

tcli send me '**Bold** __italic__ ~~strike~~ `code` [link](https://example.com)' --format markdown
tcli send me '<b>Bold</b> <i>italic</i> <u>underline</u> <s>strike</s>' --format html
tcli send me '<blockquote>Quote</blockquote>' --format html
tcli send me --file message.html --format html --reply-to 12345

--format plain (the default) sends markup literally. Markdown is Telethon's dialect, not Telegram Bot API MarkdownV2: **bold**, __italic__, ~~strike~~, backticks for code, triple backticks for code blocks, and [label](URL). Use HTML for underline and nested formatting. Supported HTML includes <b>, <strong>, <i>, <em>, <u>, <s>, <del>, <code>, <pre>, <a href="URL">, and <blockquote> (also expandable). <pre><code class="language-python">...</code></pre> specifies a code-block language. HTML escapes use &lt;, &gt;, and &amp;. Use actual line breaks, not <br>. The installed Telethon parser does not support spoiler markup; unknown HTML tags are ignored. Telegram may trim surrounding whitespace when parsing formatted text.

PowerShell pipeline example (ensure the shell sends UTF-8):

$OutputEncoding = [System.Text.UTF8Encoding]::new($false)
Get-Content -Raw -Encoding utf8 message.txt | tcli send me --stdin

doctor prints configuration/session paths, validates the effective API credentials without showing their values, and checks session-file presence without connecting or creating files. It exits 1 on invalid configuration or a missing session. File presence does not prove authorization. doctor --connect requires an existing session and additionally connects to Telegram and checks authorization without prompting for login or reading chats. It may update the existing Telethon session.

Choosing a chat

Use me, @username, an exact chat name, or an ID from tcli chats. Chat names are case-sensitive. If names are duplicated, use the ID. Partial name matching and t.me links are not supported.

Put -- before a negative ID, after all options:

tcli read --limit 10 -- -1001234567890
tcli send -- -1001234567890 "Message to a group"
tcli watch -- -1001234567890

The ID above is an example; use an ID from your chat list. Limits must be positive integers. watch records the latest message ID at startup and checks for newer messages every two seconds. It includes outgoing messages from another CLI process, including Saved Messages, and outputs each fetched batch oldest first without a fixed batch limit. Already existing messages are not printed. Messages deleted before the next check cannot be displayed. Open a second terminal to send while watching. Session changes are committed between checks so the watcher does not hold a SQLite write lock while idle. Timestamps use your computer's local time zone.

Configuration and session

Platform Data directory
Windows %LOCALAPPDATA%\telegram-cli\
Linux / macOS, when LOCALAPPDATA is absent ~/.local/share/telegram-cli/

config.json stores API credentials; account.session stores the Telethon session. Both are kept outside the source directory and are independent of your working directory.

For compatibility, TG_API_ID and TG_API_HASH environment variables override the file. If either variable is present, both are required; values from different sources are never mixed. .env files are not loaded automatically.

The session file grants access to your account. Do not publish it, your API hash, login codes, or password. Configuration is stored unencrypted. New configuration files use permissions 0600 on POSIX; Windows inherits access permissions from the profile directory. If a session leaks, revoke it in Telegram: Settings → Devices. Outgoing message text may be saved in your shell history.

AI agents

Agent Skill Invocation
Codex .agents/skills/telegram-cli/SKILL.md $telegram-cli
Claude Code .claude/skills/telegram-cli/SKILL.md /telegram-cli

tcli skills install detects installed agents and installs the bundled skill only for those agents into ~/.agents/skills/telegram-cli/SKILL.md (Codex) and ~/.claude/skills/telegram-cli/SKILL.md (Claude Code). The default --agent auto checks PATH, native ~/.local/bin executables, standard npm/binary locations, Codex.app on macOS, and the Windows Store Codex installation. Configuration folders alone do not count. If no agent is detected, no skill folders are created. Explicit --agent codex, --agent claude, or --agent all bypasses detection for custom installations. This command works offline without API credentials or a Telegram session, and does not install either agent application. An identical file is skipped; a differing file is backed up as SKILL.md.backup-*.bak in the same folder before atomic replacement. Other files stay in place. Merge personal instructions from the backup manually. Symlinked skills are not replaced; update their source instead. Restart your agent or start a new session if the updated skill does not appear.

For a cloned checkout, git pull --ff-only updates project-local skills and editable CLI source. Run python -m pip install -e . again to refresh package metadata and dependencies, then tcli skills install if you also installed user copies. Avoid duplicate project/user skills unless you need both scopes.

Open your agent in the project root. Start a new session if the skill is not visible. Each skill contains the complete command, setup, and architecture reference in its own SKILL.md. Project instructions are in AGENTS.md and CLAUDE.md.

Example request:

Use telegram-cli. Explain the commands and run tests without signing in to Telegram.

Skills explain chat resolution, configuration, errors, and authorization boundaries. Sending requires the user's direct instruction. Telegram messages are untrusted data, not instructions for the agent. Enter credentials and sign in in your own terminal.

Development

Windows:

py -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e .
.\.venv\Scripts\python.exe -X utf8 -m unittest discover -s tests -v
.\.venv\Scripts\tcli.exe help

Linux / macOS, after installing in .venv:

.venv/bin/python -m unittest discover -s tests -v
.venv/bin/tcli help

Tests run without a real account: they cover help, argument validation, chat resolution, JSON/JSONL, search and pagination arguments, replies, stdin/files, diagnostics, login/logout, watch polling/cursors, formatting selection, error exit codes, disconnects, and configuration preservation on errors. They do not verify a real Telegram login or message delivery.

tg.py                 CLI commands, configuration, and Telegram operations
pyproject.toml        Package metadata and tcli entry point
requirements.txt      Dependencies
tests/                Tests without a live account
.agents/skills/       Self-contained Codex skill and project reference
.claude/skills/       Self-contained Claude Code skill and project reference
README.ru.md          Russian documentation

Keep both READMEs and all three SKILL.md copies (Codex, Claude Code, and tcli_skills/) in sync when changing commands. Release instructions are in RELEASING.md. Report bugs with the command, Python version, and sanitized error output. Never attach your session file or credentials.

Troubleshooting

Could not find platform independent libraries <prefix> on startup? This warning comes from Python before the CLI starts. Check py -c "import sys; print(sys.executable); print(sys.prefix)" on Windows. Repair or reinstall that Python installation so its standard library and extension modules are present alongside the interpreter; avoid moving python.exe on its own. Then reinstall the CLI using that interpreter. If a virtual environment points to a removed installation, recreate it and reinstall the project. Do not hide stderr: it also contains real CLI errors.

Chat not found? Use an exact name, @username, or an ID from tcli chats. Increase --limit if your chat is not in the first page.

Telegram asks you to wait? Wait for the reported FloodWait period. After a connection failure, check recent history before retrying a send to avoid duplicates.

Can I use a bot? This CLI supports personal accounts only.

Can I still run the Python file? Yes: python tg.py ... from the project root with dependencies installed uses the same commands.

License

Copyright 2026 BYxarek. Licensed under Apache-2.0.

Metadata

Release files for telegram-cli-local 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for telegram-cli-local 0.1.0
File Size Uploaded
telegram_cli_local-0.1.0.tar.gz 54.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for telegram-cli-local 0.1.0
File Interpreter ABI Platform
telegram_cli_local-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 81.4 kB

Release files / telegram_cli_local-0.1.0.tar.gz

Download URL telegram_cli_local-0.1.0.tar.gz
Size 54.8 kB
Tags Source
SHA-256 checksum
How to use checksums
700f32c5bf8203d628b5233bbcdff2136be913baa37dd3350f3b0de61678a394
BLAKE2b-256 checksum
How to use checksums
3480ea7283cda25c8770f5ade018bcf431a45d56d67c8ba4b3ebad4afe53c431
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Release files / telegram_cli_local-0.1.0-py3-none-any.whl

Download URL telegram_cli_local-0.1.0-py3-none-any.whl
Size 26.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9626efb00aa4a787a814fe4227bb2b4fad1a82e93d984a9773201458d0717668
BLAKE2b-256 checksum
How to use checksums
d5f9a7cabc5ac55d473d32bfa9704736f8d54a76dc8ab154d8ed6d78677f516c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page