Skip to main content
Glama
rixile9999

tdl-mcp

by rixile9999

tdl-mcp

CI npm License: MIT

Read-only Telegram access for Claude and other MCP hosts, powered by the tdl CLI.

List your chats, read recent messages, and download media β€” from your own Telegram account β€” with five simple tools. It never sends messages, never modifies anything, and never touches your login.

πŸ‡°πŸ‡· ν•œκ΅­μ–΄ λ¬Έμ„œλŠ” μ—¬κΈ° μžˆμŠ΅λ‹ˆλ‹€ β†’ README.ko.md

Why tdl-mcp?

Most Telegram MCP servers embed an MTProto library (Telethon, gramjs, …), ask you to create your own Telegram application at my.telegram.org to get an api_id/api_hash, and many of them can send messages on your behalf.

tdl-mcp takes a different, deliberately boring approach:

  • Read-only by design. The server can list chats, export messages and download files. That's all. There is no code path that sends, edits, deletes, or logs in.

  • No api_id/api_hash setup. Login is handled once, by you, in your terminal with tdl login -T qr β€” scan a QR code with your phone and you're done. No Telegram app registration needed.

  • Built on a battle-tested downloader. tdl (7.5k+ ⭐) does the heavy lifting: fast parallel downloads, resume, --skip-same deduplication.

  • Tiny and auditable. One plain-JavaScript file, two dependencies (@modelcontextprotocol/sdk, zod), no build step. You can read the whole server in five minutes.

Claude / MCP host  ←stdioβ†’  tdl-mcp (Node)  β†’subprocessβ†’  tdl CLI  β†’MTProtoβ†’  Telegram

Related MCP server: Telegram MCP Server

Quick start

1. Install tdl

# macOS
brew install telegram-downloader

# Linux / WSL
curl -sSL https://docs.iyear.me/tdl/install.sh | sudo bash

# Windows (PowerShell)
iwr -useb https://docs.iyear.me/tdl/install.ps1 | iex

Any version from the one pinned in .tdl-version upward should work β€” CI continuously tests against that pin (see Compatibility).

2. Log in to Telegram (once)

tdl login -T qr

Scan the QR code with the Telegram mobile app (Settings β†’ Devices β†’ Link Desktop Device). The session is stored in ~/.tdl on your machine and shared by every MCP host β€” you log in exactly once. tdl-mcp itself never performs or refreshes logins.

3. Add the server to your MCP host

You need Node.js β‰₯ 18.

Claude Code:

claude mcp add --scope user telegram -- npx -y tdl-mcp

Claude Desktop / any other MCP host (generic mcpServers JSON):

{
  "mcpServers": {
    "telegram": {
      "command": "npx",
      "args": ["-y", "tdl-mcp"]
    }
  }
}

4. Try it

Ask your assistant things like:

"What Telegram chats do I have? Find the one about quant trading."

"Show me the last 20 messages in @some_channel."

"Download every PDF posted in that channel since message 1500 to ~/Papers."

If a tool reports that you are not logged in, run tdl login -T qr in a terminal and retry β€” that's the only manual step there is.

Tools

Tool

Arguments

What it does

tg_status

β€”

Checks whether the tdl session is logged in. Never errors: returns {logged_in:true, chats:N} or {logged_in:false, hint}.

tg_chats

filter?

Lists dialogs as [{id, type, name, username}]; filter is a case-insensitive substring match on name/username/id.

tg_messages

chat, last_n? (default 50, max 500), since_id?, with_text? (default true)

Exports recent media messages from a chat as compact {id, date, file, text} objects (at most 200 returned; truncation is noted). since_id fetches only messages after a known id β€” handy for incremental reads.

tg_download

chat, since_id?, last_n? (default 100), extensions? (csv, e.g. "xlsx,pdf"), dest? (default ~/Downloads/telegram)

Downloads media from a chat with --skip-same; returns absolute paths of newly downloaded files, or a friendly "no matching files" note.

tg_download_url

