Skip to content
ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

3 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Telegram MCP Server

MCP Badge License: Apache 2.0 Python Lint & Format Check Docker Build & Compose Validation

๐Ÿ”€ Fork Changes

This is a fork of chigwell/telegram-mcp โ€” a fantastic Telegram MCP server built by @chigwell and @l1v0n1.

All original tools and credit belong to the upstream authors.

What this fork adds

The upstream repo runs the MCP server locally (Claude Desktop / Cursor on your laptop). This fork adds everything needed to run it remotely on a VPS, accessible over HTTPS by any MCP client from anywhere โ€” without keeping your laptop on.

๐Ÿณ Production Docker Setup (Dockerfile.prod + docker-compose.prod.yml)

Problem: The upstream Dockerfile runs the MCP in stdio/local mode. There was no production-ready container config for running it as a long-lived HTTPS service that remote MCP clients (Claude.ai, Cursor, etc.) can connect to.

Solution: Added a hardened Dockerfile.prod (Alpine-based, non-root user, SSE transport, health check) and docker-compose.prod.yml that binds the container to 127.0.0.1:8000 only โ€” so it's never exposed directly to the internet.

๐ŸŒ Nginx Reverse Proxy Config (nginx/nginx.conf)

Problem: Running the MCP on a public server without a reverse proxy means no TLS, no authentication, and the raw MCP port exposed to the internet.

Solution: Added a production Nginx config that:

  • Terminates HTTPS (via Let's Encrypt / Certbot) and redirects HTTP โ†’ HTTPS
    • Enforces HTTP Basic Auth (bcrypt via htpasswd) so only password-holders can connect
      • Correctly handles SSE long-lived connections (proxy_buffering off, 3600s timeouts)
        • Exposes only /sse, /messages, and /health โ€” blocks everything else

          • Sets Host: localhost on proxied requests to satisfy the MCP's DNS-rebinding protection

          ๐Ÿ› ๏ธ One-Shot EC2/VPS Bootstrap (deploy/setup-ec2.sh)

          Problem: Setting up Docker, Nginx, Certbot, and UFW firewall on a fresh cloud server requires many manual steps that are easy to get wrong.

          Solution: A single idempotent shell script that bootstraps a fresh Ubuntu 22.04/24.04 (or Amazon Linux 2023) instance end-to-end: installs Docker, Nginx, Certbot, clones the repo, drops the Nginx config in place, and configures the UFW firewall. Run it once, fill in .env, and you're live.

          ๐Ÿ“– Step-by-Step Deployment Guide (commands.md + deploy/README.md)

          Problem: No documentation existed for deploying this MCP to a remote server that multiple people can share.

          Solution: Complete, copy-paste-ready command reference covering: DNS setup, cloud firewall rules, Nginx config, Let's Encrypt TLS, HTTP Basic Auth password management, Docker build/run, smoke testing, redeployment, and a full troubleshooting section (covering real edge cases like broken docker-buildx on Amazon Linux, Cloudflare tunnel SSE buffering, Invalid Host header from MCP's DNS-rebinding middleware, and more).

          ๐Ÿ”ง MCP Transport Security Patch (patches/main-py-transport-security.patch)

          Problem: When Nginx proxies requests, it sets Host: localhost โ€” which trips MCP's built-in DNS-rebinding protection and causes 421 Misdirected Request errors.

          Solution: Patch for main.py that disables DNS-rebinding protection (TransportSecuritySettings(enable_dns_rebinding_protection=False)), since security at the Nginx+TLS+BasicAuth layer is strictly enforced instead. The patch file documents exactly what changed and why.

          ๐Ÿ”’ Credentials Security (.gitignore hardening)

          Problem: SSL/TLS certificate and private key files (.pem, .key, .crt, .cer, .p12, .pfx) were not gitignored, risking accidental commits of cryptographic secrets when working with Let's Encrypt or SSH keys on the server.

          Solution: Added these patterns to .gitignore to prevent accidental exposure.

          โœ… CI Workflows (.github/workflows/)

          Added GitHub Actions workflows for Python linting/formatting and Docker build validation, keeping the fork green and the code quality consistent.



๐Ÿค– MCP in Action

Here's a demonstration of the Telegram MCP capabilities in Claude:

Basic usage example:

Telegram MCP in action

  1. Example: Asking Claude to analyze chat history and send a response:

