{"id":"e4083d9a-2438-4733-a510-52492062166a","slug":"tg-account-mcp","kind":"mcp","name":"tg-account-mcp","summary":"Self-hosted multi-account Telegram MCP server for consent-based agent workflows","owner":"Mesteriis","repoUrl":"https://github.com/Mesteriis/tg-account-mcp","license":"Apache-2.0","licenseTier":"permissive","trust":"community","stars":0,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-09-16T16:45:57.000Z","addedAt":"2026-10-14T05:15:09.114Z","logoUrl":"https://avatars.githubusercontent.com/u/14878777?u=496d50281c59f79d086e3e784ee47f3e2ca071a0&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["communication","cloud-infra","memory-knowledge"],"tags":["ai-agents","python","self-hosted","telegram","telethon"],"runtime":"python","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-17T13:45:53.700Z","sample":false,"url":"https://conduits.dev/tools/tg-account-mcp","language":"Python","transports":["http"],"install":{"pypi":"tg-account-mcp"},"requirements":{"env":[{"name":"TG_MCP_STATE_DIR","secret":false,"required":false,"description":"Private directory initialized with tg-mcp setup"}],"upstreamMayCharge":false},"tools":null,"readme":"# TG multi-account MCP\n\n<!-- mcp-name: io.github.Mesteriis/tg-account-mcp -->\n\n[Русская документация](README.ru.md)\n\nA self-hosted [Model Context Protocol](https://modelcontextprotocol.io/) server that lets\nAI agents work with Telegram through explicitly selected user accounts and optional bots.\nAccounts are connected in a local web wizard by scanning a QR code and entering a Telegram\n2FA password when required.\n\nThe server is designed as an agent tool rather than a Telegram client. It can search chat\nhistory, read folders and threads, download attachments, track updates, create drafts, and\nsend messages. Every operation names the account or bot it uses; the server never silently\nselects a sender.\n\n> [!IMPORTANT]\n> A Telegram session can access the corresponding account. Run this service on infrastructure\n> you control, protect the state directory and MCP tokens, and give agent tokens only the\n> permissions they need.\n\nThis is an unofficial integration that uses the Telegram API and is not affiliated with or\nendorsed by Telegram.\n\n## What it supports\n\n- Multiple Telegram user accounts, each with its own QR/2FA onboarding flow and session.\n- Dashboard controls to disable, reconnect, or permanently delete an account and its local session.\n- Optional Telegram bots connected independently through BotFather tokens.\n- Streamable HTTP MCP with Bearer-token authentication.\n- Chat, folder, message, attachment, mention, topic, reply-thread, and global search tools.\n- Cyrillic/Latin transliteration matching when finding chats.\n- User and bot sending, edits, scheduling, forwarding, reactions, drafts, and idempotency keys.\n- Scoped agent tokens with `read`, `send`, and `admin` permissions plus identity/chat allowlists.\n- A private operations dashboard that records metadata without message text, queries, passwords,\n  or tokens.\n- Docker Compose deployment with Caddy-managed HTTPS.\n\nThe current release exposes 44 MCP tools. See the [tool catalog](docs/tools.md) for the full\nlist and behavior notes.\n\n## Requirements\n\n- Python 3.12+\n- [uv](https://docs.astral.sh/uv/)\n- A Telegram `api_id` and `api_hash` from\n  [my.telegram.org](https://my.telegram.org/apps)\n\nDocker and a domain are required only for the Compose deployment.\n\n## Quick start\n\nInstall the published package:\n\n```sh\nuv tool install tg-account-mcp\ntg-mcp setup\nTG_MCP_PORT=8765 tg-mcp serve\n```\n\nFor development from a source checkout:\n\n```sh\nuv sync --frozen\nuv run tg-mcp setup\nTG_MCP_PORT=8765 uv run tg-mcp serve\n```\n\n`setup` requests the Telegram API credentials through local terminal input and generates a\nrandom MCP access token. It does not request your phone number or account password.\n\nOpen [http://127.0.0.1:8765/](http://127.0.0.1:8765/) and follow the account wizard:\n\n1. Scan the QR code in **Telegram → Settings → Devices → Link Desktop Device**.\n2. Enter the Telegram cloud password if 2FA is enabled.\n3. Give the account a local display name.\n\nRepeat the wizard to add more accounts. Bots are optional and are added separately in the\ndashboard. Their tokens are verified with Telegram before storage.\n\nThe state directory defaults to `~/.local/share/tg-mcp`. Override it with `--state-dir` or\n`TG_MCP_STATE_DIR`.\n\n## Connect an MCP client\n\nPrint the main token locally:\n\n```sh\nuv run tg-mcp show-token\n```\n\nConfigure the client to use the Streamable HTTP endpoint and Bearer header:\n\n```json\n{\n  \"url\": \"http://127.0.0.1:8765/mcp\",\n  \"headers\": {\n    \"Authorization\": \"Bearer <MCP_TOKEN>\"\n  }\n}\n```\n\nThe surrounding configuration shape depends on the MCP client. Clients that require OAuth and\ncannot set a Bearer header are not currently supported.\n\nStart with `get_capabilities`, `list_accounts`, and `list_bots`. All account and bot operations\nrequire an explicit stable ID such as `acct_…` or `bot_…`.\n\nFor a folder-oriented request such as “show today’s messages in ITQ that concern my tasks,” an\nagent can call `list_folders`, then `get_folder_messages` with matching `date_from` and `date_to`\nvalues and an IANA timezone such as `Europe/Madrid`, provided that processing this content is\npermitted under the consent requirements below.\n\n## Codex plugin\n\nThis repository also ships a Codex plugin with authenticated automatic service discovery and a\nworkflow skill for chat resolution, folder summaries, complete pagination, attachments, drafts,\nand idempotent sending.\n\n```sh\ncodex plugin marketplace add Mesteriis/tg-account-mcp --ref main\ncodex plugin add tg-account-mcp@tg-account-mcp\n```\n\nThe plugin sends an authenticated discovery request to the local machine and network. Discovery\nrequests and replies are authenticated using the configured MCP token; the token itself is never\nbroadcast or sent before the discovered endpoint is authenticated. Set `TG_MCP_URL` to skip\ndiscovery and use a specific HTTPS endpoint. See the\n[Codex plugin guide](docs/CODEX_PLUGIN.md) for server setup and example prompts.\n\nWhen Codex and the service run as the same OS user on one machine, the bridge reads the token from\nthe protected local state automatically. For a service on another machine, provide\n`TG_MCP_TOKEN` to the Codex process.\n\n## Responsible use and Telegram terms\n\nOperators must comply with the [Telegram API Terms](https://core.telegram.org/api/terms) and\n[Content Licensing Terms](https://telegram.org/tos/content-licensing). In particular:\n\n- obtain and use your own Telegram `api_id`;\n- do not perform actions on a user's behalf without that user's knowledge and consent;\n- do not scrape, index, harvest, aggregate, train on, benchmark with, or otherwise provide\n  Telegram content to AI/ML systems unless every relevant user has given explicit, informed,\n  affirmative, and continuing consent for the specific content and context;\n- respect the rights, privacy, and instructions of people whose messages or files are accessed.\n\nInstalling this software does not grant rights to Telegram content. Use synthetic data, your own\nsaved messages, or chats where the required consent has been obtained and remains valid.\n\n## Agent access control\n\nThe token generated by `setup` is the administrative token. Use `create_agent_token` to issue a\nseparate token for each agent and restrict it by:\n\n- scope: `read`, `send`, or `admin`;\n- permitted account and bot IDs;\n- permitted chat IDs.\n\nOnly a SHA-256 hash of an agent token is retained, and the plaintext token is returned once.\nRevoke access with `revoke_agent_token`. A chat-limited token cannot use aggregate inbox, folder,\nor global-search tools because those operations could reveal neighboring chats.\n\n## Direct LAN deployment\n\nFor a trusted private network without the Compose HTTPS proxy, bind the service to the LAN and\nstart it on the LAN:\n\n```sh\nTG_MCP_BIND=0.0.0.0 \\\nTG_MCP_PORT=8765 \\\ntg-mcp serve\n```\n\nOpen the server's LAN address in a browser. The dashboard does not ask for a token, so every user\nwho can reach it can view its metadata and manage Telegram identities. Same-origin browser requests\nare accepted automatically; a separate frontend origin must be added to\n`TG_MCP_ALLOWED_ORIGINS`. Permit TCP `8765` and discovery UDP `38475` only from trusted networks.\nUse a VPN or an authenticating reverse proxy when traffic crosses an untrusted network.\n\n## Docker Compose deployment\n\nPoint a domain at the server and allow inbound TCP 80/443, then run:\n\n```sh\ncp .env.example .env\n# Set TG_MCP_DOMAIN to the real hostname in .env.\ndocker compose build\ndocker compose run --rm --no-deps tg-mcp setup\ndocker compose up -d\n```\n\nOpen `https://your-domain.example/` for initial setup. The dashboard is intentionally available\nwithout a token; protect the domain with network policy or an authenticating reverse proxy.\nAgents still connect to `https://your-domain.example/mcp` with a Bearer token.\n\nCompose also publishes authenticated UDP discovery on port `38475` and advertises that HTTPS\nendpoint to clients on the same private network. Change `TG_MCP_DISCOVERY_PORT` on both sides when\nneeded, or set `TG_MCP_DISCOVERY=false` if local discovery is not part of the deployment.\n\nCaddy terminates HTTPS and does not expose the application port publicly. The application\ncontainer runs as an unprivileged user with a read-only root filesystem. Run one application\nreplica per state volume.\n\n## Security model\n\n- The state directory is required to have mode `0700`; sensitive files use `0600`.\n- Symlinks, hard-linked sensitive files, foreign ownership, and broad permissions are rejected.\n- The web UI has no third-party scripts, fonts, analytics, or remote assets.\n- Dashboard account data and setup APIs are available without a token to clients that can reach\n  the server; the MCP endpoint always requires a Bearer token.\n- Host and Origin values are checked against exact allowlists; wildcards are rejected.\n- Logs and operations history omit message bodies, search terms, credentials, QR URLs, and 2FA\n  passwords.\n- Tests use fake Telegram adapters and never send real messages.\n\nBack up the state volume only while the service is stopped and store the backup encrypted. If a\nsession is exposed, revoke it from **Telegram → Devices**. See [SECURITY.md](SECURITY.md) for\nreporting vulnerabilities and the Russian README for operational details and error codes.\n\n## Known limitations\n\n- Secret chats are not available through Telegram's cloud API.\n- Message deletion and distributed/multi-replica deployment are not supported.\n- History is read from Telegram on demand rather than copied into a local database.\n- Positional pagination can repeat or skip items when new messages arrive between pages.\n- `poll_updates` keeps its most recent 2,000 events in process memory and resets after restart.\n\n## Development\n\n```sh\nuv sync --frozen\nuv run ruff check .\nuv run ruff format --check .\nuv run pytest -q\nuv build\nTG_MCP_DOMAIN=mcp.example.test docker compose config --quiet\ndocker build -t tg-account-mcp:local .\n```\n\nArchitecture and contributor setup are documented in [docs/architecture.md](docs/architecture.md)\nand [CONTRIBUTING.md](CONTRIBUTING.md). Release and registry steps are in\n[docs/PUBLISHING.md](docs/PUBLISHING.md).\n\n## License\n\nLicensed under the [Apache License 2.0](LICENSE).\n"}