Setup
Better Telegram MCP — Manual Setup Guide
Section titled “Better Telegram MCP — Manual Setup Guide”2026-05-02 Update (v<auto>+): Plugin install (Method 1) uses stdio mode with
TELEGRAM_BOT_TOKEN. Bot mode only. User mode (MTProto via phone+OTP) is HTTP-only after this update. SetTELEGRAM_BOT_TOKENin plugin config (Method 1), or switch to HTTP mode for user mode.
Method overview
Section titled “Method overview”This plugin supports 3 install methods. Pick the one that matches your use case:
| Priority | Method | Transport | Best for |
|---|---|---|---|
| 1. Default | Plugin install (uvx/npx) | stdio | Quick local start, single workstation, no OAuth/HTTP needed. |
| 2. Fallback | Docker stdio (docker run -i --rm) | stdio | Windows/macOS where native uvx/npx hits PATH or Python version issues. |
| 3. Recommended | Docker HTTP (docker run -p 8080:8080) | HTTP | Multi-device, OAuth/relay-form auth, team self-host, claude.ai web compatibility. |
All MCP servers across this stack share this priority hierarchy. Note: 2 plugins (better-godot-mcp and better-code-review-graph) only support Method 1 (stdio) — they need direct host access to project files / repo paths and don’t ship Docker / HTTP variants.
⚠️ Mutually exclusive — pick ONE per plugin: If you choose Method 2 (Docker stdio override) OR Method 3 (HTTP), do NOT also
/plugin installthis plugin via marketplace. Both load simultaneously and create duplicate entries in/mcpdialog (plugin’s stdio + your override). Plugin matching is by endpoint (URL or command string) per CC docs, not by name — andnpx/uvx≠docker≠ HTTP URL, so all three are distinct endpoints. Trade-off: choosing Method 2 or Method 3 means you lose this plugin’s skills/agents/hooks/commands. For full plugin features, use Method 1 (default plugin install) withuserConfigcredentials prompted at install time.
Prerequisites
Section titled “Prerequisites”- Python 3.13 (3.14+ is NOT supported)
uvoruvxinstalled (docs)- Docker (optional, for self-hosted HTTP setup)
- A Telegram account and either a bot token (bot mode) or a phone number (user mode, HTTP only)
Method 1: Plugin Install (stdio, Bot Mode Only)
Section titled “Method 1: Plugin Install (stdio, Bot Mode Only)”For Claude Code users, the plugin approach is the simplest. Bot mode only — user mode requires HTTP (see Method 3).
Credential prompts at install
Section titled “Credential prompts at install”When you run /plugin install, Claude Code prompts you for the following credentials (declared in userConfig per CC docs). Sensitive values are stored in your system keychain and persist across /plugin update:
| Field | Required | Where to obtain |
|---|---|---|
TELEGRAM_BOT_TOKEN | Optional (required for stdio bot mode) | From @BotFather. Note: HTTP user-mode (phone+OTP) is configured via relay form at /authorize, not via plugin install prompt. |
-
Get a bot token from @BotFather:
- Open Telegram, send
/newbotto @BotFather - Follow prompts to name your bot
- Copy the token (format:
123456789:ABCdefGHI-JKLmnoPQRstUVwxyz)
- Open Telegram, send
-
Open Claude Code and install the plugin (Claude Code prompts for
TELEGRAM_BOT_TOKEN):Terminal window /plugin marketplace add n24q02m/claude-plugins/plugin install better-telegram-mcp@n24q02m-plugins -
Restart Claude Code — the server starts in stdio bot mode with the token injected.
Need user mode (read messages, browse chats, manage groups)? Bot tokens cannot do this. Skip to Method 3 (HTTP) — user mode runs over HTTP only and does not use the
userConfigprompt.
Note: This installs the full plugin (skills + agents + hooks + commands + stdio MCP server). If you’d rather use Method 2 (Docker stdio) or Method 3 (HTTP) below, DO NOT
/plugin installthis plugin — pick Method 2 or Method 3 instead. All three methods are mutually exclusive (see Method overview).
Method 2: Docker stdio (fallback)
Section titled “Method 2: Docker stdio (fallback)”⚠️ Before adding the Docker stdio override below, ensure this plugin is NOT installed via marketplace: Run
/plugin uninstall better-telegram-mcp@n24q02m-pluginsfirst if you previously ran/plugin install. Otherwise both entries (plugin’snpx/uvxstdio + yourdocker runstdio) will load simultaneously since plugin matches by endpoint (command string), not by name.Trade-off accepted: Choosing this method means you lose this plugin’s skills/agents/hooks/commands. Use Method 1 instead if you want full plugin features.
-
Pull the image:
Terminal window docker pull n24q02m/better-telegram-mcp:latest -
Run with bot token:
Terminal window docker run -i --rm \-e TELEGRAM_BOT_TOKEN=your_bot_token \n24q02m/better-telegram-mcp
MCP Client Config (Docker)
Section titled “MCP Client Config (Docker)”{ "mcpServers": { "telegram": { "command": "docker", "args": [ "run", "-i", "--rm", "-e", "TELEGRAM_BOT_TOKEN", "n24q02m/better-telegram-mcp" ] } }}Docker stdio supports bot mode only. For user mode, run the container in HTTP mode (see Method 3 self-host).
Why upgrade to HTTP mode?
Section titled “Why upgrade to HTTP mode?”Stdio (Methods 1-2) is the simplest path for bot mode, but stdio cannot host the browser-based phone+OTP flow that user mode requires. Switch to HTTP for any of these reasons:
- User mode access (REQUIRED for user mode) — read messages, browse chat history, list contacts, create groups/channels. Bot tokens cannot do this; only MTProto user sessions can. User mode auth is browser-based (phone + OTP code from Telegram app + optional 2FA password) and only HTTP transport hosts that flow.
- claude.ai web compatibility — claude.ai supports HTTP MCP servers; stdio is desktop/CLI only.
- One server, many sessions — a single HTTP server is shared across N Claude Code sessions instead of one stdio process per session.
- Multi-device cred sync — log in once on any device; the server keeps the session.
- Multi-user team sharing — HTTP supports per-JWT-sub credential isolation, so a team can share one self-hosted instance.
- Always-on persistent process — enables webhook listeners, long-running agents, and scheduled tasks.
Method 3: Docker HTTP (recommended)
Section titled “Method 3: Docker HTTP (recommended)”⚠️ Before adding the HTTP override below, ensure this plugin is NOT installed via marketplace: Run
/plugin uninstall better-telegram-mcp@n24q02m-pluginsfirst if you previously ran/plugin install. Otherwise both entries (plugin’s stdio + your HTTP override) will load simultaneously since plugin matches by endpoint, not name.Trade-off accepted: Choosing this method means you lose this plugin’s skills/agents/hooks/commands. For example, the
better-telegram-mcp:setup-botskill will no longer be available. Use Method 1 instead if you want full plugin features.
Switching transport vs. setting credentials: The
userConfigprompt only configures credentials for stdio mode (Method 1 / Option 1). To switch transport to HTTP, overridemcpServersin your client settings per the snippets below — this is a separate path fromuserConfigand is not driven by the install prompt.
3.1. Hosted (n24q02m.com)
Section titled “3.1. Hosted (n24q02m.com)”Live production endpoint (Dynamic Client Registration + relay form auth):
{ "mcpServers": { "telegram": { "url": "https://better-telegram-mcp.n24q02m.com/mcp" } }}The client registers a public DCR client at /register, then opens
/authorize to fill the Telegram relay form. The form supports both modes:
- Bot mode — paste your bot token from @BotFather
- User mode — enter your phone number, then the OTP code Telegram sends to your Telegram app, then your 2FA password if enabled
The server bundles public Telegram dev credentials (api_id and api_hash), so users do not need to register at my.telegram.org. After the form completes, the server issues a Bearer JWT and tools become active immediately.
Python 3.14+ is not supported because Telethon and
cryptghave not yet shipped 3.14 wheels. The Docker image bakes in Python 3.13.
3.2. Self-host with docker-compose
Section titled “3.2. Self-host with docker-compose”For private deployments (single user or team):
-
Clone and configure:
Terminal window git clone https://github.com/n24q02m/better-telegram-mcp.gitcd better-telegram-mcpcp .env.example .env# edit .env: set PUBLIC_URL=https://your-domain.com and MCP_DCR_SERVER_SECRET (random 32+ bytes) -
Bundled Telegram dev credentials (
api_id=37984984,api_hash=2f5f4c76c4de7c07302380c788390100) are baked into the image — you do not need to register at my.telegram.org. Each user authenticates through the relay form by entering their own phone number and OTP code. -
Start the server (Docker compose recommended):
Terminal window docker compose up -dThe server binds
HOST=0.0.0.0and serves multi-user mode by default with per-JWT-sub credential isolation. -
Configure your MCP client to use your domain:
{"mcpServers": {"telegram": {"url": "https://your-domain.com/mcp"}}}
See oci-vm-prod/services/better-telegram-mcp/docker-compose.yml for a reference compose file.
Edge auth: relay password
Section titled “Edge auth: relay password”Public HTTP deployments expose <your-domain>/authorize to URL discovery. To prevent random Internet users from accessing the relay form, mint a relay password:
openssl rand -hex 32# Save in your skret / .env as:MCP_RELAY_PASSWORD=<generated-32-byte-hex>Share this password out-of-band (Signal/email/SMS) with anyone you invite to use your server. They will see a login form when first opening /authorize; once logged in, the cookie persists 24 hours.
Single-user dev exception: If PUBLIC_URL=http://localhost:8080, you can leave MCP_RELAY_PASSWORD empty to disable the gate. The server logs a warning if you skip the password with a non-localhost PUBLIC_URL.
Environment Variable Reference
Section titled “Environment Variable Reference”Stdio Mode (Bot Only)
Section titled “Stdio Mode (Bot Only)”| Variable | Required | Default | Description |
|---|---|---|---|
TELEGRAM_BOT_TOKEN | Yes | — | Bot token from @BotFather |
HTTP Mode (Bot + User)
Section titled “HTTP Mode (Bot + User)”HTTP mode credentials are entered via the browser-based relay form, not env vars. Server-side env vars for self-hosting:
| Variable | Required | Default | Description |
|---|---|---|---|
PUBLIC_URL | Self-host | — | Public URL of the server (enables multi-user) |
MCP_DCR_SERVER_SECRET | Self-host | — | DCR server secret (32+ random bytes) |
HOST | Self-host | 127.0.0.1 | Bind address (0.0.0.0 for Docker) |
PORT | Self-host | 8000 | HTTP port |
The bundled Telegram dev api_id (37984984) and api_hash (2f5f4c76c4de7c07302380c788390100) are public dev credentials baked into the source.
Troubleshooting
Section titled “Troubleshooting”Bot cannot send messages
Section titled “Bot cannot send messages”Bots can only message users who have started a conversation with the bot first. Have the target user send /start to your bot.
Bot token does not work
Section titled “Bot token does not work”Verify the token format: <bot_id>:<token_secret> (e.g., 123456789:ABCdefGHI-JKLmnoPQRstUVwxyz). Re-issue from @BotFather if needed.
Need to read messages or browse chat history
Section titled “Need to read messages or browse chat history”Bot mode (stdio Methods 1-2) cannot read messages or browse chats — the Bot API does not expose these capabilities. Switch to HTTP mode (Method 3) and authenticate as a user via phone+OTP.
OTP code not received (HTTP user mode)
Section titled “OTP code not received (HTTP user mode)”The OTP code is sent to the Telegram app as a message from “Telegram” service notifications, not via SMS. Open your Telegram app on any device.
Session expired (HTTP user mode)
Section titled “Session expired (HTTP user mode)”Re-run the /authorize flow on the HTTP server — the relay form will prompt for phone+OTP again.
2FA password prompt
Section titled “2FA password prompt”2FA passwords are entered via the relay form during OTP authentication. They are never stored in environment variables or files.
”FloodWaitError” from Telegram
Section titled “”FloodWaitError” from Telegram”Telegram rate-limits API calls. Wait the indicated time before retrying. The server handles this automatically for most operations.