telegram-cli
Python CLI wrapper for Telegram interaction using Telethon (MTProto protocol). Use when the user wants to: (1) send messages, (2) read messages from chats/channels/groups, (3) list chats, (4) download
SKILL.mdsrc-tauri/bundled_skills/telegram-cli/SKILL.md
GitHubTelegram CLI Skill
Enables the agent to interact with Telegram on behalf of the user via Telethon (MTProto protocol).
Path Conventions & Aliased Locations
LibrAgent organizes skill resources using canonical @ aliases across all platforms (Windows, Linux, macOS):
- Skill files & documentation: Use
@system-skills/telegram-cli/SKILL.mdor@system-skills/telegram-cli/references/cli-reference.mdwith workspace tools (workspace__readFile,workspace__listDirectory, etc.). - Shell execution (
workspace__runInPersistentShell): When invoking python scripts, reference<skill-base-dir>/scripts/...using the skill's Base Directory (either the canonical alias@system-skills/telegram-clior the concrete Base Directory injected in your system prompt reference block). - On Linux/macOS, use
python3ifpythonis unavailable. - Always quote paths to handle spaces properly:
"<skill-base-dir>/scripts/check_config.py".
⚠️ Security Rules (Mandatory)
- NEVER ask for 2FA passwords, verification codes, or other transient secrets in chat.
- NEVER display or repeat the contents of
~/.libragent/telegram_config.json. - NEVER pass
--password-valueor--code-valueas command-line arguments. Command-line arguments leak into system process tables (ps aux,Get-Process), shell histories, and execution logs. - Collect transient secrets (verification codes, 2FA passwords) exclusively through
requireUserInput=truewith--code-stdin/--password-stdinviaworkspace__runInPersistentShell. - If the user accidentally sends a password or code in chat:
- Acknowledge receipt without echoing or repeating the secret text.
- Use
--password-envwith an environment variable or run the setup tool with stdin. - NEVER echo the secret in output.
- ALWAYS use
setup.pyto persist credentials and session.
Overview
Telegram integration involves these steps:
- Detect environment & config — verify Python and run
check_config.pyto check if account is configured - Setup (first time only) — gather API ID/Hash, phone number, then run
setup.pywith hidden prompts for code/password - Dispatch action — classify the user's request and call
telegram_cli.pywith the right action - Present results — format and summarize the output for the user
Dependencies & Environment Setup
1. Python Environment Check
Before running any script, ensure Python 3.9+ is available in the shell:
- Check version:
python --version || python3 --version - If Python is not installed:
- Windows:
(Or via Miniconda:winget install Python.Python.3.12 --silent --accept-package-agreements --accept-source-agreementswinget install Anaconda.Miniconda3 --silent --accept-package-agreements --accept-source-agreements) - macOS:
brew install python - Linux:
sudo apt update && sudo apt install -y python3 python3-pip - You may also recommend the setup-wizard skill to guide automated environment diagnostics.
- Windows:
2. Telethon Installation
Telethon MTProto client library is required:
# Windows
python -m pip install telethon
# Linux / macOS
python3 -m pip install telethon
References
These reference files are located in the skill directory:
- cli-reference.md (or
@system-skills/telegram-cli/references/cli-reference.md) — CLI commands, options, outputs, and errors reference
Step 1: Detect Config
Always start by checking if the account is configured:
python "<skill-base-dir>/scripts/check_config.py"
(On Linux/macOS, use python3 if python is not aliased)
- Exit code
0with"status": "ok"→ configured and authorized, proceed to Step 3 - Exit code
1→ missing config/session or not authorized (missing,missing_session,unauthorized,auth_restart_needed), go to Step 2 - Exit code
2→ config exists but is incomplete/corrupt, go to Step 2 to reconfigure/overwrite it "status": "auth_restart_needed"→ delete~/.libragent/telegram_session.sessionand restart from Step A (send_code)
Step 2: Account Setup (First Time or Reset)
Do not run python "<skill-base-dir>/scripts/setup.py" bare without arguments inside LibrAgent.
2.1: Guide API ID/Hash Acquisition
If the user doesn't have API credentials, guide them to:
- Visit https://my.telegram.org
- Log in with their phone number
- Click "API development tools"
- Fill in App title and Short name (can be anything)
- Copy the
api_idandapi_hash
2.2: Two-Step Authentication Flow
1. Collect API credentials in chat
Ask the user for:
api_id(integer)api_hash(string)phone(international format, e.g.,+821012345678)
2. Interactive setup commands
Step A — Send verification code:
# Windows (PowerShell)
python "<skill-base-dir>/scripts/setup.py" --api-id 12345678 --api-hash "abcdef0123456789..." --phone "+821012345678" --action send_code
# Linux / macOS (Bash)
python3 "<skill-base-dir>/scripts/setup.py" --api-id 12345678 --api-hash "abcdef0123456789..." --phone "+821012345678" --action send_code
This outputs a JSON confirmation that the code was sent. On AuthRestartError, the script clears the partial session and retries once. If it still fails, you get "status": "auth_restart_needed" — run send_code again.
Step B — Sign in with verification code:
Execute workspace__runInPersistentShell tool call with:
command:python "<skill-base-dir>/scripts/setup.py" --action sign_in --code-stdinrequireUserInput:trueinputType:"text"inputPrompt:"텔레그램 인증 코드를 입력하세요:"
{
"command": "python \"<skill-base-dir>/scripts/setup.py\" --action sign_in --code-stdin",
"requireUserInput": true,
"inputType": "text",
"inputPrompt": "텔레그램 인증 코드를 입력하세요:"
}
LibrAgent auto-detects --code-stdin and pipes the UI input into Python stdin (stdinDelivery=child).
[!NOTE] Do not use
Read-Hostinside LibrAgent persistent PowerShell. Those sessions run-NonInteractive, soRead-HostraisesPSInvalidOperationException. The--code-stdin/--password-stdinpath is the supported contract across Windows, macOS, and Linux.
Step C — Handle 2FA (if Step B returns "password_needed"):
Execute workspace__runInPersistentShell tool call with:
command:python "<skill-base-dir>/scripts/setup.py" --action sign_in --password-stdinrequireUserInput:trueinputType:"password"inputPrompt:"텔레그램 2FA 비밀번호를 입력하세요:"
{
"command": "python \"<skill-base-dir>/scripts/setup.py\" --action sign_in --password-stdin",
"requireUserInput": true,
"inputType": "password",
"inputPrompt": "텔레그램 2FA 비밀번호를 입력하세요:"
}
After successful setup, re-run check_config.py to confirm "status": "ok", then proceed to Step 3.
Step 3: Dispatch Action
Classify the user's request into one of six actions and call telegram_cli.py.
📌 Saved Messages (나와의 채팅 / 내게 쓰기)
Telegram provides personal cloud storage via "Saved Messages". To send or retrieve messages from your Saved Messages:
- Use
--chat me(or@me,saved,@saved,saved messages,saved_messages,저장한 메시지,나와의 채팅,내게 쓰기). - The CLI automatically resolves
medirectly to your own Telegram account. - Example — Send to Saved Messages:
python "<skill-base-dir>/scripts/telegram_cli.py" --action send_message --chat me --message "메모 내용" - Example — Read from Saved Messages:
python "<skill-base-dir>/scripts/telegram_cli.py" --action get_messages --chat me --limit 20
🔢 Numeric Chat / User IDs & Username Resolution
- Numeric User ID (e.g.,
5097924805): Pass directly as--chat 5097924805. The CLI automatically detects numeric strings and resolves them as integer entity IDs. - Numeric Channel / Supergroup ID (e.g.,
-1001234567890): Pass directly as--chat -1001234567890. - Username: Use
@channel_nameorchannel_name. - Unknown Chat Name: If the user only provides a human-readable title (e.g. "가족방" or "팀 채널"), run
list_chatsfirst to find the exact numeric ID or username.
Output handling (recommended for message/search actions)
On Windows, large JSON payloads can break in PowerShell (cp949). Prefer saving results to a UTF-8 file:
python "<skill-base-dir>/scripts/telegram_cli.py" --action get_messages `
--chat "<chat_id_or_username>" `
--limit 50 `
--output "<workspace>/telegram_messages.json"
When --output is set, stdout prints a compact summary (status, output path, count). Read the file for full message bodies.
All CLI output uses UTF-8 (ensure_ascii=False). Errors go to stderr as UTF-8 JSON.
Output handling (Windows 필수)
On Windows, always set these before invoking any CLI command. Use UTF-8 without BOM — [System.Text.Encoding]::UTF8 prepends U+FEFF to native stdin and will corrupt --code-stdin / --password-stdin secrets:
$utf8 = New-Object System.Text.UTF8Encoding $false
[Console]::InputEncoding = [Console]::OutputEncoding = $OutputEncoding = $utf8
$env:PYTHONUTF8 = "1"
LibrAgent persistent shells already apply this encoding and PYTHONUTF8=1. setup.py also strips any leading UTF-8 BOM from stdin secrets as defense in depth.
Input encoding & PowerShell escaping (Windows / Unicode / Literal $ workaround)
On Windows, passing Unicode characters (like Korean) as command-line arguments can cause character corruption (mojibake) due to PowerShell's default encoding (cp949).
To bypass this bottleneck, it is highly recommended to write the message or query to a UTF-8 file and use --message-file or --query-file instead of --message or --query.
[!WARNING] PowerShell Here-String Interpolation Danger: If you use double-quoted Here-Strings (
@" ... "@) in PowerShell, characters starting with$are treated as variables. For example,$3,000will evaluate$3as an empty variable, resulting in,000, and$1.5Bwill evaluate$1as empty, resulting in.5B.How to avoid this:
- (Best/Recommended): Use the agent's
writeFile(orworkspace__writeFile) tool to directly create and write the message content to a file (e.g.,<workspace>/tg_message.txt) as UTF-8. This completely bypasses any PowerShell escaping or variable interpolation issues.- (Alternative - Single Quotes): If you must write the file via PowerShell, use single-quoted Here-Strings (
@' ... '@) which disable variable interpolation.
Send Message (Windows Recommended via writeFile)
- Use the
writeFile(orworkspace__writeFile) tool to save your message (e.g. including$3,000or Korean text) directly to<workspace>/tg_message.txtin UTF-8 format. - Call the CLI pointing to the file:
python "<skill-base-dir>/scripts/telegram_cli.py" --action send_message `
--chat "<chat_id_or_username>" `
--message-file "<workspace>/tg_message.txt"
- Clean up the temporary file afterwards:
Remove-Item -Path "<workspace>/tg_message.txt" -ErrorAction SilentlyContinue
Search Messages (Windows Recommended via writeFile)
- Use the
writeFile(orworkspace__writeFile) tool to save your query directly to<workspace>/tg_query.txtin UTF-8 format. - Call the CLI pointing to the file:
python "<skill-base-dir>/scripts/telegram_cli.py" --action search_messages `
--query-file "<workspace>/tg_query.txt" `
--output "<workspace>/telegram_search.json"
- Clean up the temporary file afterwards:
Remove-Item -Path "<workspace>/tg_query.txt" -ErrorAction SilentlyContinue
Dispatch CLI Actions
Classify the user's request into one of the actions (send_message, get_messages, list_chats, search_messages, download_file, get_chat_info) and execute the CLI. For a detailed reference of CLI parameters, JSON output schemas, and pagination strategies, see the cli-reference.md guide.
Step 4: Present Results
- Message list: Show as a numbered table —
# From Date Content - Send confirmation: Confirm action completed with brief summary
- Chat list: Show as a table —
# Name Type Members/ID Last Activity - Search results: Same as message list, with match count
- Errors: See Error Handling in cli-reference.md
Always provide the next concrete step, never just report the error.
Output Format Guidelines
For message listings, use this format:
📨 텔레그램 메시지 (chat: @example_channel)
# 날짜 내용
1 06/01 14:23 오늘 회의는 14시에 시작됩니다.
2 06/01 13:45 [이미지]
3 06/01 12:00 새로운 기능 배포 완료
더 보려면: "다음 20개 보여줘"
For send confirmation:
✅ 텔레그램 메시지 발송 완료
받는 곳: @example_channel
발송 시각: 2026-06-01 14:30
For chat listings:
💬 텔레그램 채팅 목록 (총 25개)
# 이름 유형 마지막 활동
1 ● LibrAgent Dev 채널 10분 전
2 GitHub Notifications 채널 1시간 전
3 ● 프로젝트 A 그룹(42) 3시간 전
4 김철수 개인 어제
● = 읽지 않음