| name | tg-cli |
| description | Manage the user's personal Telegram account directly from the command line. Use when the user asks to: read Telegram messages or chats, list dialogs or unread messages, send a message or file as themselves on Telegram, schedule a message for a future time, reply to or edit a specific message, delete messages, add reactions, get reactions on a message, forward messages between chats, copy-forward without attribution, search messages inside a chat or across all chats, join or leave a group or channel, export full chat history, mark messages as read, search for public Telegram groups, get info about a chat or user, list group members or admins, list forum topics, get or create an invite link, invite a user into a group, find common chats with a user, get a user's profile photos, download media from a message, pin or unpin a message, mute or unmute a chat, scan a message ID range, get a specific message by ID, watch a dialog for new messages in real time, create a group, list channels/groups where the user is admin (my-channels), kick/ban/unban users, promote or demote admins, set group title or description or photo, list or add contacts. search members by name/username, export all members to CSV, find active members, transcribe voice messages, restrict users with partial bans, delete all messages from a user, create channels or supergroups, manage active sessions, block/unblock users, delete conversation history, archive/unarchive dialogs, generate message links, send albums, watch with keyword filter and edit events, send messages with HTML or Markdown formatting. This is for the user's personal account (MTProto, not a bot). Two-step agent-friendly auth: call auth-request, get the code from the user, then call auth-complete — no interactive TTY needed. QR auth also available via auth-qr.
|
| version | 1.7.0 |
| metadata | {"openclaw":{"emoji":"✈️","homepage":"https://github.com/strelov1/tg-cli","requires":{"bins":["tg-cli"],"config":["~/.tg-cli/config.json"]},"install":[{"kind":"shell","bins":["tg-cli"],"run":"OS=$(uname -s | tr '[:upper:]' '[:lower:]')\nARCH=$(uname -m)\ncase \"$ARCH\" in\n x86_64) ARCH=amd64 ;;\n arm64|aarch64) ARCH=arm64 ;;\nesac\nBASE=\"https://github.com/strelov1/tg-cli/releases/latest/download\"\nBIN=\"tg-cli-${OS}-${ARCH}\"\nTMP=$(mktemp)\ncurl -fsSL \"${BASE}/${BIN}\" -o \"$TMP\"\nEXPECTED=$(curl -fsSL \"${BASE}/checksums.txt\" | grep \"${BIN}\" | awk '{print $1}')\nif command -v sha256sum >/dev/null 2>&1; then\n ACTUAL=$(sha256sum \"$TMP\" | awk '{print $1}')\nelif command -v shasum >/dev/null 2>&1; then\n ACTUAL=$(shasum -a 256 \"$TMP\" | awk '{print $1}')\nelse\n echo \"Warning: no sha256 tool found, skipping checksum\" >&2\n ACTUAL=\"$EXPECTED\"\nfi\nif [ \"$EXPECTED\" != \"$ACTUAL\" ]; then\n echo \"Checksum verification failed\" >&2; rm -f \"$TMP\"; exit 1\nfi\ninstall -m 755 \"$TMP\" /usr/local/bin/tg-cli\nrm -f \"$TMP\"\n"}]}} |
tg-cli — Agentic Telegram CLI
Standalone CLI for managing a personal Telegram account via MTProto. No subprocesses, no browser, no interactive prompts. Every command returns JSON on stdout; progress and errors go to stderr.
Security Notes
- Verification codes and 2FA passwords are required only during initial authorization (
auth-request / auth-complete). These are standard Telegram credentials — never share them outside of this auth flow.
- The install script verifies SHA-256 checksums against the official release manifest before installing the binary.
- Source code and release artifacts are open and auditable at github.com/strelov1/tg-cli.
- You can build from source instead of using the pre-built binary:
go install github.com/strelov1/tg-cli@latest
Setup (First Run)
Step 1: Check if configured
tg-cli config list
If app-id and api-hash are missing — help the user get them from my.telegram.org/apps:
tg-cli config set app-id <id>
tg-cli config set api-hash <hash>
Step 2: Check accounts
tg-cli accounts
If no authorized accounts — start auth (see Authorization below).
Authorization
Two-step (phone + code)
Step 1 — Request code
tg-cli auth-request +12025551234
Returns {"status":"code_sent","phone":"+12025551234"}. A verification code is sent to the user's Telegram app (or SMS).
Tell the user: "Check your Telegram — I've sent a code. Please share it with me."
Step 2 — Complete auth
tg-cli auth-complete +12025551234 --code 12345
tg-cli auth-complete +12025551234 --code 12345 --password MySecret2FA
Returns {"status":"authorized","phone":"...","username":"..."}.
If the user has 2FA enabled and you didn't pass --password, re-run with it.
QR code (scan from existing device)
tg-cli auth-qr
Displays a QR code in the terminal. The user opens Telegram on their phone: Settings → Devices → Link Desktop Device, then scans the QR. Once scanned, the session is saved automatically.
Commands
Account info
tg-cli me
tg-cli status
tg-cli accounts
tg-cli accounts use +12025551234
List dialogs
tg-cli dialogs
tg-cli dialogs --unread
tg-cli dialogs --limit 50
Output:
[
{ "id": 123, "name": "Alice", "username": "alice", "type": "user", "unread_count": 3 },
{ "id": 456, "name": "Dev Team", "type": "supergroup", "unread_count": 0 }
]
Types: user, group, supergroup, channel.
Read messages
tg-cli read alice
tg-cli read team-chat
tg-cli read @username
tg-cli read +12025551234
tg-cli read team-chat --offset 1000
tg-cli read team-chat --since 1h
tg-cli read team-chat --since 30m
tg-cli read team-chat --since 7d
tg-cli read team-chat --format text
Output:
{
"messages": [
{
"id": 1,
"who": "Alice",
"when": "2024-01-01T10:00:00Z",
"text": "Hello",
"views": 100,
"forwards": 2,
"reply_to": 0,
"reactions": [{ "emoji": "👍", "count": 5 }]
}
],
"offset": 1
}
Use offset value from response as --offset to load older messages.
Get a specific message by ID
tg-cli get-message team-chat 12345
tg-cli get-message @channel 99
Scan a range of message IDs
Fetches all messages (including media-only) in the given ID range. Useful for gap analysis in channels.
tg-cli scan team-chat 100 200
Send message
tg-cli send @alice "Hello!"
tg-cli send team-chat "Build is done ✅"
tg-cli send +12025551234 "Hey there"
tg-cli send team-chat "Meeting in 5 min!" --at "2026-03-15 09:55"
Reply to a message
tg-cli reply team-chat 12345 "Got it, thanks!"
tg-cli reply @alice 99 "Sure, see you then"
Edit a message
tg-cli edit team-chat 12345 "Updated text here"
Only works on your own messages.
Delete messages
tg-cli delete team-chat 12345
tg-cli delete team-chat 100 101 102
React to a message
tg-cli react team-chat 12345 👍
tg-cli react @alice 99 ❤️
Get reactions on a message
tg-cli reactions team-chat 12345
Output:
{
"reactions": [
{ "emoji": "👍", "count": 10 },
{ "emoji": "❤️", "count": 3 }
]
}
Forward a message
tg-cli forward team-chat 12345 @alice
tg-cli forward inbox 99 project-chat
Copy-forward without attribution
Sends the message content without the "Forwarded from" header.
tg-cli forward-copy team-chat 12345 @alice
Send a file
tg-cli send-file @alice /path/to/report.pdf
tg-cli send-file team-chat ./screenshot.png
Download media from a message
tg-cli download-media team-chat 12345
tg-cli download-media team-chat 12345 --out /tmp/file.jpg
Mark as read
tg-cli mark-read team-chat
Pin / unpin a message
tg-cli pin team-chat 12345
tg-cli unpin team-chat 12345
Mute / unmute notifications
tg-cli mute team-chat 1h
tg-cli mute team-chat 7d
tg-cli mute team-chat forever
tg-cli unmute team-chat
Duration formats: 30m, 1h, 7d, forever.
Search messages in a dialog
tg-cli search team-chat "deploy" --limit 20
Output:
{"results": [...], "total": 5, "query": "deploy", "dialog": "team-chat"}
Search messages across all chats
tg-cli search-all "deployment failed" --limit 20
Output:
{"results": [...], "total": 3, "query": "deployment failed"}
Get info about a user, group, or channel
tg-cli info @alice
tg-cli info team-chat
tg-cli info @golang_digest
List group members
tg-cli members team-chat
tg-cli members @golang_digest --limit 50
List group admins
tg-cli admins team-chat
Output:
{ "admins": [{ "id": 1, "username": "alice", "first_name": "Alice", "role": "creator" }] }
List forum topics
tg-cli topics team-chat
Get invite link
tg-cli invite-link team-chat
Output:
{ "link": "https://t.me/+AbCdEfGhIjK" }
Invite a user into a group
tg-cli invite team-chat @alice
tg-cli invite team-chat +12025551234
Works for both regular groups and supergroups.
Common chats with a user
tg-cli common-chats @alice
User's profile photos
tg-cli user-photos @alice
tg-cli user-photos @alice --limit 5
Watch for new messages
tg-cli watch team-chat
tg-cli watch @alice --interval 10
Prints each new message as a JSON object to stdout as it arrives. Runs until Ctrl+C or --timeout.
Search public groups/channels
tg-cli search-groups "golang" --limit 10
Join a group or channel
tg-cli join @golang_digest
tg-cli join https://t.me/+AbCdEfGhIjK
Leave a group or channel
tg-cli leave golang_digest
tg-cli leave team-chat
My channels / managed groups
List channels and supergroups where the current user is admin or creator:
tg-cli my-channels
tg-cli my-channels --owned
Output: {"channels": [{"id": 123, "title": "...", "type": "supergroup", "members": 500, "is_owner": true, "admin_rights": {...}}], "total": 1}
Kick / ban / unban
tg-cli kick team-chat @alice
tg-cli ban team-chat @alice
tg-cli ban team-chat @alice --until "2026-04-01 00:00"
tg-cli unban team-chat @alice
Promote / demote admins
tg-cli promote team-chat @alice
tg-cli promote team-chat @alice --perms post,edit,delete,pin --rank "Editor"
tg-cli demote team-chat @alice
Available --perms values: post, edit, delete, ban, invite, pin, add_admins, manage, anonymous, change_info, topics, all.
Edit group/channel properties
tg-cli set-title team-chat "Dev Team 2.0"
tg-cli set-description team-chat "All things development"
tg-cli set-photo team-chat ./logo.png
Contacts
tg-cli contacts
tg-cli contacts add +12025551234 John
tg-cli contacts add +12025551234 John Doe
Export full chat history
tg-cli export team-chat > history.json
tg-cli export team-chat --limit 500 > recent.json
Progress is printed to stderr. Output:
{
"account": "+12025551234",
"dialog": "team-chat",
"total_messages": 1234,
"incomplete": false,
"messages": [
{ "id": 1, "who": "Alice", "when": "...", "text": "...", "views": 100, "forwards": 2 }
]
}
"incomplete": true means the export was interrupted (FLOOD_WAIT or timeout) — partial data is returned.
Multiple Accounts
tg-cli --account +19005551234 dialogs
tg-cli --account +79001234567 send @alice "Hello from my Russian number"
Set a default account:
tg-cli accounts use +12025551234
Timeout
tg-cli --timeout 30 dialogs
Config
- Config file:
~/.tg-cli/config.json
- Sessions:
~/.tg-cli/sessions/<phone>/session.json
tg-cli config list
tg-cli config set app-id 12345
tg-cli config set api-hash abc123...
tg-cli config set default-account +12025551234
Quick Reference
| Action | Command |
|---|
| Search members | tg-cli search-members <group> <query> |
| Export members CSV | tg-cli parse-members <group> [--limit <n>] [--out file.csv] |
| Active members | tg-cli active-members <group> [--days <n>] |
| Channel stats | tg-cli stats <name> |
| Transcribe voice | tg-cli transcribe <name> <id> |
| Restrict user | tg-cli restrict <group> <user> [--no-send] [--no-media] |
| Delete user messages | tg-cli delete-user-messages <chat> <user> |
| Create channel | tg-cli create-channel <title> [--supergroup] [--username @x] |
| List sessions | tg-cli sessions |
| Revoke session | tg-cli sessions revoke <hash> |
| Block user | tg-cli block <user> |
| Unblock user | tg-cli unblock <user> |
| List blocked | tg-cli blocked |
| Delete history | tg-cli delete-history <name> [--revoke] |
| Archive dialog | tg-cli archive <name> |
| Unarchive dialog | tg-cli unarchive <name> |
| Message link | tg-cli message-link <name> <id> |
| Send album | tg-cli send-album <name> <file1> [<file2>...] [--caption "..."] [--spoiler] [--at "YYYY-MM-DD HH:MM"] |
| List scheduled | tg-cli list-scheduled <name> |
| Paid invite (Stars) | tg-cli paid-invite-link <name> --stars <amount> [--title "..."] |
| Comment on post | tg-cli comment <channel> <message-id> <text...> |
| Link discussion | tg-cli set-discussion <channel> <group> |
| Preview chat folder | tg-cli chatlist-preview <addlist-url-or-slug> |
| Join chat folder | tg-cli chatlist-join <addlist-url-or-slug> [--peers @ch1,...] [--dry-run] |
| Dump a channel | tg-cli download-channel <chat> [--out <dir>] [--limit N] [--skip-media] [--resume] |
| Dump folder network | tg-cli download-network <addlist-url-or-slug> [--out <dir>] [--peers @ch1,...] [--auto-join] [--resume] |
| Send with HTML/MD | tg-cli send <name> <text> --parse-mode html|markdown |
| Watch with filter | tg-cli watch <name> [--keyword <w>] [--event new,edit] |
| Read media only | tg-cli read <name> --media-only |
| Read in text format | tg-cli read <name> --format text |
| Filter dialogs | tg-cli dialogs [--type user|channel|group] [--archived] |
Common Errors
| Error | Meaning | Fix |
|---|
app-id and api-hash are required | Not configured | tg-cli config set app-id ... |
auth code expired | 5-min TTL on code | Re-run auth-request |
2FA required | User has 2FA | Re-run auth-complete with --password |
cannot find "..." | Unknown dialog name | Try @username format or full name |
session invalid or expired | Session gone | Re-authorize with auth-request / auth-complete |