Skip to main content
Glama
StoyPenny

Telegram MCP Server

by StoyPenny

Telegram MCP Server

License: MIT Python 3.10+ Docker MCP Telegram Bot API

A Model Context Protocol (MCP) server that enables AI assistants (like Kilo Code) to ask you questions via Telegram and wait for your responses. This creates a "human-in-the-loop" workflow where the AI can request decisions, approvals, or specific input during long-running tasks.

Features

  • ๐Ÿค– Interactive AI Workflow: AI can pause and ask you questions via Telegram

  • ๐Ÿ“ฑ Button Support: Present multiple choice options as clickable buttons

  • โฑ๏ธ Long Polling: Waits up to 2 minutes for your response

  • ๐Ÿ”’ Secure: Uses environment variables for credentials

  • ๐ŸŽฏ Simple Integration: Works with any MCP-compatible AI assistant

  • ๐Ÿณ Docker Support: Run natively or in a container

Prerequisites

  • Python 3.10+ (for native installation)

  • OR Docker and Docker Compose (for containerized installation)

  • A Telegram account

  • A Telegram Bot Token (from @BotFather)

Installation Methods

You can run this MCP server in two ways:

  1. Native Python Installation - Run directly on your system

  2. Docker Installation - Run in a container (recommended for production)

Native Installation

1. Create a Telegram Bot

  1. Open Telegram and search for @BotFather

  2. Send /newbot and follow the prompts

  3. Name your bot (e.g., "MyDevBot")

  4. Copy the HTTP API Token provided

  5. Important: Send /start to your new bot so it can message you

2. Find Your Telegram User ID (Optional)

  1. Search for @userinfobot on Telegram

  2. Send it any message

  3. Copy your User ID

3. Clone and Setup

# Clone the repository git clone https://github.com/yourusername/telegram-mcp-server.git cd telegram-mcp-server # Create virtual environment python3 -m venv venv # Activate virtual environment source venv/bin/activate # On Linux/Mac # OR venv\Scripts\activate # On Windows # Install dependencies pip install -r requirements.txt

4. Configuration

Create a .env file from the sample:

cp .env.sample .env

Edit .env and add your credentials:

TELEGRAM_BOT_TOKEN=your_bot_token_here TELEGRAM_USER_ID=your_user_id_here # Optional - bot will auto-detect if not set

โš ๏ธ Security Note: The .env file is gitignored to protect your credentials.

5. Test the Server Locally

# Activate virtual environment source venv/bin/activate # Run the server python telegram_server.py

You should see:

โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ โ–„โ–€โ–€ โ–„โ–€โ–ˆ โ–ˆโ–€โ–€ โ–€โ–ˆโ–€ โ–ˆโ–€โ–„โ–€โ–ˆ โ–ˆโ–€โ–€ โ–ˆโ–€โ–ˆ โ”‚ โ”‚ โ–ˆโ–€ โ–ˆโ–€โ–ˆ โ–„โ–„โ–ˆ โ–ˆ โ–ˆ โ–€ โ–ˆ โ–ˆโ–„โ–„ โ–ˆโ–€โ–€ โ”‚ โ”‚ FastMCP 2.14.2 โ”‚ โ”‚ ๐Ÿ–ฅ Server: Telegram Human Loop โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Press Ctrl+C to stop the test.

Docker Installation

1. Configure Environment

cp .env.sample .env # Edit .env with your credentials

2. Build and Run

# Build the Docker image docker-compose build # Start the container in detached mode docker-compose up -d

3. View Logs

docker-compose logs -f telegram-mcp

4. Stop the Server

docker-compose down

Docker Commands Reference

Building:

# Build the image docker-compose build # Build without cache (force rebuild) docker-compose build --no-cache

Running:

# Start in detached mode (background) docker-compose up -d # Start in foreground (see logs directly) docker-compose up # Start and rebuild if needed docker-compose up -d --build

Monitoring:

# View logs docker-compose logs -f telegram-mcp # View last 100 lines of logs docker-compose logs --tail=100 telegram-mcp # Check container status docker-compose ps # Execute commands inside the container docker-compose exec telegram-mcp python --version

Stopping and Cleaning:

# Stop the container docker-compose stop # Stop and remove containers docker-compose down # Stop, remove containers, and remove volumes docker-compose down -v # Remove all (containers, networks, images) docker-compose down --rmi all

Restart:

# Restart the container docker-compose restart # Rebuild and restart from scratch docker-compose down docker-compose build --no-cache docker-compose up -d

Development:

# Open a shell in the running container docker-compose exec telegram-mcp /bin/bash # Test the server locally (without Docker) source venv/bin/activate && python telegram_server.py

Connecting to MCP Clients

For Kilo Code (or similar MCP clients)

  1. Open your MCP settings file:

    • Location: ~/.config/Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/mcpSettings.json

    • Or use your client's UI: Settings โ†’ MCP Servers โ†’ Edit Configuration

  2. Add this configuration (replace ):

{ "mcpServers": { "telegram": { "command": "bash", "args": ["/absolute/path/to/telegram-mcp-server/run.sh"] } } }

