tg
A tiny authenticated Telegram harness for agents and humans.
One Python process. One authenticated Telegram account per run. The full Telethon surface.
tg keeps the runtime deliberately small: configuration, named sessions,
authentication, locking, and Python process semantics. Telethon remains the Telegram
API.
Telethon is the API; tg only provides the authenticated execution boundary.
When a workflow is missing, write the missing logic as ordinary Python and run it
through tg.
agent wants something in Telegram
│
▼
tg
│
├── client.* friendly Telethon methods
└── functions.* raw Telegram API when needed
Three commands plus direct Python execution.
tg login
tg doctor
tg skill
tg script.py
The Python distribution is tg-harness. The installed command is tg.
Give it to your agent
Install from PyPI:
uv tool install tg-harness
Or install the current GitHub version:
uv tool install git+https://github.com/speech115/tg.git
Then give the agent this instruction:
Use tg for Telegram. Run tg doctor first. If the account is not authorized, ask
me to complete tg login. For Telegram work, use one tg program per decision
boundary, prefer Telethon client methods, and fall back to functions.* / types.*
for raw Telegram requests.
Requires Python 3.12+ and a POSIX system (macOS or Linux).
Configure once
Create Telegram API credentials at https://my.telegram.org/apps, then create
~/.config/tg/config.toml:
[telegram]
api_id = 123456
api_hash = "your-api-hash"
Alternatively, set TG_API_ID and TG_API_HASH in the environment.
Set TG_CONFIG when the config lives elsewhere.
Authorize the default account:
tg login
tg doctor
The default account is main. Named accounts map directly to Telethon session files:
tg --account work login
tg --account work doctor
tg --account work script.py
~/.local/state/tg/
├── main.session
├── work.session
└── another.session
Account names must match [A-Za-z0-9_-]+.
Run ordinary Python
For a one-off task:
tg <<'PY'
dialogs = await client.get_dialogs(limit=10)
for dialog in dialogs:
print(dialog.name)
PY
For reusable logic:
tg script.py arg1 --flag
tg --account work script.py arg1 --flag
Every run gets:
client # authenticated Telethon client
functions # raw Telegram request constructors
types # raw Telegram types
account # selected named account
It also gets normal __file__, sys.argv, and local-import behavior.
Prefer the friendly API when it fits:
messages = await client.get_messages("me", limit=20)
Drop to the raw API when it does not:
result = await client(functions.users.GetFullUserRequest(id=types.InputUserSelf()))
How it works
one tg process
│
authenticated Telethon client
│
┌───────────────────┴───────────────────┐
│ │
client.* helpers raw TL requests
│ functions.* / types.*
└───────────────────┬───────────────────┘
│
Telegram API
config ~/.config/tg/config.toml (or TG_CONFIG)
sessions ~/.local/state/tg/<account>.session
locking one process per named session
Workflow logic stays in ordinary Python scripts.
Agent skill
The repository ships skills/tg/SKILL.md.
Use tg skill to print the bundled instructions. Its main rule is simple: bundle
deterministic operations into one tg process and stop only at a real decision
boundary. That avoids reconnecting for every API call and keeps agent behavior
both faster and simpler.
Trust boundary
tg is intentionally not a sandbox.
Code passed to it has the permissions of the selected Telegram account and can read, send, edit, delete, download, join, leave, and perform raw Telegram API operations.
Treat these as secrets:
api_hash- Telethon
.sessionfiles - any exported authorization material
The runtime keeps sessions outside the repository and serializes access to each named session with a lock.
See CONTRIBUTING.md for development and integration instructions.
License
MIT. See LICENSE.
Release files for tg-harness 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tg_harness-0.1.2.tar.gz | 153.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tg_harness-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 163.0 kB
Release files / tg_harness-0.1.2.tar.gz
| Download URL | tg_harness-0.1.2.tar.gz |
|---|---|
| Size | 153.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
63d2bf1df975bdefde1fb16d3fa9db4bf065a9356b58d30c0ac48fb28051b35f
|
|
BLAKE2b-256 checksum How to use checksums |
0f830375964677cb8339650ad7145d10063877b24f2524ee3dc3930595d0900e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / tg_harness-0.1.2-py3-none-any.whl
| Download URL | tg_harness-0.1.2-py3-none-any.whl |
|---|---|
| Size | 9.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
29999ff78b6b19f0918f4cb5370b6618329fbefa52bafd4b9532d1634a979f64
|
|
BLAKE2b-256 checksum How to use checksums |
61ed2919cf78ad80e8e5fa5fa6e5828f3c794cc01336f8e6c94d32fdfa4ae427
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.7 {"installer":{"name":"uv","version":"0.12.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|