telegram-call-mcp

telegram-call-mcp

MCP server that enables AI agents to place real Telegram voice calls and speak a message aloud via TTS, with configurable repeats and call handling.

Category
Visit Server

README

telegram-call-mcp

An MCP server that lets AI agents place real Telegram voice calls and speak a message aloud. The agent calls one tool — make_call — with the text and a repeat count; the server synthesizes speech (any TTS model on OpenRouter, default x-ai/grok-voice-tts-1.0 with the rex voice), texts the fuller details version to the owner's chat, rings their Telegram, waits for them to pick up, plays the message, and hangs up. A second tool — send_message — texts the owner without ringing, for updates that can wait.

Built for "wake me up if production is on fire" scenarios: text notifications are easy to sleep through, a ringing phone is not.

Agent ──make_call("DB is down", details="…")──▶ telegram-call-mcp
                                                   │  1. TTS via OpenRouter (mp3)
                                                   │  2. ffmpeg → WAV 48kHz mono
                                                   │  3. 💬 text message with the details
                                                   │  4. 📞 Telegram P2P call (py-tgcalls)
                                                   ▼
                                           owner's phone rings,
                                           message plays twice

The tools

make_call

Argument Type Required Description
message string yes Text to speak. Markdown, URLs, emojis and long IDs are stripped; if the result still exceeds MAX_MESSAGE_LENGTH (default 500 chars), the call is rejected with an error asking the agent to shorten it.
repeat int 1–10 no (default 2) How many times to play the message, with a 2s pause between repeats.
details string ≤4000 no Fuller version of the alert, sent as a plain Telegram text message right before the call rings — links, IDs, error output and next steps belong here, not in the voice. When omitted, the spoken text is sent instead, so every call is preceded by a text.

Returns a structured result:

{ "status": "answered", "detail": "message played in full", "message_spoken": "DB is down", "text_sent": true }

status is one of answered, no_answer, busy, declined, error; text_sent reports whether the pre-call text message reached the chat. An unanswered call means the spoken message was not heard — the text usually still lands, but for anything critical the agent should retry the call later.

send_message

Argument Type Required Description
message string ≤4000 yes Text delivered verbatim to the owner's Telegram chat.

Returns { "status": "sent", "detail": "text message sent (57 chars)" }.

No ringing — for "deploy finished, all green" class updates that the owner reads whenever they next pick up the phone. The tool descriptions steer the agent to reserve make_call for things that cannot wait.