Example: If you cloned to /home/user/projects/telegram-mcp-server, use:

{ "mcpServers": { "telegram": { "command": "bash", "args": ["/home/user/projects/telegram-mcp-server/run.sh"] } } }
  1. Restart your MCP client or reload the MCP servers

Note: An example configuration is provided in mcp-config.example.json for reference.

Method 2: Direct Python Execution

{ "mcpServers": { "telegram": { "command": "/absolute/path/to/telegram-mcp-server/venv/bin/python", "args": ["/absolute/path/to/telegram-mcp-server/telegram_server.py"] } } }

Method 3: Using Docker

Option A: Docker Compose Exec

{ "mcpServers": { "telegram": { "command": "docker-compose", "args": [ "-f", "/absolute/path/to/telegram-mcp-server/docker-compose.yml", "exec", "-T", "telegram-mcp", "python", "telegram_server.py" ], "cwd": "/absolute/path/to/telegram-mcp-server" } } }

Option B: Docker Run

{ "mcpServers": { "telegram": { "command": "docker", "args": [ "run", "--rm", "-i", "--env-file", "/absolute/path/to/telegram-mcp-server/.env", "telegram-mcp-server", "python", "telegram_server.py" ] } } }

Available Tools

Once connected, your AI assistant will have access to these tools:

  1. ask_human(question, options, wait, timeout_seconds, allow_custom) - Send questions to Telegram

    • wait=True (default): Blocks until you respond or timeout

    • wait=False: Sends question and returns immediately (non-blocking mode)

    • options: Optional list of button choices

    • allow_custom=True (default): Adds "Custom answer" button when options provided

    • Works in both blocking and non-blocking modes

  2. get_telegram_response(mark_as_read) - Retrieve your latest Telegram message

    • Use after ask_human(wait=False) to get your response

    • mark_as_read=True (default): Won't retrieve the same message twice

  3. send_telegram_notification(message) - Send one-way status updates

    • For progress reports, completion notifications, or status updates

    • Doesn't expect a response

    • Perfect for keeping you informed during long-running tasks

  4. list_telegram_messages(limit) - View recent conversation history

    • Shows last 5-20 messages for context

    • Useful for checking if you've already replied

Usage Examples

Example 1: Simple Question

You say to your AI:

"I'm going to grab coffee. If you need to know which database to use, ask me via Telegram."

AI calls:

ask_human(question="Should I use PostgreSQL or MongoDB for this project?")

What happens:

  1. Your phone buzzes with a Telegram message

  2. You reply: "PostgreSQL"

  3. AI receives "PostgreSQL" and continues

Example 2: Multiple Choice with Buttons

AI calls:

ask_human( question="How should I structure the authentication?", options=["JWT", "Session Cookies", "OAuth2", "Skip for now"] )

What happens:

  1. You receive a Telegram message with 4 clickable buttons

  2. You tap "JWT"

  3. AI receives "JWT" instantly

Example 3: Approval Workflow

You say to your AI:

"Refactor the entire codebase, but ask me before making any breaking changes."

AI calls:

ask_human( question="I want to rename `getUserData()` to `fetchUser()`. This will break 23 files. Proceed?", options=["Yes, proceed", "No, skip this", "Show me the files first"] )

Example 4: Non-Blocking Mode for Complex Questions

AI asks without waiting:

ask_human( question="Please review this 500-line refactor and provide detailed feedback", wait=False )

What happens:

  1. You receive the question on Telegram

  2. You take your time to review (no timeout)

  3. When ready, you tell the AI: "I've answered on Telegram"

  4. AI retrieves your answer: get_telegram_response()

Example 5: Progress Notifications

AI sends status updates:

send_telegram_notification("๐Ÿš€ Starting database migration...") send_telegram_notification("โœ… Step 1/5 complete: Schema created") send_telegram_notification("๐ŸŽ‰ Migration complete! All 1,247 records migrated successfully.")

How It Works

  1. AI calls with a question and optional button choices

  2. Server sends Telegram message to your configured chat

  3. Long polling loop checks Telegram every 2 seconds for your response

  4. You respond via text or button click

  5. Server returns your answer to the AI

  6. AI continues with your input

Timeout Behavior

  • Default timeout: 120 seconds (2 minutes)

  • Configurable via the timeout_seconds parameter in ask_human()

  • If you don't respond in time, the AI receives: "Timeout: User did not respond in time..."

Non-Blocking Mode

For complex questions that require extended thinking time, use non-blocking mode to avoid timeouts:

  1. AI asks without waiting:

    ask_human("Please review this architecture and provide feedback", wait=False)
  2. You receive the question and can take as long as needed to think and respond

  3. When ready, tell the AI you've replied:

    "I've answered on Telegram"

  4. AI retrieves your answer:

    answer = get_telegram_response()

Custom Answers with Buttons

When you provide button options, the AI automatically adds a "โœ๏ธ Custom answer" button (unless allow_custom=False). This lets you:

  • Click a button for quick selection

  • OR type your own custom response

Example:

