MCP server for the Telegram Ads platform (ads.telegram.org, TON cabinet): create, target, pause and read stats for ads; 26 tools, new ads start on hold.
Why
Telegram does not publish an advertiser API. This server wraps the logged-in ads.telegram.org session (stel_token / stel_ssid in a gitignored .env) and exposes 26 MCP tools, plus ads://playbook and ads://account.
Cabinets: TON (billed in Gram), EUR and Stars (whole-number amounts, no user targeting; opt-in with TG_ADS_STARS=on). get_account returns money rules; bad amounts are rejected before any call. Unofficial — not Telegram.
Write permission is .env TG_ADS_WRITE_GATE=strict|confirm|open (default confirm). Spend/destructive tools need confirm=true unless open. A blocked call returns code: write_gated with tool / class / would_send (intended args, no secrets) and sent: false — not a platform dry-run.
Why this MCP
- Optional lazy tool loading: set
TG_ADS_TOOL_LOADING=lazy(or choose it in the setup wizard) to start with a small core and enable toolsets on demand; see Lazy tool loading. - Money safety: ads are created
on_hold; spending actions go through a write gate shown byget_account. - Targeting references and
search_targetsso the agent never guesses IDs; 3 prompts, 3 resources incl.ads://playbook. - Session cookies stay in
.env, never in chat. - Other Telegram Ads MCP servers on GitHub: Free-cat/telegram_ads_mcp (14 tools), reputasyon/telegram-ads-mcp (8 tools).
Lazy tool loading
Optional lazy tool loading: TG_ADS_TOOL_LOADING=lazy starts with a small core plus tg_ads_enable_toolsets and adds toolsets on demand (tools/list_changed). Startup cost (tools/list + instructions, ≈chars/4): eager ≈7262 tokens, lazy ≈1748 tokens (−76%). Default eager is unchanged; if your client ignores tools/list_changed, keep eager or reconnect after enabling. Scope: enablement is process-wide (the MCP SDK MCPServer has no per-session tool visibility). Over stdio that is one client; in shared HTTP mode one client's enabled toolsets are listed for every client of that process (each call still passes its own gates), so use eager for shared HTTP.
Clients and notifications/tools/list_changed (verified against official docs, changelogs or maintainer statements, 2026-10):
Maintained and up to date
- Actively maintained by ZAI.ONE: current version 0.6.0; release notes in CHANGELOG.md and Releases.
- Built-in update check: ask the assistant to run
check_update(public GitHub API, no credentials, cached; nothing is installed automatically;TG_ADS_DISABLE_UPDATE_CHECK=1turns it off). - Follows current MCP practice: tool annotations (read-only / destructive hints), server
instructions, prompts and resources, structured errors with recovery hints, secrets kept out of tool output, a token budget for tool descriptions enforced in tests. - CI runs the test suite on Linux and Windows for every pull request.
What's new in 0.5.0
- Compact output.
get_adsandget_ad_statsreturndetail="summary"by default: no null/empty fields, no per-bucketcharts. Passdetail="full"for the previous payload. - Safer
.env. From the working folder's.envonlySTEL_*cookies are read (no parent walk); settings come fromTG_ADS_ENV_FILE, the clone's.envor the process environment. - Agent layer. Router instructions, skills (launch / review / diagnose),
ads://guide/{topic}, errorhint/docs, Claude Code and Cursor plugins pinned tov0.5.0. - License. LicenseRef-ZAI-ONE 2.0 (source-available); earlier MIT releases stay MIT (see NOTICE).
Quick start
git clone https://github.com/zai-one/telegram-ads-mcp.git
cd telegram-ads-mcp
uv sync
cp .env.example .env # STEL_TOKEN / STEL_SSID — DevTools steps in INSTALL.md; never paste into chat
{
"mcpServers": {
"telegram-ads": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/telegram-ads-mcp", "run", "telegram-ads-mcp"]
}
}
}
Agent setup (clone, config, star): copy INSTALL.md into the chat. Command: telegram-ads-mcp (alias tg-ads-mcp). After connect: ads://playbook. Prompts: launch-campaign, review-account, diagnose-ad. Client file names are in INSTALL.md (Cursor, Claude, VS Code servers, Codex TOML). Do not put cookies in MCP env. Example: mcp.json.example.
HTTP: uv run telegram-ads-mcp --transport streamable-http --host 127.0.0.1 --port 8000 → http://127.0.0.1:8000/mcp.
Install anywhere (uvx, plugins)
Cookies stay in a .env file on disk (never in MCP env values or chat). For uvx installs point TG_ADS_ENV_FILE at that file (path only), or start the client from a folder that has .env. From the working folder's .env (that folder only, not its parents) the server takes STEL_* cookies and nothing else; settings such as TG_ADS_WRITE_GATE, MCP_TRANSPORT / MCP_HOST / MCP_PORT or TG_ADS_DISABLE_UPDATE_CHECK are read only from TG_ADS_ENV_FILE, the clone's own .env, or the process environment, so an unrelated project's .env cannot open the write gate or expose the server on the network.
# Claude Code: MCP only
claude mcp add telegram-ads --env TG_ADS_ENV_FILE=/path/to/telegram-ads.env -- uvx --from git+https://github.com/zai-one/[email protected] telegram-ads-mcp
# Claude Code: plugin = MCP + skills (launch / review / diagnose)
/plugin marketplace add zai-one/telegram-ads-mcp
/plugin install telegram-ads@telegram-ads-mcp
Cursor: one-click install or .cursor/mcp.json:
{"mcpServers": {"telegram-ads": {"command": "uvx", "args": ["--from", "git+https://github.com/zai-one/[email protected]", "telegram-ads-mcp"], "env": {"TG_ADS_ENV_FILE": "/path/to/telegram-ads.env"}}}}
Codex ~/.codex/config.toml:
[mcp_servers.telegram-ads]
command = "uvx"
args = ["--from", "git+https://github.com/zai-one/[email protected]", "telegram-ads-mcp"]
env = { TG_ADS_ENV_FILE = "/path/to/telegram-ads.env" }
Claude Desktop claude_desktop_config.json: the same mcpServers block as Cursor. Skills for Codex and other hosts: copy skills/* into .agents/skills/.
Skills: telegram-ads-launch-campaign, telegram-ads-review-account, telegram-ads-diagnose-ad (mirrored by the prompts). Guides on demand: ads://guide/index → ads://guide/{topic}.
Example asks: "Review my Telegram Ads cabinet", "Launch an ad for t.me/my_channel with CPM 0.5 and budget 5 Gram", "Why does ad 35 get no views?", "Pause ad 35", "Show stats for ad 35 for its lifetime".
Tools
Always create ads on_hold. budget="0" cannot go to review. Amounts are Gram strings. Search ads: no text / picture / media. launch_ad does not activate; it adds budget and sends review. Do not combine langs with specific channels.
Updates. check_update compares your version with the latest release and returns the release notes link plus the command to run (git pull --ff-only && uv sync in a clone, otherwise pip install --upgrade "telegram-ads-mcp @ git+…@vX"). run_in says where to run it. It only suggests and never installs. Only plain version tags (v1.2.3) are accepted. One anonymous GitHub API call, 3 s timeout, cached 24 h; after a failed call it waits 30 min, and force=true re-checks at most once a minute; offline returns status: unavailable. When the cache knows of a newer release, check_session adds update_hint and the server instructions get one line. At startup (stdio and HTTP alike) the server itself calls api.github.com anonymously, at most once a day, unless disabled; for a server or firewalled deployment set TG_ADS_DISABLE_UPDATE_CHECK=1 in .env or the process environment.
Issues
I'm working on this. If something is missing or broken, open an issue. I will patch this repo.
Use the form. Tick both “no cookies / no hashes” boxes. Never paste stel_token, stel_ssid, .env, confirm_hash, API hash=, or DevTools screenshots.
Local draft: uv run python scripts/check_security.py --issue draft.md — prints gh issue create only if the draft is clean. It does not open the Issue.
Support is not guaranteed. Issues are read when I can.
EUR and Stars support is fixture-tested; found a mismatch on a live EUR/Stars cabinet? Write on Telegram: t.me/zai_one. Do not send cookies in the GitHub issue.
Built by ZAI.ONE
ZAI.ONE is a digital agency working on websites, SEO, advertising and analytics. We also build tools that connect AI assistants to everyday work. Talk to us on Telegram about setup, automation or an integration for your team.
LicenseRef-ZAI-ONE · LICENSE · SECURITY.md · open an issue
License, use and contributing
- Use: you may install and use this MCP server freely for yourself and your organisation, including commercial work. If it helps, please consider giving the repository a ⭐ — appreciated, never required.
- Contribute: issues and pull requests are welcome; see CONTRIBUTING.md. Never post tokens, cookies, sessions or account data.
- Not allowed without written permission from ZAI.ONE: copying code into other projects, forking for redistribution, embedding the server in other products or offering it as a competing service.
- License: LicenseRef-ZAI-ONE 2.0 (source-available, not open source). Third-party notices and license history: NOTICE.