Requirements

  • Python 3.10+
  • ffmpeg (with ffprobe) in PATHbrew install ffmpeg / apt install ffmpeg
  • A dedicated Telegram account for the server (bots can't make calls, so it signs in as a real user account; see Security notes)
  • An OpenRouter API key for TTS

Setup

1. Install

pip install telegram-call-mcp        # or: pipx install / uv tool install

Or from source:

git clone https://github.com/maloleg/telegram-call-mcp
cd telegram-call-mcp
pip install .

2. Get Telegram API credentials

  1. Sign in at my.telegram.org with the account that will be making the calls (a spare/dedicated account, not your own).
  2. Open API development tools, create an application (any name, URL can be left empty).
  3. Note the api_id and api_hash.

3. Sign in once

export TELEGRAM_API_ID=123456
export TELEGRAM_API_HASH=abcdef...
export CALL_TARGET_USER_ID=111111111   # your own numeric Telegram user id

telegram-call-mcp login

(The OpenRouter key is not needed here — login only talks to Telegram.)

The login prompts for the phone number, the code Telegram sends, and the 2FA password if enabled, then saves a session file to ~/.telegram-call-mcp/telegram.session.

Not sure about your numeric user id? Ask @userinfobot on Telegram.

The caller and the callee must be different accounts. Telegram cannot call itself. Sign the server in with a dedicated account and point CALL_TARGET_USER_ID at your personal one.

On the receiving account, allow calls from non-contacts (Settings → Privacy → Calls → Everybody) or add the server's account to your contacts — otherwise Telegram rejects the call before it ever rings.

4. Verify the setup

export OPENROUTER_API_KEY=sk-or-...   # the remaining variable, for TTS

telegram-call-mcp check

check (alias: doctor) verifies everything a real call needs — config, ffmpeg, the Telegram session, that the target user is reachable, and the TTS key — without ringing anyone:

OK   config   all required variables set
OK   ffmpeg   ffmpeg and ffprobe found in PATH
OK   session  signed in as Alert Bot (id=8012345678)
OK   target   can call Oleg (id=111111111)
OK   tts      x-ai/grok-voice-tts-1.0 synthesized 38400 bytes of audio

All checks passed - ready to place calls.

Run it after any config change: the server connects lazily, so a broken setup would otherwise surface only on the first real call — usually at the worst possible moment.

5. Add to your MCP client

Claude Code — a personal alert tool belongs in user scope (-s user, available in all your projects); the default scope registers the server only in the current project. Reference the variables exported above instead of pasting literal values, so the secrets don't end up in your shell history:

claude mcp add -s user telegram-call \
  --env TELEGRAM_API_ID="$TELEGRAM_API_ID" \
  --env TELEGRAM_API_HASH="$TELEGRAM_API_HASH" \
  --env CALL_TARGET_USER_ID="$CALL_TARGET_USER_ID" \
  --env OPENROUTER_API_KEY="$OPENROUTER_API_KEY" \
  -- telegram-call-mcp

(If you keep the variables in a .env file, load them first with set -a; source .env; set +a.)

Claude Desktop / any JSON-config client (claude_desktop_config.json):

{
  "mcpServers": {
    "telegram-call": {
      "command": "telegram-call-mcp",
      "env": {
        "TELEGRAM_API_ID": "123456",
        "TELEGRAM_API_HASH": "abcdef...",
        "CALL_TARGET_USER_ID": "111111111",
        "OPENROUTER_API_KEY": "sk-or-..."
      }
    }
  }
}

That's it. Ask the agent to "call me and say the deploy finished" to test.

Configuration reference

Variable Required Default Description
TELEGRAM_API_ID From my.telegram.org
TELEGRAM_API_HASH From my.telegram.org
CALL_TARGET_USER_ID Numeric Telegram user id to call
OPENROUTER_API_KEY OpenRouter API key for TTS (not needed for login)
TTS_MODEL x-ai/grok-voice-tts-1.0 Any TTS model on OpenRouter's /audio/speech endpoint
TTS_VOICE rex Voice name. The default applies only with the default model (voice names are model-specific); set it explicitly for other models, or set it empty to send no voice
TTS_BASE_URL https://openrouter.ai/api/v1 Any OpenAI-compatible audio API works
TELEGRAM_PROXY socks5://host:port or http://host:port for MTProto (Telethon ignores HTTP_PROXY)
TELEGRAM_SESSION_PATH ~/.telegram-call-mcp/telegram Session file location (without .session)
CALL_ANSWER_TIMEOUT 45 Seconds to wait for the callee to answer
CALL_REPEAT_PAUSE 2 Pause between repeats, seconds
MAX_MESSAGE_LENGTH 500 Max message length after sanitization; longer messages are rejected, not truncated
LOG_LEVEL INFO stderr logging verbosity

Security notes

  • The session file is full access to the Telegram account. It is created with your user permissions in ~/.telegram-call-mcp/; treat it like a private key. Use a dedicated account so a leak never exposes your personal chats.
  • The tool can only reach the one user id fixed in the server config — the agent cannot choose an arbitrary callee or text recipient, dial numbers, or message anyone else. The pre-call text goes to that same user.
  • The message text passes through OpenRouter for synthesis; don't have agents speak secrets aloud.
  • Automating a user account is subject to Telegram's terms; a dedicated account keeps any risk away from your personal one.

Troubleshooting

Start with telegram-call-mcp check — it validates the config, ffmpeg, the session, target reachability and the TTS key in one pass, without placing a call.

Symptom Cause / fix
Tool error: session not authorized Run telegram-call-mcp login with the same env vars the MCP client uses.
Connection to Telegram failed at startup Direct MTProto is blocked in your network. Set TELEGRAM_PROXY to a local SOCKS/HTTP proxy.
Call connects but there is silence / error (TelegramServerError) after ~10s of "REFLECTOR" log lines The voice media stream (UDP to Telegram relays) is blocked. A SOCKS proxy is not enough — voice traffic bypasses it. Run your VPN in TUN / system-tunnel mode so UDP is routed too.
declined immediately, phone never rang The callee's privacy settings reject calls from non-contacts, or the two accounts are the same.
ffmpeg not found Install ffmpeg and make sure ffmpeg/ffprobe are in the PATH visible to your MCP client.
TTS HTTP 401/402 Bad or out-of-credit OPENROUTER_API_KEY.

Development

python -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/mypy src
LOG_LEVEL=DEBUG .venv/bin/telegram-call-mcp   # run on stdio

The call machinery lives in caller.py (Telethon + py-tgcalls, pinned to 2.3.3 — private-call APIs are version-sensitive), TTS and audio prep in tts.py, tool definition in server.py.

License

MIT

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured