Skip to main content

Agent-friendly Telegram CLI built on Telethon -- read, write, archive your Telegram from the terminal.

Project description

tgctl

PyPI CI Python License: MIT

Agent-friendly Telegram CLI built on Telethon. Read, write, archive, and listen to your own Telegram account from the terminal with JSON output, idempotency, audit logging, multi-account stores, and explicit safety gates for autonomous-agent use.

tgctl is for developers and local agents that need a predictable Telegram surface without running a bot account or handing control to a GUI client. It uses your normal Telegram account through Telethon and stores a local SQLite cache for fast offline queries.

Names: the PyPI distribution is tgctl (in the kubectl/flyctl family — Telegram control). The binary on PATH is tg. The Python import is from tgcli import Client. The GitHub repo is tg-cli.

Quick start

pip install tgctl
echo "TG_API_ID=12345678" > .env
echo "TG_API_HASH=abcdef0123456789abcdef0123456789" >> .env
tg login
tg stats

Get TG_API_ID and TG_API_HASH from https://my.telegram.org/apps.

Features

  • 62 commands covering read, write, media, folder, topic, account, admin, and destructive operations
  • Multi-account mode with isolated session, database, and audit paths per account
  • JSON envelope output for clean agent integration
  • Local SQLite cache for fast reads and archival workflows
  • Write safety through --allow-write, --dry-run, idempotency keys, and append-only audit logs
  • Destructive safety through typed --confirm <id> checks
  • Read-only mode for trusted inspection with --read-only or TG_READONLY=1

Commands at a glance

Command Purpose
account-sessions List authenticated Telegram sessions
accounts-add Create a local account store
accounts-list List local account stores
accounts-remove Delete a local account store
accounts-show Show current account paths
accounts-use Switch the default local account
backfill Pull historical messages into SQLite
block-user Block a user or bot
chats-info Show cached chat metadata
contacts List synced contacts
delete-msg Delete one or more messages
discover Scan dialogs without fetching messages
doctor Diagnose env, session, DB, schema, and optional live API
edit-msg Edit one of your own text messages
folder-add-chat Add a chat to a Telegram folder
folder-create Create a Telegram folder
folder-delete Delete a Telegram folder
folder-edit Edit a Telegram folder
folder-remove-chat Remove a chat from a Telegram folder
folder-show Show one Telegram folder
folders-list List Telegram folders
folders-reorder Reorder Telegram folders
forward Forward one cached message
get-msg Get one cached message by id
leave-chat Leave a group, supergroup, or channel
list-msgs List cached messages from one chat
listen Capture new incoming messages forever
login Run one-time interactive auth
mark-read Mark all messages in a chat as read
me Print authenticated user info
pin-msg Pin a message
react Add a reaction to a message
search Search cached messages in one chat
send Send a text message
show Print messages from one chat
stats Show a database summary
sync-contacts Pull phone-book contacts from Telegram
terminate-session Terminate a Telegram session
topic-create Create a forum topic
topic-edit Edit a forum topic
topic-pin Pin a forum topic
topic-unpin Unpin a forum topic
topics-list List forum topics in a supergroup
unblock-user Unblock a user or bot
unpin-msg Unpin a message
unread List chats with unread messages

Why tg-cli?

Telegram tooling usually optimizes for one of four shapes: interactive TUIs, file-transfer utilities, bot APIs, or MCP servers. tg-cli is narrower and more scriptable: a local user-account CLI with stable exit codes, JSON output, SQLite-backed reads, an audit trail, and explicit write gates. It is designed for shell scripts and coding agents that need to inspect or operate on the user's own Telegram account while keeping every write intentional.

Python SDK

Use tg-cli inside your own Python apps without subprocess:

from tgcli import Client

c = Client()                                  # default account

# Read paths
me = c.me()
summary = c.stats(min_msgs=10)
history = c.messages.show(chat_id=12345, limit=50)

# Write paths reuse the CLI's safety gates
result = c.messages.send(
    chat=12345,
    text="hello",
    allow_write=True,                         # required, mirrors --allow-write
    idempotency_key="abc123",                 # optional replay protection
)

