https://github.com/pageton/gotg-cli
Telegram MTProto debug and invoke CLI — call any TL method, trace API calls, and expose Telegram as an MCP server for LLM-driven interaction
https://github.com/pageton/gotg-cli
cli debug gotd llm mcp mtproto telegram tl-schema
Last synced: 23 days ago
JSON representation
Telegram MTProto debug and invoke CLI — call any TL method, trace API calls, and expose Telegram as an MCP server for LLM-driven interaction
- Host: GitHub
- URL: https://github.com/pageton/gotg-cli
- Owner: pageton
- Created: 2026-05-01T20:02:34.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-02T02:57:23.000Z (about 2 months ago)
- Last Synced: 2026-05-02T03:28:05.783Z (about 2 months ago)
- Topics: cli, debug, gotd, llm, mcp, mtproto, telegram, tl-schema
- Language: Go
- Size: 92.8 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# tgdev
**Telegram MTProto debug and invoke CLI**
Call any TL method, trace API calls with correlation IDs, and expose Telegram as an MCP server for LLM-driven interaction.
[Install](#install) • [Quick start](#quick-start) • [Commands](#commands) • [MCP Setup](#mcp-setup) • [Session Management](#session-management) • [Configuration](#configuration)
[](https://go.dev)
[](https://modelcontextprotocol.io)
[](https://github.com/gotd/td)
---
## Features
- **Invoke any TL method** — call the full Telegram API from the terminal with JSON parameters
- **Persistent listener** — long-running client with IPC server for fast repeated invocations
- **Lifecycle tracing** — correlation IDs link updates to API calls to responses
- **MCP server** — expose Telegram as tools for Claude, GPT, or any MCP-compatible LLM
- **Multiple auth methods** — bot token, phone login, session string, or SQLite database
- **Auto-completion** — shell completions for bash, zsh, and fish with full method discovery
## Install
```bash
go install github.com/pageton/gotg-cli/cmd/tgdev@latest
```
Or build from source:
```bash
go build -o tgdev ./cmd/tgdev/
```
With version info:
```bash
go build -ldflags "-X main.version=$(git describe --tags --always) \
-X main.commit=$(git rev-parse --short HEAD) \
-X main.buildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-o tgdev ./cmd/tgdev/
```
Requires Go 1.25+.
## Quick start
```bash
# Terminal 1 — start a persistent listener
tgdev listen --db ~/tgdev.db --api-id 12345 --api-hash YOUR_HASH --bot-token YOUR_TOKEN
# Terminal 2 — invoke through the listener (fast, reuses connection)
tgdev invoke messages.sendMessage '{"Message":"hello","Peer":{"_":"inputPeerUser","UserID":123,"AccessHash":"..."}}'
```
> [!TIP]
> When `tgdev listen` is running, all `invoke` calls go through a Unix domain socket — no reconnection overhead. Without a listener, `invoke` creates a standalone connection (slower, requires auth flags).
### Get your API credentials
1. Log in at [my.telegram.org](https://my.telegram.org)
2. Go to **API Development Tools**
3. Create an application to get your `api_id` and `api_hash`
### Get current account info
```bash
tgdev getme --api-id 12345 --api-hash YOUR_HASH --bot-token YOUR_TOKEN
```
Or through a running listener:
```bash
tgdev getme
```
## Commands
| Command | Description |
| ----------------------------- | --------------------------------------------------------- |
| `tgdev invoke [json]` | Invoke a TL method via listener or standalone connection |
| `tgdev listen` | Start persistent client with update stream and IPC server |
| `tgdev trace` | Full lifecycle tracing with correlation IDs |
| `tgdev methods [prefix]` | List available TL methods |
| `tgdev getme` | Get current user/bot info (`users.getFullUser`) |
| `tgdev export-session` | Export session string from SQLite database |
| `tgdev mcp` | Start MCP server (stdio or HTTP) |
| `tgdev completion ` | Generate shell completions (bash, zsh, fish) |
| `tgdev version` | Print version |
| `tgdev help` | Show usage |
### Invoke
```bash
# Through a running listener
tgdev invoke users.getFullUser '{"ID":{"_":"inputUserSelf"}}'
# Standalone (no listener needed)
tgdev invoke users.getFullUser '{"ID":{"_":"inputUserSelf"}}' --api-id 12345 --api-hash HASH --bot-token TOKEN
# JSON output
tgdev invoke --format json users.getFullUser '{"ID":{"_":"inputUserSelf"}}'
```
### Listen
Starts a persistent Telegram client that logs incoming updates and accepts invoke commands over IPC.
```bash
tgdev listen --db ~/tgdev.db --api-id 12345 --api-hash HASH --bot-token TOKEN
```
### Trace
Like `listen`, but adds correlation IDs that link updates, handler invocations, API calls, and responses together.
```bash
tgdev trace --db ~/tgdev.db --api-id 12345 --api-hash HASH --bot-token TOKEN
```
Output example:
```
[1] >> messages.sendMessage
[1] {Message:"hello", Peer:{...}}
[1] << messages.sendMessage [12ms]
[1] {ID:42, Date:1709123456}
[2] UPDATE updateNewMessage
```
### Methods
```bash
# List all methods
tgdev methods
# Filter by prefix
tgdev methods messages.
# JSON output
tgdev methods --format json messages.send
```
## MCP Setup
tgdev exposes Telegram as an MCP server, letting LLMs call any TL method as a tool.
### Quick Setup
**stdio mode** (Claude Code, Cursor, local MCP clients):
```bash
tgdev mcp --api-id 12345 --api-hash YOUR_HASH --bot-token YOUR_TOKEN
```
**HTTP mode** (remote/multi-client):
```bash
tgdev mcp --http :8080 --api-id 12345 --api-hash YOUR_HASH --bot-token YOUR_TOKEN
```
**With persistent listener** (fastest, reuses connection):
```bash
# Terminal 1: start listener
tgdev listen --db ~/tgdev.db --api-id 12345 --api-hash YOUR_HASH --bot-token YOUR_TOKEN
# Terminal 2: start MCP server
tgdev mcp
```
> [!TIP]
> When `tgdev listen` or `tgdev trace` is running, MCP tools route through the listener's IPC socket.
> Otherwise, the MCP server creates its own standalone connection.
### Full Setup Guide
For detailed setup instructions, configuration examples, and troubleshooting:
- **[Complete MCP Setup Guide](docs/setup-mcp.md)** — stdio/HTTP modes, auth methods, client configs, security
### MCP Client Configuration
**Claude Code (`.claude/mcp.json`):**
```json
{
"mcpServers": {
"tgdev": {
"command": "tgdev",
"args": ["mcp"],
"env": {
"TGDEV_API_ID": "12345",
"TGDEV_API_HASH": "YOUR_HASH",
"TGDEV_BOT_TOKEN": "YOUR_TOKEN"
}
}
}
}
```
**Cursor (`~/.cursor/mcp.json`):**
```json
{
"mcpServers": {
"tgdev": {
"command": "tgdev",
"args": ["mcp"]
}
}
}
```
> [!IMPORTANT]
> Prefer environment variables (`TGDEV_*`) over CLI flags for secrets.
> CLI args are visible in `ps aux` output.
### Available MCP Tools
| Tool | Description |
| ----------------------- | ----------------------------------------------------------- |
| `tgdev_list_methods` | List TL methods with prefix filtering and cursor pagination |
| `tgdev_describe_method` | Show fields, types, and constructor hints for a method |
| `tgdev_invoke` | Invoke any TL method with JSON params |
| `tgdev_get_me` | Get current account info |
| `tgdev_listener_status` | Check if a listener is reachable on the IPC socket |
| `tgdev_config_info` | Show non-secret MCP configuration |
### JSON Parameter Format
Interface fields (like `InputPeer`, `InputUser`) use a `"_"` constructor key:
```json
{
"Peer": {"_": "inputPeerUser", "UserID": 123, "AccessHash": "..."},
"Message": "Hello!"
}
```
To discover constructor names: use `tgdev_describe_method` tool.
## Session Management
tgdev supports multiple session formats. Use [telegram-tools](https://github.com/pageton/telegram-tools) (client-side web app) to:
- **Generate** session strings via Telegram auth (phone or bot token) in gotg, GramJS, Kurigram, mtcute, or Telethon formats
- **Convert** between formats — paste a session string, auto-detect its format, convert to any other
- **Analyze** session strings — decode and inspect DC, auth key, user ID, isBot flag
- **Test DC connectivity** — ping all Telegram production and test data centers
> [!NOTE]
> Session strings grant full account access — treat them like passwords.
> Prefer environment variables (`TGDEV_SESSION`) or config file over CLI flags to avoid exposing in `ps aux`.
### Quick session setup
1. Visit [telegram-tools](https://pageton.github.io/telegram-tools/) (client-side, no backend)
2. Authenticate with phone number or bot token
3. Export session in **gotg** format
4. Use with tgdev:
```bash
# Via CLI flag (visible in ps aux)
tgdev listen --session "YOUR_SESSION_STRING" --api-id 12345 --api-hash HASH
# Via environment variable (recommended)
export TGDEV_SESSION="YOUR_SESSION_STRING"
tgdev listen --api-id 12345 --api-hash HASH
# Via config file (safest)
echo '{"session": "YOUR_SESSION_STRING", "api_id": 12345, "api_hash": "HASH"}' > ~/.tgdev.json
chmod 0600 ~/.tgdev.json
tgdev listen
```
### Session formats supported by tgdev
| Format | Source | Detection Method |
|--------|--------|-------------------|
| gotg native | `session.StringSession()` | JSON, standard base64 |
| Pyrogram | `session.PyrogramSession()` | URL-safe base64, 271 bytes decoded |
| Telethon | `session.TelethonSession()` | Prefix `1` + URL-safe base64, 263/275 bytes |
| GramJS | `session.GramjsSession()` | Prefix `1` + standard base64 |
| mtcute | `session.MtcuteSession()` | URL-safe base64, prefix byte 0x03 |
`tgdev` auto-detects session format via `detectSessionFormat()` in `cmd/tgdev/main.go`.
### Export session from SQLite
If you already have a SQLite database from `tgdev listen --db ~/tgdev.db`:
```bash
tgdev export-session --db ~/tgdev.db
```
The output is a gotg-compatible session string. Use `--session-type` to specify format if auto-detection fails.
### Session string safety
- Never commit session strings to version control
- Use `chmod 0600 ~/.tgdev.json` for config file
- IPC socket is mode 0600 (owner-only access)
- `--debug` logs full API payloads to stderr — contains session tokens
Config file: `~/.tgdev.json` (auto-restricted to `0600` permissions).
```json
{
"api_id": 12345,
"api_hash": "your_api_hash",
"bot_token": "123:ABC",
"database_path": "~/tgdev.db"
}
```
### Auth methods
| Method | Flag | Notes |
| --------------- | ------------- | --------------------------------- |
| Bot token | `--bot-token` | Fastest for bots |
| Phone number | `--phone` | Interactive user login |
| Session string | `--session` | Telethon/Pyrogram/gotg format |
| SQLite database | `--db` | Persistent sessions (recommended) |
### Credential priority
CLI flags > environment variables > config file.
### Environment variables
| Variable | Maps to |
| ----------------- | ------------- |
| `TGDEV_API_ID` | `--api-id` |
| `TGDEV_API_HASH` | `--api-hash` |
| `TGDEV_BOT_TOKEN` | `--bot-token` |
| `TGDEV_SESSION` | `--session` |
| `TGDEV_PHONE` | `--phone` |
### Global flags
```
--api-id INT Telegram API ID
--api-hash STRING Telegram API Hash
--session STRING Session string
--bot-token STRING Bot token
--phone STRING Phone number
--db PATH SQLite database path for persistent sessions
--db-name STRING Session name within the database (default: "default")
--socket PATH Unix socket path for IPC (default: $XDG_RUNTIME_DIR/tgdev.sock)
--config PATH Config file path (default: ~/.tgdev.json)
--no-color Disable colored output
--debug Enable verbose debug output (logs full request/response payloads)
--format FORMAT Output format: text (default), json
```
> [!WARNING]
> `--debug` logs full API request and response payloads to stderr. Do not use in shared terminals
> or redirect to persistent logs — the output may contain session tokens and other sensitive data.
## Architecture
```
.
├── cmd/tgdev/ CLI entrypoint and command implementations
│ ├── main.go Command dispatch, flag parsing, client creation
│ └── version.go Build version variables (injected via ldflags)
├── invoke/ TL method registry, JSON unmarshal, invocation, response formatting
│ ├── registry.go Bidirectional lookup: TL schema names ↔ Go types
│ ├── invoke.go Generic TL method invocation via raw RPC
│ ├── invoker.go DebugInvoker middleware: logging, timing, correlation
│ ├── unmarshal.go JSON → gotd struct with interface constructor resolution
│ ├── format.go InvokeJSON: JSON-serialized response path
│ └── pretty.go Color definitions and duration formatting
├── internal/
│ ├── config/ Config loading, validation, credential layering
│ │ └── config.go CLI flags > env vars > config file (~/.tgdev.json)
│ ├── ipc/ Unix domain socket IPC server and client
│ │ └── ipc.go InvokeRequest/Response JSON protocol
│ └── mcpserver/ MCP server with tool definitions
│ └── server.go tgdev_list_methods, tgdev_invoke, etc.
├── trace/ Correlation ID tracing, update listener, RPC middleware
│ ├── tracer.go Tracer: combines invoke logging + update tracking
│ └── listener.go UpdateListener for gotg dispatcher
├── tg-dev-agent/ Skill: Telegram bot testing via tgdev + MCP
├── go.mod Module: github.com/pageton/gotg-cli (Go 1.25.0)
└── README.md User-facing documentation
```
The `invoke` package provides bidirectional lookup between TL schema names and gotd Go types using reflection over the full `tg.TypesMap()` and `tg.TypesConstructorMap()` registries. The `trace` package adds correlation IDs that link updates to handler invocations to API calls to responses.
## Dependencies
- [gotd/td](https://github.com/gotd/td) — MTProto client library
- [pageton/gotg](https://github.com/pageton/gotg) — Telegram framework (local replace directive)
- [modelcontextprotocol/go-sdk](https://github.com/modelcontextprotocol/go-sdk) — MCP server SDK
- [fatih/color](https://github.com/fatih/color) — Colored terminal output
- [modernc.org/sqlite](https://modernc.org/sqlite) — Pure-Go SQLite driver