Telegram MCP Request

  1. Successfully sent message to the group:

Telegram MCP Result

As you can see, the AI can seamlessly interact with your Telegram account, retrieving and displaying your chats, messages, and other data in a natural way.


A full-featured Telegram integration for Claude, Cursor, and any MCP-compatible client, powered by Telethon and the Model Context Protocol (MCP). This project lets you interact with your Telegram account programmatically, automating everything from messaging to group management.


๐Ÿš€ Features & Tools

This MCP server exposes a huge suite of Telegram tools. Every major Telegram/Telethon feature is available as a tool!

Chat & Group Management

  • get_chats(page, page_size): Paginated list of chats
  • list_chats(chat_type, limit, unread_only, unmuted_only, with_about): List chats with metadata and filtering; with_about=True enriches output with each chat's description (slower).
  • get_chat(chat_id): Detailed info about a chat
  • create_group(title, user_ids): Create a new group
  • invite_to_group(group_id, user_ids): Invite users to a group or channel
  • create_channel(title, about, megagroup): Create a channel or supergroup
  • edit_chat_title(chat_id, title): Change chat/group/channel title
  • edit_chat_about(chat_id, about): Edit chat/group/channel description (About, max 255 chars)
  • delete_chat_photo(chat_id): Remove chat/group/channel photo
  • leave_chat(chat_id): Leave a group or channel
  • get_participants(chat_id): List all participants
  • get_admins(chat_id): List all admins
  • get_banned_users(chat_id): List all banned users
  • promote_admin(chat_id, user_id): Promote user to admin
  • demote_admin(chat_id, user_id): Demote admin to user
  • ban_user(chat_id, user_id): Ban user
  • unban_user(chat_id, user_id): Unban user
  • edit_admin_rights(chat_id, user_id, rank, ...rights): Set granular admin rights (extends promote_admin)
  • set_default_chat_permissions(chat_id, ...perms, until_date): Set default member permissions (send, media, invite, pin, etc.)
  • toggle_slow_mode(chat_id, seconds): Enable/disable slow mode in supergroups (0/10/30/60/300/900/3600s)
  • get_invite_link(chat_id): Get invite link
  • export_chat_invite(chat_id): Export invite link
  • import_chat_invite(hash): Join chat by invite hash
  • join_chat_by_link(link): Join chat by invite link
  • subscribe_public_channel(channel): Subscribe to a public channel or supergroup by username or ID
  • get_common_chats(user_id, limit=100, max_id=0): List chats shared with a specific user
  • get_message_read_by(chat_id, message_id): List users who have read a message (small groups/supergroups with read receipts enabled)

Messaging

  • get_messages(chat_id, page, page_size): Paginated messages
  • list_messages(chat_id, limit, search_query, from_date, to_date): Filtered messages
  • list_topics(chat_id, limit, offset_topic, search_query): List forum topics in supergroups
  • send_message(chat_id, message): Send a message
  • reply_to_message(chat_id, message_id, text): Reply to a message
  • edit_message(chat_id, message_id, new_text): Edit your message
  • delete_message(chat_id, message_id): Delete a message
  • delete_messages_bulk(chat_id, message_ids, revoke=True): Delete multiple messages in one call
  • delete_chat_history(chat_id, max_id=0, revoke=False): Clear the full message history of a chat
  • forward_message(from_chat_id, message_id, to_chat_id): Forward a message
  • pin_message(chat_id, message_id): Pin a message
  • unpin_message(chat_id, message_id): Unpin a message
  • unpin_all_messages(chat_id): Unpin all pinned messages in a chat
  • mark_as_read(chat_id): Mark all as read
  • get_message_context(chat_id, message_id, context_size): Context around a message
  • get_history(chat_id, limit): Full chat history
  • get_pinned_messages(chat_id): List pinned messages
  • get_last_interaction(contact_id): Most recent message with a contact
  • create_poll(chat_id, question, options, multiple_choice, quiz_mode, public_votes, close_date): Create a poll
  • list_inline_buttons(chat_id, message_id, limit): Inspect inline keyboards to discover button text/index
  • press_inline_button(chat_id, message_id, button_text, button_index): Trigger inline keyboard callbacks by label or index
  • send_reaction(chat_id, message_id, emoji, big=False): Add a reaction to a message
  • remove_reaction(chat_id, message_id): Remove a reaction from a message
  • get_message_reactions(chat_id, message_id, limit=50): Get all reactions on a message
  • send_scheduled_message(chat_id, message, schedule_date): Schedule a message for future delivery (ISO-8601 or Unix timestamp)
  • get_scheduled_messages(chat_id): List all pending scheduled messages in a chat
  • delete_scheduled_message(chat_id, message_ids): Delete one or more scheduled messages
  • get_message_link(chat_id, message_id, thread=False): Export a t.me/... link to a message (channels/supergroups only)