# Dry-run any write to preview without calling Telegram
preview = c.messages.send(
    chat=12345, text="hi", allow_write=True, dry_run=True
)
assert preview["dry_run"] is True

The SDK reuses the CLI's safety gates — calling a write method without allow_write=True raises tgcli.safety.WriteDisallowed. Destructive admin methods accept confirm=<resolved-id> matching the CLI --confirm flag.

Multi-account: v0.4.0 SDK is single-account-per-process. Set TG_ACCOUNT=<name> BEFORE importing tgcli, then construct Client(account="<name>"). Mismatched constructions raise RuntimeError. For concurrent multi-account work, run one process per account.

The SDK exposes a curated subset of runners (me, stats, messages.send, messages.show, admin.chat_title) for v1.0. All 62 commands remain available through the CLI surface; open an issue if you need a specific runner exposed in the SDK.

Configuration

Paths and credentials can be provided through environment variables or a local .env file.

Variable Purpose
TG_API_ID Telegram API id from my.telegram.org
TG_API_HASH Telegram API hash from my.telegram.org
TG_SESSION_PATH Telethon session file path
TG_DB_PATH SQLite cache path
TG_AUDIT_PATH Append-only audit log path
TG_MEDIA_DIR Media output directory
TG_ACCOUNT Active local account name
TG_READONLY Reject Telegram-side and local DB writes when set to 1
TG_ALLOW_WRITE Allow writes without passing --allow-write each time

Multi-account

tg accounts-add work
tg --account work login
tg accounts-use work
tg accounts-show

Each account stores its own session, database, and audit log under accounts/<NAME>/. The default account remains default.

Safety

Writes are blocked unless you pass --allow-write or set TG_ALLOW_WRITE=1. Destructive commands also require a typed --confirm <id> value matched against the resolved chat, user, message, folder, or session id. --dry-run reports what would happen without calling Telegram. --read-only and TG_READONLY=1 reject both Telegram-side writes and local DB writers.

Every invocation appends audit entries to audit.log. Write commands record pre-call and post-call entries with the same request_id; idempotency keys can replay a cached successful envelope instead of calling Telegram again.

Architecture

tgcli.__main__ builds the argparse surface and dispatches into command modules under tgcli/commands/. Commands share the same output envelope, resolver, safety, idempotency, and audit helpers. Telethon handles Telegram API access; SQLite stores chats, messages, contacts, folders, topics, and idempotency state.

tg command
  -> argparse
  -> command runner
  -> safety gates + resolver + audit
  -> Telethon and/or SQLite
  -> JSON envelope or human output

Contributing

See AGENTS.md for the project's working conventions and docs/superpowers/plans/ for the design history.

License

MIT - see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tgctl-1.0.0.tar.gz (56.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tgctl-1.0.0-py3-none-any.whl (66.0 kB view details)

Uploaded Python 3

File details

Details for the file tgctl-1.0.0.tar.gz.

File metadata

  • Download URL: tgctl-1.0.0.tar.gz
  • Upload date:
  • Size: 56.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tgctl-1.0.0.tar.gz
Algorithm Hash digest
SHA256 05c0381d704adc1b21466cfea14d6c412299e889c4cd534a2dcd92aae4b00e35
MD5 fc3d250372f2815b32c4e968649c33a6
BLAKE2b-256 4278355b6aa80dcb28f2d53be81105382a3bb5172842ec67062d6ff5dcf2c491

See more details on using hashes here.

Provenance

The following attestation bundles were made for tgctl-1.0.0.tar.gz:

Publisher: release.yml on b1rd33/tg-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tgctl-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: tgctl-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 66.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tgctl-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 92f3bc3a453c744de5ab3af57e06666f8f18e7d5f4e3b622b635534ea17a7378
MD5 d0b835aaa0e382686afbe387afaacc58
BLAKE2b-256 15d3dce9fb0de19bc80ddf69af1d0f921a90c4942afe7a533fb316c17ffa2288

See more details on using hashes here.

Provenance

The following attestation bundles were made for tgctl-1.0.0-py3-none-any.whl:

Publisher: release.yml on b1rd33/tg-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page