ask_human( "Which database?", options=["PostgreSQL", "MongoDB", "MySQL"], wait=False )

You'll see 4 buttons:

  • PostgreSQL

  • MongoDB

  • MySQL

  • โœ๏ธ Custom answer (type below)

Best Practices

Use Non-Blocking Mode (

  • Questions require code review or deep analysis

  • You might be away from your device

  • The decision requires research or consultation

  • You need more than 2 minutes to respond

Use Blocking Mode (

  • Questions are simple yes/no decisions

  • You're actively working with the AI

  • Quick responses are expected

  • Using button options for multiple choice

Use Notifications (

  • Progress updates during long-running tasks

  • Task completion notifications

  • Error or warning alerts

  • Status updates that don't require a response

  • Keeping yourself informed while away from the computer

Project Structure

telegram-mcp-server/ โ”œโ”€โ”€ telegram_server.py # Main MCP server code โ”œโ”€โ”€ .env # Your credentials (gitignored) โ”œโ”€โ”€ .env.sample # Template for environment variables โ”œโ”€โ”€ .gitignore # Protects secrets โ”œโ”€โ”€ requirements.txt # Python dependencies โ”œโ”€โ”€ run.sh # Startup script (executable) โ”œโ”€โ”€ mcp-config.example.json # Example MCP configuration (customize for your setup) โ”œโ”€โ”€ Dockerfile # Docker image definition โ”œโ”€โ”€ docker-compose.yml # Docker Compose configuration โ”œโ”€โ”€ .dockerignore # Docker build exclusions โ””โ”€โ”€ README.md # This file

Troubleshooting

"Command 'python' not found"

Solution: Use python3 instead, or install the symlink:

sudo apt install python-is-python3

The run.sh script already uses the correct Python from the virtual environment.

"Error: Could not find a Telegram Chat ID"

Solution: Make sure you've sent /start to your bot at least once.

"Permission denied: ./run.sh"

Solution: Make the script executable:

chmod +x run.sh

"Timeout: User did not respond in time"

Solutions:

  • Respond faster (within 2 minutes)

  • Increase timeout in the ask_human() call

  • Use non-blocking mode (wait=False) for complex questions

MCP Server Not Showing in Client

Solutions:

  1. Check the MCP settings file path is correct

  2. Verify the absolute path in your configuration

  3. Restart your MCP client completely

  4. Check client logs for connection errors

Docker Container Won't Start

Check logs:

docker-compose logs telegram-mcp

Environment Variables Not Loading

Ensure .env file exists and is properly formatted:

cat .env

Permission Issues with Docker

If you encounter permission issues, ensure the .env file is readable:

chmod 644 .env

Advanced Configuration

Changing the Default Timeout

You can customize the timeout per question:

# Short timeout for quick questions ask_human("Proceed?", options=["Yes", "No"], timeout_seconds=30) # Longer timeout for thoughtful questions ask_human("Which approach?", timeout_seconds=300) # 5 minutes

Restricting to Specific User

The server uses TELEGRAM_USER_ID from .env. Only messages from this user ID will be accepted.

Using Multiple Bots

Create separate directories with different .env files and register each as a different MCP server:

{ "mcpServers": { "telegram-work": { "command": "bash", "args": ["/path/to/work-bot/run.sh"] }, "telegram-personal": { "command": "bash", "args": ["/path/to/personal-bot/run.sh"] } } }

Security Best Practices

  1. โœ… Never commit - Already in .gitignore

  2. โœ… Use - Prevents unauthorized users from controlling your AI

  3. โœ… Regenerate tokens if accidentally exposed

  4. โœ… Use private Telegram bots - Don't share your bot with others

  5. โœ… Use Docker secrets for sensitive data in production

  6. โœ… Regularly update the base Python image for security patches

Production Deployment

For production deployment:

  1. Remove development volume mounts from docker-compose.yml

  2. Use environment variables or secrets management instead of .env file

  3. Consider using a process manager or orchestration tool (Kubernetes, Docker Swarm)

  4. Set up proper logging and monitoring

  5. Configure restart policies appropriately

Example production docker-compose.yml:

version: '3.8' services: telegram-mcp: build: context: . dockerfile: Dockerfile container_name: telegram-mcp-server environment: - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN} - TELEGRAM_USER_ID=${TELEGRAM_USER_ID} - PYTHONUNBUFFERED=1 restart: always logging: driver: "json-file" options: max-size: "10m" max-file: "3"

Dependencies

  • fastmcp (2.14.2+) - MCP server framework

  • httpx (0.28.1+) - Async HTTP client for Telegram API

  • python-dotenv (1.2.1+) - Environment variable management

See requirements.txt for full list.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - Use freely!

Support

For issues with:

Changelog

v1.0.0 (2026-01-02)

  • Initial release

  • Support for blocking and non-blocking question modes

  • Button support for multiple choice questions

  • Progress notification system

  • Docker support

  • Comprehensive documentation

-
security - not tested
F
license - not found
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/StoyPenny/mcp-kilo-telegram'

If you have feedback or need assistance with the MCP directory API, please join our Discord server