Contact Management

  • list_contacts(): List all contacts
  • search_contacts(query): Search contacts
  • add_contact(phone, first_name, last_name): Add a contact
  • delete_contact(user_id): Delete a contact
  • block_user(user_id): Block a user
  • unblock_user(user_id): Unblock a user
  • import_contacts(contacts): Bulk import contacts
  • export_contacts(): Export all contacts as JSON
  • get_blocked_users(): List blocked users
  • get_contact_ids(): List all contact IDs
  • get_direct_chat_by_contact(contact_query): Find direct chat with a contact
  • get_contact_chats(contact_id): List all chats with a contact

User & Profile

  • get_me(): Get your user info
  • update_profile(first_name, last_name, about): Update your profile
  • set_profile_photo(file_path): Set a profile photo from an allowed root path
  • delete_profile_photo(): Remove your profile photo
  • get_user_photos(user_id, limit): Get a user's profile photos
  • get_user_status(user_id): Get a user's online status

Media

  • get_media_info(chat_id, message_id): Get info about media in a message
  • send_file(chat_id, file_path, caption): Send a local file from allowed roots
  • download_media(chat_id, message_id, file_path): Save message media under allowed roots
  • upload_file(file_path): Upload a local file and return upload metadata
  • send_voice(chat_id, file_path): Send .ogg/.opus voice note from allowed roots
  • send_sticker(chat_id, file_path): Send .webp sticker from allowed roots
  • edit_chat_photo(chat_id, file_path): Update chat photo from allowed roots

Search & Discovery

  • search_public_chats(query, limit): Search public chats/channels/bots with a configurable result limit
  • search_messages(chat_id, query, limit): Search messages in a chat
  • search_global(query, page, page_size): Search messages globally with pagination
  • resolve_username(username): Resolve a username to ID

Stickers, GIFs, Bots

  • get_sticker_sets(): List sticker sets
  • get_bot_info(bot_username): Get info about a bot
  • set_bot_commands(bot_username, commands): Set bot commands (bot accounts only)

Privacy, Settings, and Misc

  • get_privacy_settings(): Get privacy settings
  • set_privacy_settings(key, allow_users, disallow_users): Set privacy settings
  • mute_chat(chat_id): Mute notifications
  • unmute_chat(chat_id): Unmute notifications
  • archive_chat(chat_id): Archive a chat
  • unarchive_chat(chat_id): Unarchive a chat
  • get_recent_actions(chat_id): Get recent admin actions

Drafts

  • save_draft(chat_id, message, reply_to_msg_id, no_webpage): Save a draft message to a chat/channel
  • get_drafts(): Get all draft messages across all chats
  • clear_draft(chat_id): Clear/delete a draft from a specific chat

Multi-Account

  • list_accounts(): List all configured accounts with profile info

All tools accept an optional account parameter to target a specific account. In multi-account mode:

  • Read-only tools (e.g., get_chats, list_messages) query all accounts when account is omitted, returning results prefixed with [label].
  • Write tools (e.g., send_message, mark_as_read) require an explicit account value.
  • Single-account setups work exactly as before โ€” the account parameter is optional everywhere.

Input Validation

To improve robustness, all functions accepting chat_id or user_id parameters now include input validation. You can use any of the following formats for these IDs:

  • Integer ID: The direct integer ID for a user, chat, or channel (e.g., 123456789 or -1001234567890).
  • String ID: The integer ID provided as a string (e.g., "123456789").
  • Username: The public username for a user or channel (e.g., "@username" or "username").

The server will automatically validate the input and convert it to the correct format before making a request to Telegram. If the input is invalid, a clear error message will be returned.

File-path Tools Security Model

File-path tools are available, but disabled by default until allowed roots are configured.

Supported file-path tools:

  • send_file, download_media, set_profile_photo, edit_chat_photo, send_voice, send_sticker, upload_file