urls (array of https://t.me/... links), extensions?, dest?

Downloads the media of specific messages by link. Validates every url starts with https://t.me/.

chat accepts either a numeric id or an @username/domain, exactly as shown by tg_chats.

Environment variables

Variable

Effect

TDL_BIN

Path to the tdl binary. Default: tdl on PATH, falling back to /opt/homebrew/bin/tdl (GUI-launched MCP hosts often don't inherit the Homebrew PATH).

TDL_NS

tdl namespace, passed as -n <ns> on every call. Use it to keep separate Telegram accounts/sessions apart.

Set them in your host's server config, e.g.:

{
  "mcpServers": {
    "telegram": {
      "command": "npx",
      "args": ["-y", "tdl-mcp"],
      "env": { "TDL_NS": "work" }
    }
  }
}

Compatibility & staying up to date

tdl-mcp shells out to the tdl CLI, so its real dependency is tdl's command-line surface. That surface is guarded automatically:

  • .tdl-version pins the tdl release this package is tested against.

  • scripts/contract.mjs verifies β€” without logging in β€” that every flag the server uses (chat ls -o json, chat export -c/-T/-i/-o/--with-content, dl -f/-u/-i/-d/--skip-same, global -n) still exists in that tdl binary. CI runs it on every push and PR.

  • A scheduled workflow watches tdl releases. When a new version appears it runs the contract test against the new binary and scans the release notes for breaking-change markers. Routine updates become a simple version-bump PR; anything suspicious is escalated to an AI-assisted upgrade PR that adapts the wrapper code.

So if you're on a newer tdl than the pin, chances are excellent everything just works β€” and if it ever wouldn't, this repo finds out before you do.

Development

git clone https://github.com/rixile9999/tdl-mcp.git
cd tdl-mcp
npm install
npm test          # smoke (MCP protocol, login-free) + contract (tdl CLI surface)
  • npm run smoke spawns the server over stdio and checks the tool catalog, tg_status shape, and input validation β€” passes whether or not you are logged in.

  • npm run contract checks the installed tdl binary against the CLI surface the server uses. scripts/install-tdl.sh [vX.Y.Z] installs a specific (checksum-verified) tdl release if you want to test against another version.

PRs welcome. Please keep the server read-only β€” tools that send, edit or delete are out of scope for this project.

Security notes

  • The tdl session in ~/.tdl is a full user-account credential β€” anyone who can read it can act as your Telegram account. Protect it like an SSH key: don't copy it into repos, shared backups, or other machines.

  • tdl-mcp never reads or transmits the session itself; it only runs the tdl binary locally. Nothing leaves your machine except tdl's own Telegram traffic.

  • Downloads go to a directory you choose (dest), defaulting to ~/Downloads/telegram.

Telegram terms-of-service note

tdl drives a regular user session (MTProto), not a bot. Quiet, read-only, personal-use automation of your own account is generally tolerated, but aggressive crawling can get an account limited: keep ranges modest (last_n, since_id), avoid large parallel pulls, and let --skip-same do its job instead of re-downloading.

License

MIT for everything in this repository.

tdl itself is a separate project licensed under AGPL-3.0. tdl-mcp does not bundle, link, or modify tdl β€” it invokes the binary you installed as a separate process, so the AGPL applies to tdl, not to this wrapper. You install tdl yourself through official channels (step 1 above).

Available Tools

5 tools
tg_chatsList Telegram chatsA

List the Telegram dialogs (chats/channels/groups/users) visible to the logged-in session, as [{id, type, name, username}]. Use it to find the chat id or @username to pass as chat to tg_messages / tg_download. Optional filter does a case-insensitive substring match on name/username/id.

ParametersJSON Schema
NameRequiredDescriptionDefault
filterNoCase-insensitive substring to match against chat name, username or id

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided, so description bears full burden. Discloses output format and that it lists dialogs visible to the logged-in session. No mention of destructive actions, appropriate for a read-only tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with core purpose and output, second sentence adds usage and parameter detail. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a simple list tool with one optional parameter and no output schema, the description covers all necessary aspects: purpose, output format, usage, and parameter behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% (one parameter fully described in schema). Description restates the filter purpose: 'case-insensitive substring match on name/username/id.' Adds minimal value beyond schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states it lists Telegram dialogs visible to the session and specifies output format. Distinguishes from sibling tools like tg_messages and tg_download by clarifying its role in finding chat IDs or usernames for use with those tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells when to use: to find chat id or @username for tg_messages/tg_download. Mentions optional filter for matching. Lacks explicit when-not-to-use statements, but context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tg_downloadDownload Telegram media from a chatA

Download media files from one chat (by id or @username) to a local directory and return the absolute paths of newly downloaded files. Use extensions (csv, e.g. 'xlsx,pdf') to fetch only certain file types; since_id for 'everything new after message X'; last_n for 'the latest N media messages' (default 100). Already-present files are skipped (--skip-same).

ParametersJSON Schema
NameRequiredDescriptionDefault
chatYesChat id or @username/domain (as shown by tg_chats)
destNoDestination directory (default ~/Downloads/telegram)
last_nNoHow many recent media messages to consider (default 100)
since_idNoOnly messages with id > since_id (overrides last_n)
extensionsNoComma-separated file extensions to include, e.g. 'xlsx,pdf'

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full disclosure burden. It explains the tool returns absolute paths of newly downloaded files and skips already-present files (--skip-same). This addresses key behaviors, though it omits permissions, rate limits, or error handling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences: first states the core action and return value, second gives parameter usage hints. It is front-loaded, concise, and every sentence adds necessary information without waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 5 parameters, no output schema, and no annotations, the description covers the main purpose, return value, parameter behaviors, and skip-same behavior. It does not address prerequisites (e.g., authentication) or error scenarios, but it is largely complete for typical use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The description adds value beyond schema: provides examples for extensions ('xlsx,pdf'), explains since_id as 'everything new after message X', and clarifies last_n as 'latest N media messages' with default 100. This enriches parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool downloads media files from a single chat to a local directory and returns paths of newly downloaded files. It specifies the resource (media files from one chat) and the action (download), distinguishing it from siblings like tg_download_url (URL downloads) and tg_chats (chat listing).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides usage guidance for parameters (extensions, since_id, last_n) and notes default behavior (last_n default 100) and skip-same behavior. However, it does not explicitly state when to choose this tool over siblings (e.g., tg_download_url for URL downloads, tg_messages for text), limiting differentiation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tg_download_urlDownload Telegram media by t.me linkA

Download the media of specific Telegram messages given their t.me links (e.g. https://t.me/channel/123) and return the absolute paths of newly downloaded files. Use when you already have message links rather than a chat to scan. Already-present files are skipped (--skip-same).

ParametersJSON Schema
NameRequiredDescriptionDefault
destNoDestination directory (default ~/Downloads/telegram)
urlsYesTelegram message links; each must start with https://t.me/
extensionsNoComma-separated file extensions to include, e.g. 'xlsx,pdf'

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It discloses a key behavior: 'Already-present files are skipped (--skip-same).' It also states it returns absolute paths of newly downloaded files. This is adequate for a download tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with purpose and usage. It is concise and informative, with no wasted words. The behavioral note about skipping existing files is well integrated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 3 parameters with full schema coverage and no output schema, the description sufficiently explains purpose, when to use, and a behavioral note. It is complete for this straightforward tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers all 3 parameters with descriptions (100% coverage). The description adds no additional parameter meaning beyond what the schema provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Download the media of specific Telegram messages given their t.me links' with an example URL. It distinguishes itself from sibling tools like tg_download by specifying it uses direct links rather than scanning a chat.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Use when you already have message links rather than a chat to scan,' providing clear context for when to use this tool. While it doesn't explicitly state when not to use it, the guidance is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tg_messagesRead recent Telegram messagesA

Export recent media messages from one chat (by id or @username) and return them as compact {id, date, file, text} objects β€” newest range exported via tdl. Use last_n for 'the last N media messages', or since_id to fetch only messages after a known message id (incremental reads). Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault
chatYesChat id or @username/domain (as shown by tg_chats)
last_nNoHow many recent media messages to export (default 50, max 500)
since_idNoOnly messages with id > since_id (overrides last_n; for incremental reads)
with_textNoInclude message text content (default true)

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must fully disclose behavior. It states read-only and mentions the output format and parameter overrides (since_id overrides last_n). However, it does not disclose potential rate limits, auth requirements, or what happens if no media messages are found.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise, consisting of two functional sentences plus a standalone 'Read-only.' It is front-loaded with the main action and every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description adequately explains the return format and the two primary use cases. It does not define 'media messages' or mention error handling, but it is otherwise complete for a read-only tool with clear parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, baseline 3. The description adds valuable context beyond the schema: explains the difference between last_n and since_id, notes that since_id overrides last_n, and describes the output format compact objects. It also implies the chat parameter can be id or @username, matching the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool exports recent media messages from a single chat, using a specific verb ('Export') and resource ('recent media messages from one chat'). It distinguishes from siblings like tg_chats (which lists chats) and tg_download (which downloads files).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly explains when to use last_n vs since_id (incremental reads). It says 'Read-only' but does not specify when not to use this tool or mention alternatives like tg_download or tg_status for other operations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tg_statusTelegram session statusA

Check whether the local tdl Telegram session is logged in and usable. Call this first if another tg_* tool fails or before starting Telegram work. Never errors β€” returns {logged_in:false, hint} when the session is missing.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Without annotations, the description carries full burden. It discloses that the tool never errors and returns {logged_in:false, hint} when missing, covering error handling and output format. However, it omits details about side effects or performance, but these are minimal for a status check.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no wasted words. The first sentence states purpose, the second adds usage guidance and behavior. Front-loaded and efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no parameters, no output schema, and low complexity, the description covers purpose, usage, and behavior. It lacks explanation of what 'hint' contains or what 'usable' means, but these are minor gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist, so schema coverage is 100% and the description need not add parameter info. Baseline 4 is appropriate as the description adds no parameter details but doesn't need to.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Check') and resource ('local tdl Telegram session'), clearly stating its function to verify login status. It distinguishes itself from siblings by being a diagnostic tool to call before other tg_* tools, though not explicitly mentioning what it doesn't do.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly advises calling this tool first if another tg_* tool fails or before starting Telegram work, providing clear context for when to use it. No alternatives are needed given its singular purpose.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv1.0.0
    • First observedtg_chats
    • First observedtg_download
    • First observedtg_download_url
    • First observedtg_messages
    • First observedtg_status

TDQS

A4.2/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: listing chats, downloading media by chat, downloading media by URL, exporting message metadata, and checking session status. The two download tools are differentiated by source (chat vs. message links), and tg_messages returns metadata, not files, avoiding overlap.

Naming Consistency3/5

All tools share the 'tg_' prefix, but the naming pattern is inconsistent: some use nouns (tg_chats, tg_messages, tg_status) and others use verbs (tg_download, tg_download_url). This mix could be confusing; a consistent verb_noun pattern would improve predictability.

Tool Count5/5

With 5 tools, the server covers the core functionality of a Telegram media downloader (chat discovery, message inspection, two download methods, and status check) without unnecessary duplication or missing essentials.

Completeness4/5

The tool surface covers the main workflow: find chats, list messages, download media, and verify session. Minor gaps exist, such as the lack of date-range filtering or a direct login/logout tool, but these are not critical for common use cases.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A read-only Telegram MCP server that retrieves messages from your DMs, groups, and channels, enabling Claude to generate executive briefings from Telegram conversations.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A Telegram integration for Claude, Cursor, and other MCP-compatible clients. It exposes Telegram account, chat, message, contact, media, folder, and admin operations through the Model Context Protocol using Telethon.
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    A Telegram integration for Claude, Cursor, and other MCP-compatible clients. It exposes over 80 tools for account, chat, message, contact, media, folder, and admin operations through the Model Context Protocol.
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants like Claude to read, search, and send messages through your personal Telegram account via MCP tools.
    MIT