Security semantics (aligned with MCP filesystem server):

  • Server-side allowlist via CLI positional arguments (fallback when Roots API is unsupported).
  • Client-provided MCP Roots replace the server allowlist when available.
  • If the client returns an empty Roots list, file-path tools are disabled (deny-all).
  • All paths are resolved via realpath and must stay inside an allowed root.
  • Traversal/glob-like patterns are rejected (.., *, ?, ~, etc.).
  • Relative paths resolve against the first allowed root.
  • Write tools default to <first_root>/downloads/ when file_path is omitted.

Example server launch with allowlisted roots:

uv --directory /full/path/to/telegram-mcp run main.py /data/telegram /tmp/telegram-mcp

GIF tools are currently limited: get_gif_search and send_gif are available, while get_saved_gifs is not implemented due to reliability limits in Telethon/Telegram API interactions.


๐Ÿ“‹ Requirements


๐Ÿ”ง Installation & Setup

1. Fork & Clone

git clone https://github.com/chigwell/telegram-mcp.git
cd telegram-mcp

2. Install Dependencies with uv

uv sync

3. Generate a Session String

uv run session_string_generator.py

Follow the prompts to authenticate. You'll be asked for an optional account label (e.g., work, personal) โ€” leave empty for a single-account setup.

4. Configure .env

Copy .env.example to .env and fill in your values.

Single account:

TELEGRAM_API_ID=your_api_id_here
TELEGRAM_API_HASH=your_api_hash_here
TELEGRAM_SESSION_STRING=your_session_string_here

Multiple accounts:

TELEGRAM_API_ID=your_api_id_here
TELEGRAM_API_HASH=your_api_hash_here
TELEGRAM_SESSION_STRING_WORK=session_string_for_work_account
TELEGRAM_SESSION_STRING_PERSONAL=session_string_for_personal_account

Add _<LABEL> suffix to TELEGRAM_SESSION_STRING for each account. Labels become account identifiers used in tool calls. A shared TELEGRAM_API_ID and TELEGRAM_API_HASH are used for all accounts.

Get your API credentials at my.telegram.org/apps.


๐Ÿณ Running with Docker

If you have Docker and Docker Compose installed, you can build and run the server in a container, simplifying dependency management.

1. Build the Image

From the project root directory, build the Docker image:

docker build -t telegram-mcp:latest .

2. Running the Container

You have two options:

Option A: Using Docker Compose (Recommended for Local Use)

This method uses the docker-compose.yml file and automatically reads your credentials from a .env file.

  1. Create .env File: Ensure you have a .env file in the project root containing your TELEGRAM_API_ID, TELEGRAM_API_HASH, and TELEGRAM_SESSION_STRING (or TELEGRAM_SESSION_NAME). Use .env.example as a template.
  2. Run Compose:
    docker compose up --build
    • Use docker compose up -d to run in detached mode (background).
    • Press Ctrl+C to stop the server.

Option B: Using docker run

You can run the container directly, passing credentials as environment variables.

docker run -it --rm \
  -e TELEGRAM_API_ID="YOUR_API_ID" \
  -e TELEGRAM_API_HASH="YOUR_API_HASH" \
  -e TELEGRAM_SESSION_STRING="YOUR_SESSION_STRING" \
  telegram-mcp:latest
  • Replace placeholders with your actual credentials.
  • For multiple accounts, use -e TELEGRAM_SESSION_STRING_WORK="..." -e TELEGRAM_SESSION_STRING_PERSONAL="..." instead.
  • Use -e TELEGRAM_SESSION_NAME=your_session_file_name instead of TELEGRAM_SESSION_STRING if you prefer file-based sessions (requires volume mounting, see docker-compose.yml for an example).
  • The -it flags are crucial for interacting with the server.

โš™๏ธ Configuration for Claude & Cursor

MCP Configuration

Edit your Claude desktop config (e.g. ~/Library/Application Support/Claude/claude_desktop_config.json) or Cursor config (~/.cursor/mcp.json):

{
  "mcpServers": {
    "telegram-mcp": {
      "command": "uv",
      "args": [
        "--directory",
        "/full/path/to/telegram-mcp",
        "run",
        "main.py"
      ]
    }
  }
}

๐Ÿ“ Tool Examples with Code & Output

Below are examples of the most commonly used tools with their implementation and sample output.

Getting Your Chats

@mcp.tool()
@with_account(readonly=True)
async def get_chats(account: str = None, page: int = 1, page_size: int = 20) -> str:
    """
    Get a paginated list of chats.
    Args:
        account: Account label (optional in single-account mode).
        page: Page number (1-indexed).
        page_size: Number of chats per page.
    """
    try:
        cl = get_client(account)
        dialogs = await cl.get_dialogs()
        ...

Example output (multi-account, no account specified):

[work]
Chat ID: -100987654321, Title: My Project Group
Chat ID: 111223344, Title: Jane Smith

[personal]
Chat ID: 123456789, Title: John Doe
Chat ID: -200123456789, Title: News Channel

Sending Messages

@mcp.tool()
@with_account(readonly=False)
async def send_message(chat_id: Union[int, str], message: str, account: str = None) -> str:
    """
    Send a message to a specific chat.
    Args:
        chat_id: The ID of the chat.
        message: The message content to send.
        account: Account label (required in multi-account mode).
    """
    try:
        cl = get_client(account)
        entity = await resolve_entity(chat_id, cl)
        await cl.send_message(entity, message)
        return "Message sent successfully."
    ...

Example output:

Message sent successfully.

Listing Inline Buttons

@mcp.tool()
@with_account(readonly=True)
async def list_inline_buttons(
    chat_id: Union[int, str],
    message_id: Optional[int] = None,
    limit: int = 20,
    account: str = None,
) -> str:
    """
    Discover inline keyboard layout, including button indices, callback availability, and URLs.
    """

Example usage:

list_inline_buttons(chat_id="@sample_tasks_bot")

This returns something like:

Buttons for message 42 (date 2025-01-01 12:00:00+00:00):
[0] text='๐Ÿ“‹ View tasks', callback=yes
[1] text='โ„น๏ธ Help', callback=yes
[2] text='๐ŸŒ Visit site', callback=no, url=https://example.org

Pressing Inline Buttons

@mcp.tool()
@with_account(readonly=False)
async def press_inline_button(
    chat_id: Union[int, str],
    message_id: Optional[int] = None,
    button_text: Optional[str] = None,
    button_index: Optional[int] = None,
    account: str = None,
) -> str:
    """
    Press an inline keyboard button by label or zero-based index.
    If message_id is omitted, the server searches recent messages for the latest inline keyboard.
    """

Example usage:

press_inline_button(chat_id="@sample_tasks_bot", button_text="๐Ÿ“‹ View tasks")

Use list_inline_buttons first if you need to inspect available buttonsโ€”pass a bogus button_text to quickly list options or call list_inline_buttons directly. Once you know the text or index, press_inline_button sends the callback, just like tapping the button in a native Telegram client.

Subscribing to Public Channels

@mcp.tool()
@with_account(readonly=False)
async def subscribe_public_channel(channel: Union[int, str], account: str = None) -> str:
    """
    Join a public channel or supergroup by username (e.g., "@examplechannel") or ID.
    """

Example usage:

subscribe_public_channel(channel="@daily_updates_feed")

If the account is already a participant, the tool reports that instead of failing, making it safe to run repeatedly in workflows that need idempotent joins.

Getting Chat Invite Links

The get_invite_link function is particularly robust with multiple fallback methods:

@mcp.tool()
@with_account(readonly=True)
async def get_invite_link(chat_id: int, account: str = None) -> str:
    """
    Get the invite link for a group or channel.
    """
    try:
        cl = get_client(account)
        entity = await resolve_entity(chat_id, cl)
        # Tries ExportChatInviteRequest, then export_chat_invite_link,
        # then GetFullChatRequest as fallbacks
        ...

Example output:

https://t.me/+AbCdEfGhIjKlMnOp

Joining Chats via Invite Links

@mcp.tool()
@with_account(readonly=False)
async def join_chat_by_link(link: str, account: str = None) -> str:
    """
    Join a chat by invite link.
    """
    try:
        cl = get_client(account)
        # Extracts hash, checks membership, and joins via ImportChatInviteRequest
        ...

Example output:

Successfully joined chat: Developer Community

Searching Public Chats

@mcp.tool()
@with_account(readonly=True)
async def search_public_chats(query: str, limit: int = 20, account: str = None) -> str:
    """
    Search for public chats, channels, or bots by username or title.
    """
    try:
        cl = get_client(account)
        result = await cl(functions.contacts.SearchRequest(q=query, limit=limit))
        entities = [format_entity(e) for e in result.chats + result.users]
        return json.dumps(entities, indent=2)
    ...

Example output:

[
  {
    "id": 123456789,
    "name": "TelegramBot",
    "type": "user",
    "username": "telegram_bot"
  },
  {
    "id": 987654321,
    "name": "Telegram News",
    "type": "user",
    "username": "telegram_news"
  }
]

Getting Direct Chats with Contacts

@mcp.tool()
@with_account(readonly=True)
async def get_direct_chat_by_contact(contact_query: str, account: str = None) -> str:
    """
    Find a direct chat with a specific contact by name, username, or phone.

    Args:
        contact_query: Name, username, or phone number to search for.
    """
    try:
        cl = get_client(account)
        result = await cl(functions.contacts.GetContactsRequest(hash=0))
        # Searches contacts, then matches against dialogs
        ...

Example output:

Chat ID: 123456789, Contact: John Smith, Username: @johnsmith, Unread: 3

๐ŸŽฎ Usage Examples

  • "Show my recent chats"
  • "Send 'Hello world' to chat 123456789"
  • "Add contact with phone +1234567890, name John Doe"
  • "Create a group 'Project Team' with users 111, 222, 333"
  • "Download the media from message 42 in chat 123456789"
  • "Mute notifications for chat 123456789"
  • "Promote user 111 to admin in group 123456789"
  • "Search for public channels about 'news'"
  • "Join the Telegram group with invite link https://t.me/+AbCdEfGhIjK"
  • "Send a sticker to my Saved Messages"
  • "Get all my sticker sets"

Multi-account examples:

  • "Show unread messages from all accounts"
  • "Reply to John from my work account: see you at 3pm"
  • "List my accounts"

You can use these tools via natural language in Claude, Cursor, or any MCP-compatible client.


๐Ÿง  Error Handling & Robustness

This implementation includes comprehensive error handling:

  • Multi-account support: Run multiple Telegram accounts simultaneously with label-based configuration
  • Session management: Works with both file-based and string-based sessions
  • Error reporting: Detailed errors logged to mcp_errors.log
  • Graceful degradation: Multiple fallback approaches for critical functions
  • User-friendly messages: Clear, actionable error messages instead of technical errors
  • Account type detection: Functions that require bot accounts detect and notify when used with user accounts
  • Invite link processing: Handles various link formats and already-member cases

The code is designed to be robust against common Telegram API issues and limitations.


๐Ÿ› ๏ธ Contribution Guide

  1. Fork this repo: chigwell/telegram-mcp
  2. Clone your fork:
    git clone https://github.com/<your-github-username>/telegram-mcp.git
  3. Create a new branch:
    git checkout -b my-feature
  4. Make your changes, add tests/docs if needed.
  5. Push and open a Pull Request to chigwell/telegram-mcp with a clear description.
  6. Tag @chigwell or @l1v0n1 in your PR for review.

๐Ÿ”’ Security Considerations

  • Never commit your .env or session string.
  • The session string gives full access to your Telegram accountโ€”keep it safe!
  • All processing is local; no data is sent anywhere except Telegram's API.
  • Use .env.example as a template and keep your actual .env file private.
  • Test files are automatically excluded in .gitignore.

๐Ÿ› ๏ธ Troubleshooting

  • Check logs in your MCP client (Claude/Cursor) and the terminal for errors.
  • Detailed error logs can be found in mcp_errors.log.
  • Interpreter errors? Make sure your .venv is created and selected.
  • Database lock? Use session string authentication, not file-based sessions.
  • iCloud/Dropbox issues? Move your project to a local path without spaces if you see odd errors.
  • Regenerate session string if you change your Telegram password or see auth errors.
  • Bot-only functions will show clear messages when used with regular user accounts.
  • Test script failures? Check test configuration in .env for valid test accounts/groups.

๐Ÿ“„ License

This project is licensed under the Apache 2.0 License.


๐Ÿ™ Acknowledgements


Maintained by @chigwell and @l1v0n1. PRs welcome!

Star History

Star History Chart

Contributors

About

Telegram MCP server powered by Telethon to let MCP clients read chats, manage groups, and send/modify messages, media, contacts, and settings.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages