Skip to main content
Glama
thenavidm

telegram-mcp-cli

by thenavidm

Telegram MCP Server & CLI

npm License YouTube X LinkedIn

Telegram MCP server and CLI for Claude Code, Codex and AI agents. 74 tools for chats, history, search, sending, media, contacts, groups, admin, topics, reactions, polls, folders and privacy, on your real account.

One install gives you both surfaces, the same tools under the same names, covering what the app does rather than what a bot is allowed to see.

Most Telegram integrations are bots, and a bot only ever receives messages sent to that bot. Your own conversations are invisible to it. This signs in as you over MTProto, so an agent can read the group you were actually talking in and answer in it.

Built and maintained by Navid Moazzez.

Two ways to use it

Command line

telegram-cli in your terminal, for scripting, cron, pipes, or just asking a quick question without opening anything:

telegram-cli                                       # every command, one line each
telegram-cli list-chats --unread-only --limit 10   # what needs an answer
telegram-cli history --peer @sarah --limit 20      # one conversation
telegram-cli search --query invoice                # across every chat
telegram-cli send --peer me --text "note to self"  # Saved Messages
telegram-cli list-chats --json | jq -r '.items[].name'
telegram-cli which search my messages             # find the command for a task
telegram-cli <command> --help                      # what any command takes

--confirm is the shell spelling of the confirmation that deleting requires. --json gives JSON, --compact puts it on one line, --agent turns on both with no prompts and no color, and errors are JSON on stderr whichever you pick. Built on Slipway, which turns one definition of each tool into the MCP server and the CLI.

Reads return real objects rather than rendered text, so --json hands you fields you can filter, and --fields id,text cuts the response before it is ever printed.

MCP server, for AI agents

telegram-mcp is what Claude Code, Claude Desktop, Cursor and the rest launch. You never run it by hand:

claude mcp add telegram \
  -e TELEGRAM_API_ID=1234567 \
  -e TELEGRAM_API_HASH=your_hash \
  -e TELEGRAM_SESSION=your_session_string \
  -- npx -y @thenavidm/telegram-mcp-cli

Then just ask: "what did I miss in the group chats while I was asleep?"

Every other client is in section 4.

Which one

Where you are

What you can reach

An agent that can run shell commands, like Claude Code or Cursor

Both. The CLI is the cheaper one: nothing until it runs

claude.ai, the Claude Desktop chat tab, or a phone

The server only. There is no shell to run a command in

A terminal, a script, cron or CI

The CLI only. There is no MCP client in a shell

They are the same program reading the same tool definitions, so anything one can do, the other can.

Related MCP server: Telegram MCP Server

Features

74 tools. Every one is both a shell command and an MCP tool, under the same name; the command is the tool name with dashes.

These 13 are what the server loads by default, because they cover daily use:

Capability

CLI command

MCP tool

Who am I

telegram-cli whoami

whoami

Resolve a handle or id

telegram-cli resolve

resolve

List chats

telegram-cli list-chats

list_chats

One chat's details

telegram-cli get-chat

get_chat

Read history

telegram-cli history

history

Search messages

telegram-cli search

search

Send a message

telegram-cli send

send

Edit a message

telegram-cli edit

edit

Delete messages

telegram-cli delete

delete

Forward messages

telegram-cli forward

forward

Mark a chat read

telegram-cli mark-read

mark_read

Download media

telegram-cli download-media

download_media

Send a file

telegram-cli send-file

send_file

Check your setup

telegram-cli doctor

not a tool

Sign in once

telegram-mcp login

not a tool

The other 61 cover contacts and blocking, groups and admin, reactions, pins, polls and scheduling, archiving, muting and drafts, chat folders, stickers, albums and voice notes, forum topics, inline buttons, your own profile and your privacy settings. They are always there in the CLI. TELEGRAM_TOOLS=full loads them into the server as well, and section 6 says what that costs.

All 74 are in section 7.

Contents

Section

1

What you can ask it

Real prompts, not features

2

Quick install

Node 20 and one command

3

Set up your account

api_id, api_hash, session string

4

Connect your client

Every client, copy and paste

5

Output and exit codes

What scripts branch on

6

Which surface, and what each costs

Measured in Claude Code, and how to spend less

7

Tools

All 74, grouped, with the default 13 in full

8

Writing safely

Why deleting asks twice

9

Reading messages

The output format, and why

10

How it works

Architecture

11

Your data

What is stored and where

12

Risks

Read this before you install

13

Troubleshooting

When something breaks

14

FAQ

Including what an MCP server is

1. What you can ask it

Real prompts, not a feature list. Each of these is one or two tool calls.

What did I miss in the group chats while I was asleep?

Find the last thing Sarah sent me about the invoice and reply that I will look at it tonight.

Search every chat for the wifi password someone sent me last year.

Which conversations have unread messages, and which actually need an answer rather than an emoji?

Save the PDF that Tom sent me this morning to my desktop.

Send myself a note in Saved Messages with these three links.

The reading tools are the ones worth having on. Searching a decade of chat for a thing you half remember is what this is genuinely better at than scrolling.

2. Quick install ⚡

Node 20 or newer. Nothing else.

npx -y @thenavidm/telegram-mcp-cli@latest --version

That is the whole install. npx fetches it on demand, so there is nothing to update later. Prefer it on your $PATH?

npm install -g @thenavidm/telegram-mcp-cli

Installing needs no account. Only signing in does, which is the next section.

Before you start

You need

Check with

If missing

Node 20 or newer

node -v

nodejs.org

A Telegram account

Open the app

Any account works, no Premium needed

A phone you can receive a code on

The code arrives in the Telegram app, not by SMS

IMPORTANT

You need an api_id frommy.telegram.org, not a bot token from BotFather. A bot cannot read your chats, which is the entire point of this. Section 3 walks through it.

3. Set up your account 🔑

Three values. The first two identify the application, the third is you.

The api_id and api_hash

Go to my.telegram.org, sign in with your phone number, open API development tools, and fill in the short form. Any app name and a short description are fine. You get an api_id and an api_hash.

These identify the software, not you, and they are not especially secret. They cannot read anything on their own.

The session string

export TELEGRAM_API_ID=1234567
export TELEGRAM_API_HASH=your_hash_here
npx -y @thenavidm/telegram-mcp-cli login

It asks for your phone number, the code Telegram sends you, and your two-step password if you have one. It prints the session string on stdout and everything else on stderr, so telegram-mcp login > session.txt captures only the string.

export TELEGRAM_SESSION='the string it printed'

What that string is

Full access to your account, and it does not expire. It is not a token scoped to some permissions, it is your login. Anyone holding it can read every message you have and send as you.

Keep it out of repos. Put it in your MCP client's config, which is a file only you can read, rather than in a shell profile that gets committed by accident.

Revoking

Telegram, Settings → Devices. The session shows up as a logged-in device and terminating it invalidates the string immediately. Do that if it leaks, or whenever you stop using this, then run login again if you come back.

4. Connect your client 🔌

npm install -g @thenavidm/telegram-mcp-cli

Or run it without installing anything:

npx -y @thenavidm/telegram-mcp-cli

Node 20 or newer.

Claude Code

claude mcp add telegram \
  -e TELEGRAM_API_ID=1234567 \
  -e TELEGRAM_API_HASH=your_hash \
  -e TELEGRAM_SESSION=your_session_string \
  -- npx -y @thenavidm/telegram-mcp-cli

Claude Desktop

The short way: download the .mcpb extension from the latest release and double-click it. It carries its own dependencies, so there is no config file to edit and nothing to install first. It asks for your API ID, API hash and session string in a form, and stores them as sensitive fields rather than plain text in a config file.

The long way, if you would rather edit the config yourself:

Settings → Developer → Edit Config, then add:

{
  "mcpServers": {
    "telegram": {
      "command": "npx",
      "args": ["-y", "@thenavidm/telegram-mcp-cli"],
      "env": {
        "TELEGRAM_API_ID": "1234567",
        "TELEGRAM_API_HASH": "your_hash",
        "TELEGRAM_SESSION": "your_session_string"
      }
    }
  }
}

Restart Claude Desktop afterwards.

Cursor

Settings → MCP → Add new global MCP server, using the same JSON as Claude Desktop.

Windsurf

Settings → Cascade → Model Context Protocol, same JSON shape.

VS Code

code --add-mcp '{"name":"telegram","command":"npx","args":["-y","@thenavidm/telegram-mcp-cli"]}'

Then set the three environment variables in your shell profile, or add an env block to the entry.

Anything else

Any client that speaks MCP over stdio. The command is npx -y @thenavidm/telegram-mcp-cli with the three variables in the environment.

Docker

docker build -t telegram-mcp .
docker run --rm -i \
  -e TELEGRAM_API_ID -e TELEGRAM_API_HASH -e TELEGRAM_SESSION \
  telegram-mcp

Check it worked

telegram-cli doctor

It names any missing variable, says where to get it, and signs in to confirm the session actually works rather than only that it is present.

5. Output and exit codes

What gets printed

Reads return objects. A list comes back as {count, next_cursor, items}, so paging is a field rather than something you infer.

telegram-cli list-chats --limit 3 --fields name,unread
{
  "count": 3,
  "items": [
    { "name": "Sarah", "unread": 2 },
    { "name": "Design", "unread": 14 },
    { "name": "Mum", "unread": 1 }
  ]
}

Errors are JSON on stderr, with the code and often a hint:

{
  "error": "Telegram rate limited this account. Wait 42s.",
  "code": "RATE_LIMIT",
  "retryAfter": 42,
  "hint": "Flood waits are per method and get longer if you keep calling. Wait it out."
}

Exit codes

A script branches on the number.

Code

Means

0

Fine

1

Something unexpected went wrong

2

Bad usage, or a write refused for want of --confirm

3

No such chat, user or message

4

The session is invalid or expired

5

Telegram rejected the call, or forbade it

7

Rate limited, retry_after_seconds says how long

10

Nothing configured yet

6. Which surface, and what each costs

Both surfaces are the same program with the same 13 tools. The difference is when the model pays for them. Measured in Claude Code:

MCP server

CLI

Every message, with every tool loaded

2,400 tokens

nothing

Every message, Claude Code's default

130 tokens

nothing

When Telegram comes up

nothing more, or the tools it picks

2,300 tokens for SKILL.md, once

20 messages with Telegram in 1, every tool loaded

48,000 tokens

2,300 tokens

Claude Code's tool search is on by default: it sends only the tool names and the server instructions, and loads a tool's full definition when the model reaches for it. An app that loads every tool up front pays the first line on every message, whether Telegram comes up or not. With the skill added, Claude Code also lists its one-line description, about 130 tokens.

To spend less, turn the server off when you are not using it, which in Claude Code is the /mcp panel. TELEGRAM_READ_ONLY=1 takes the six write tools off the list, leaving seven. These numbers are the default profile's 13 tools; TELEGRAM_TOOLS=full lists all 74 and costs more. Or install the CLI and add the server on the days it earns its place.

Measured on 2026-10-05 against 0.4.4, with Claude Code 2.1.286 on Claude Opus 5.5 (one short prompt with and without the server connected, once with ENABLE_TOOL_SEARCH=false and once with the default, the difference read from the API's own usage figures; SKILL.md the same way) and Codex 0.159.3 on gpt-6.1-sol, with a placeholder session that cannot connect:

Cost

0.4.4

0.5.0

Claude Code, the 13 daily tools loaded, every message

2,820

2,380

Claude Code, all 74 loaded (TELEGRAM_TOOLS=full), every message

14,438

11,868

Claude Code's default, tool search, every message (median of nine runs)

123

124

SKILL.md, read once

2,581

2,293

Codex over the CLI, one task, median of five

72,800

53,221

Codex over MCP, the same task, median of five

35,380

35,372

The task was "find the command that searches message text across every chat, and the flags it requires". Other apps and models count tokens a little differently, and tool-list characters divided by four are not API usage.

7. Tools

74 tools. Each is also a shell command under the same name with dashes, so list_chats runs as telegram-cli list-chats.

The 13 in the default set are documented here with their arguments, because they are what the server loads unless you tell it otherwise. The other 61 are listed by name only. Arguments move, and a hand-typed list of 74 signatures goes stale the day a tool is added, so ask the binary instead:

telegram-cli                    # all 74, one line each, writes marked
telegram-cli <command> --help   # its arguments, derived from the schema
telegram-cli schema <command>   # the JSON Schema an MCP client receives

Two things hold across all of them. Every list tool takes fields for projection and a limit that is clamped rather than trusted. Writes are marked *, and the irreversible ones are marked ! and refuse to run without confirmation. Those are the same marks the bare command prints.

peer is the same everywhere: a @username, a numeric id, or me for Saved Messages.

The default 13

What TELEGRAM_TOOLS=core advertises, which is the default: about 2,400 tokens a message in an app that loads every tool, measured in Claude Code.

Account

Tool

Arguments

What it does

whoami

none

Which account this session is signed in as

resolve

peer

A @username, phone or id to something you can act on

Chats

Tool

Arguments

What it does

list_chats

limit, unread_only, kind, fields

Recent conversations, newest first

get_chat

peer

One chat: name, kind, username, member count

Reading

Tool

Arguments

What it does

history

peer, limit, before_id, full, fields

Messages from one chat, newest first

search

query, peer, limit, fields

Search text in one chat or everywhere

download_media

peer, message_id, dir

Save a photo, video, document or voice note

Writing

Tool

Arguments

What it does

send *

peer, text, reply_to, silent

Send a message. Posts as you

send_file *

peer, path, caption

Send a local file

edit *

peer, message_id, text

Change a message you sent

forward *

from, to, message_ids

Forward between chats

mark_read *

peer

Clear a chat's unread count

delete !

peer, message_ids, revoke, confirm

Delete messages. Cannot be undone

The other 61

Always reachable from the CLI, where an unused command costs nothing. TELEGRAM_TOOLS=full loads them into the server too, at about 11,900 tokens a message in an app that loads every tool. See section 6 before you do.

Contacts and people

Tool

What it does

list_contacts

List contacts

search_contacts

Search contacts and users

get_user

Get a user's profile

list_blocked

List blocked users

add_contact *

Add a contact

block *

Block someone

unblock *

Unblock someone

delete_contact !

Remove a contact

Groups, channels and admin

Tool

What it does

get_participants

List members of a chat

get_full_chat

Full details of a chat

create_group *

Create a group or channel

join_chat *

Join a chat

invite_to_chat *

Add people to a chat

invite_link *

Get or create an invite link

set_admin *

Promote or demote an admin

edit_chat *

Change a chat's title or description

leave_chat !

Leave a chat

set_banned !

Ban or unban someone

Reactions, pins, polls and scheduling

Tool

What it does

get_pinned

List pinned messages

get_reactions

Who reacted to a message

get_scheduled

List scheduled messages

message_link

Get a link to a message

pin *

Pin or unpin a message

react *

React to a message

create_poll *

Send a poll

delete_scheduled !

Cancel scheduled messages

Organizing your chat list

Tool

What it does

common_chats

Chats you share with someone

search_public

Search public chats

list_drafts

List unsent drafts

archive *

Archive or unarchive a chat

mute *

Mute or unmute a chat

save_draft *

Save or clear a draft

delete_history !

Delete a chat's history

Chat folders

Tool

What it does

list_folders

List chat folders

get_folder

One folder's contents

create_folder *

Create a chat folder

update_folder *

Rename a folder or change what is in it

reorder_folders *

Reorder chat folders

delete_folder !

Delete a chat folder

More media

Tool

What it does

list_sticker_sets

List your sticker sets

search_gifs

Search GIFs

media_info

Describe a message's media

transcribe_voice

Transcribe a voice message

send_sticker *

Send a sticker or GIF

send_album *

Send several photos as one album

send_contact *

Share a contact card

send_voice *

Send a voice note

Forum topics and inline buttons

Tool

What it does

list_topics

List forum topics

list_buttons

List a message's inline buttons

create_topic *

Create a forum topic

edit_topic *

Rename, close or reopen a topic

enable_topics *

Turn forum topics on or off

press_button *

Press an inline button

Your profile and privacy

Tool

What it does

list_profile_photos

List profile photos

get_privacy

Read your privacy settings

export_contacts

Export every contact

update_profile *

Update your profile

set_profile_photo *

Set your profile photo

set_privacy *

Change a privacy setting

import_contacts *

Import contacts in bulk

delete_profile_photo !

Delete your current profile photo

8. Writing safely

Writes are on, and guarded. Shipping no writes is not safety, it just moves the work back to you. Shipping them unguarded is worse, because send posts as you to a real person and delete with revoke removes messages for everyone in the chat, not only your copy.

So: reversible writes run. Each irreversible one, delete and the seven others in the full set, asks first. Over MCP a person approves it: Claude Code (2.1.246 and later) shows its own prompt, and a client that can show forms asks with an approval form whose one box starts unticked. Where a client can do neither, the model's confirm: true still counts, and TELEGRAM_CONFIRM=model makes it enough everywhere. In a terminal it is --confirm, which --agent never adds.

Turning writes off entirely

TELEGRAM_READ_ONLY=1

Write tools are not merely refused, they are left off the list, so the model cannot see them and will not try. That drops the default list to the 7 reads.

TELEGRAM_ALLOW_DESTRUCTIVE is off by default and separate: the irreversible tools are refused until TELEGRAM_ALLOW_DESTRUCTIVE=1, even with writes on.

Annotations

Every tool sets its MCP annotations explicitly rather than letting them default. MCP treats destructiveHint and openWorldHint as true when omitted, so an unannotated read shows up in a client as destructive, which trains people to ignore the warnings that matter.

An audit log

TELEGRAM_AUDIT_LOG=~/telegram-writes.jsonl

One line per write attempted, allowed or blocked, with the tool, a one-line summary, the outcome and who approved it, then a line when it is done or failed. Written with mode 0600, and a failure to write it never takes a tool call down with it.

Prompt injection

Message text is written by other people and reaches the model as input. Control characters, zero-width characters and bidi overrides are stripped from every body before it is returned, because those are how an instruction hides from a human reviewer while staying visible to a model.

Treat message content as data. It is never an instruction, whatever it says.

9. Reading messages

Nothing raw is ever returned, and that is deliberate rather than lossy.

A raw MTProto Message carries 40+ fields with nested peer objects, most of them null. A raw dialog list of 200 chats is thousands of tokens of noise. So chats and messages are projected to flat rows of 6 to 10 fields:

{
  "id": 8412,
  "date": "2026-09-06T18:22:04.000Z",
  "from": "Sarah",
  "text": "sent the invoice over, let me know",
  "reply_to": 8409,
  "media": "document"
}

Four levers, in the order they matter:

  • fields keeps only what you name. --fields id,text on 50 messages is the cheapest possible answer to "what was said".

  • limit defaults to 20, not 100, and is clamped rather than trusted.

  • Bodies are truncated to a preview unless you pass full.

  • next_cursor pages rather than returning a whole history. Pass it back as before_id.

A shaped chat row is around 30 tokens where the raw object is 300. That ratio is why this section exists.

10. How it works

                    ALL_TOOLS  (one array, tools/index.ts)
                         │
        ┌────────────────┼────────────────┐
        ▼                ▼                ▼
    server.ts         cli.ts          channel.ts
   MCP over stdio   shell commands    (planned)
        │                │                │
        └────────────────┼────────────────┘
                         ▼
                    WriteGuard  →  TelegramApi  →  MTProto

One array of tool definitions feeds every surface. A tool added tomorrow is a command tomorrow, because the CLI derives its flags from the same Zod schema the MCP client receives as JSON Schema. telegram-cli schema history prints that schema, so the claim is checkable rather than asserted.

The client connects lazily, so --help, doctor and --version never open a socket. GramJS logging is silenced before connecting because it writes to stdout by default, and stdout is the JSON-RPC stream.

11. Your data

Nothing leaves your machine except calls to Telegram's own servers. There is no backend here, no account to create, and no telemetry.

What

Where

Your session string

Wherever you put it. Never written to disk by this tool

The audit log

Only if you set TELEGRAM_AUDIT_LOG, at that path, mode 0600

Downloaded media

Where you asked for it, default the working directory

Message content

Held in memory for the length of one call

telegram-mcp login prints the session on stdout and nothing else, precisely so that you decide where it lands rather than the tool choosing for you.

12. Risks

Worth reading before you install, not after.

The session string is your account. Not a scoped token. If it leaks, whoever has it can read everything and send as you, until you revoke it under Settings → Devices.

An agent with this connected can message real people. That is the point, and it is also the risk. TELEGRAM_READ_ONLY=1 exists for when you are pointing something you do not fully trust at it.

Message text is untrusted input. Sanitising helps and is not a guarantee. Anything you would not want a model to act on unquestioned should not be in a chat it can read.

Telegram rate limits hard. FLOOD_WAIT on a new session is normal, the waits get longer if you keep calling, and an automated retry loop can get an account limited for hours. The error carries retryAfter so a caller can wait the right amount instead of guessing.

Automating a user account is not what a bot account is. Telegram's terms allow user clients, but bulk or spammy behaviour through one is what gets accounts limited. This is built for reading your own chats and answering them.

13. Troubleshooting

Symptom

Cause and fix

not_configured, exit 10

One of the three variables is missing. telegram-cli doctor names it

auth, exit 4

Session revoked or expired. Run login again

rate_limited, exit 7

Flood wait. retry_after_seconds says how long. Wait, do not retry

not_found on a peer

Use resolve or list_chats to get a valid id first

The server starts then exits

Usually a bad session string. doctor connects and will say so

Garbled JSON-RPC in a client

Something is writing to stdout. Open an issue with the client name

delete refuses

By design. TELEGRAM_ALLOW_DESTRUCTIVE=1, then a person's approval or --confirm

Environment variables

Credentials

Variable

What it is

TELEGRAM_API_ID

From my.telegram.org, API development tools

TELEGRAM_API_HASH

Issued with the api_id, same page

TELEGRAM_SESSION

From telegram-mcp login. Full account access

Safety

Variable

What it does

TELEGRAM_READ_ONLY=1

Leaves every write off the list, so the model cannot see one

TELEGRAM_ALLOW_DESTRUCTIVE=1

Permits the irreversible tools at all. Off by default

TELEGRAM_CONFIRM=model

Lets confirm: true alone approve an irreversible call over MCP, for an agent with no person to ask

TELEGRAM_AUDIT_LOG

Append-only record of every write attempted, allowed or blocked

Tuning

Variable

What it does

TELEGRAM_TOOLS

core (default), full, or read. Decides context cost

TELEGRAM_TOOLSETS

The same choice by module, comma separated: core, account, chats, messages, media, contacts, groups, engage, organize, profile, topics, stickers, folders, or all. Unlike TELEGRAM_TOOLS, it narrows the CLI too

TELEGRAM_SURFACE

search lists three tools that find, describe and run the rest

TELEGRAM_TIMEOUT

Per-call deadline in seconds, default 30

TELEGRAM_TOOL_TIMEOUT_MS

Give up on any tool after this long

TELEGRAM_DEBUG

1 prints debug lines on stderr

Several accounts

Variable

What it does

TELEGRAM_SESSION_<LABEL>

A second account, for example TELEGRAM_SESSION_WORK. Read and kept as a secret, but no tool chooses between accounts yet

0.4's docs said every account-scoped tool took an optional account; none did. Run one server per account until one does.

Pushing messages into a session

Variable

What it does

TELEGRAM_CHANNEL_ALLOW

Allowlist path for --channel, default ~/.telegram-mcp/channel-allow.json

telegram-mcp --channel

Runs as a Claude Code channel, pushing real Telegram messages into a session that is already open. It declares claude/channel under the experimental capabilities, where Claude Code looks for it, and tells the model to reply with the reply tool and the chat_id from the event. A channel you build yourself is not on Claude Code's allowlist, so start Claude Code with --dangerously-load-development-channels server:<the name in your MCP config>. The official Telegram channel is a bot, so it only sees messages sent to that bot. This one is backed by your account, so an event can come from any chat you are actually in.

Nothing is forwarded until you allow a chat, which the allow_chat tool does. That default matters: without it every message in every group you are in becomes model input, which is both expensive and a prompt-injection surface.

Each allowed chat can carry a persona name, and it arrives on the event as persona, so one session can answer as a different assistant depending on which chat the message came from.

Running it always on

Variable

What it does

TELEGRAM_HTTP_PORT

Port for --http, default 8787

TELEGRAM_HTTP_HOST

Interface for --http, default 127.0.0.1

TELEGRAM_HTTP_TOKEN

Bearer token required on every HTTP request

TELEGRAM_HTTP_ALLOWED_ORIGINS

Comma-separated browser origins allowed to call --http; a page from any other site is refused

telegram-mcp --http --port=8787

Binds to loopback, because a process holding a session string should not be reachable from the network, and refuses to bind anywhere else without TELEGRAM_HTTP_TOKEN, which would hand your account to anyone who can route to the port.

Running it 24/7

For claude.ai, your phone, or the channel, the server has to be reachable when the call happens. deploy/install.sh sets that up on a Linux box:

sudo bash deploy/install.sh
sudo nano /etc/telegram-mcp.env
sudo systemctl start telegram-mcp

Own user, own directory, port 8788 bound to loopback only, systemd unit that restarts on failure and starts on boot. Put your reverse proxy in front of 127.0.0.1:8788.

telegram-mcp login runs on your laptop, not the server: it asks for a phone code interactively. Paste the session string into the env file.

Worth knowing: a Telegram session does not expire and needs no live connection. The process can be down for a month and reconnect with the same string. A server buys reachability, not session survival, so if you only use the CLI you do not need one at all.

Versions

See CHANGELOG.md.

14. FAQ ❓

An MCP server is a standard way to give an AI assistant real access to a tool, so it can act rather than guess. You install it once, your assistant gains the tools, and it works in Claude, Cursor and anything else that speaks the protocol. You never call the tools yourself, you just ask in plain language.

telegram-cli is the same program as the MCP server, run as commands. AI agents that run commands, like Claude Code, Codex and OpenCode, use it on their own, and you can type the same commands in a terminal, a script or a cron job. Every tool is a command with dashes, so list_chats runs as telegram-cli list-chats.

Use the MCP server in an app with no terminal, like Claude Desktop's chat. Use the CLI anywhere commands run: an agent like Claude Code, Codex or OpenCode, a script or a cron job. The MCP server's tools take up context on every message, and the CLI costs nothing until it runs.

A bot is a separate account, and it only receives messages that people send to that bot. It cannot read your conversations, your groups, or anything that happened before it existed.

This signs in as you, over the same protocol the official apps use. Every chat you are in, all of the history, and search across it.

Telegram publishes the client API at my.telegram.org specifically so people can build clients, and third-party clients are common and long-standing.

What gets accounts limited is behaviour, not the API: bulk messaging, spam, mass adding people. Reading your own chats and answering them is what this is for. Rate limits are real and the tool surfaces them rather than retrying into them.

Telegram authenticates a user by sending a code to an existing session, so there is a one-time interactive login. What comes out is a session string, which is how the tool signs in afterwards without asking again.

It is full access to the account and does not expire. Treat it exactly as you would your password, and revoke it under Settings → Devices when you are done.

No. BotFather issues bot tokens, and a bot is the thing this deliberately is not. You need an api_id and api_hash from my.telegram.org, which is a different page and a different kind of credential.

Nothing leaves your machine except calls to Telegram. There is no backend here, no account to create and no telemetry. Your session sits in your client's config file and the audit log, if you enable one, sits where you pointed it.

It only acts when a model calls a tool, and a model only calls one in response to something you said. The risk is not spontaneity, it is misreading: a request to "reply to everyone" doing more than you meant.

That is what the guard is for. delete refuses without explicit confirmation, TELEGRAM_ALLOW_DESTRUCTIVE keeps it off entirely by default, and TELEGRAM_READ_ONLY=1 removes every write tool from the list.

Because an app that loads every tool up front sends every definition with every message, whether you use it or not. All 74 here measure about 14,400 tokens in Claude Code, against 2,800 for the 13, and more tools make tool selection worse: a model picks correctly from 13 far more reliably than from 80.

The 13 cover what actually gets used. The long tail belongs in the CLI, where it costs nothing until you type it.

Not yet. One session per server instance today. You can run a second instance with a different session string under a different name in your client config, which works but is clumsier than it should be.

Reading and sending work the same either way. Premium-only features like longer messages and larger uploads follow whatever your account already has, because this is your account rather than a bot with its own limits.

Questions

Run into a problem or have a question? Open an issue and I will help.

About the author

Navid Moazzez is a leading AI business strategist, and the host of the AI Creator Summit, watched by 100,000+ creators. He helps creators and founders master AI and build their own AI Operating System (AI OS) to automate their business and life. He creates useful free tools, MCP servers and CLIs that creators and founders can use in their own workflows.

Links

If this is useful, star the repo and come say hi on X.

Dependencies

Library

License

What it does

Slipway

Apache-2.0

The MCP server and the CLI from one definition of each tool

MCP TypeScript SDK

Apache-2.0

The MCP protocol and its transports, through Slipway

GramJS

MIT

The MTProto client, published as telegram

License

MIT. Free to use, modify, and share.

Not affiliated with, endorsed by, or connected to Telegram Messenger Inc.


© 2026 Navid Media. Made with ❤️ by Navid Moazzez.

Available Tools

13 tools
deleteDelete messagesA
Destructive

Delete one or more messages. This cannot be undone, and with revoke it removes them for everyone in the chat, not only for you.

ParametersJSON Schema
NameRequiredDescriptionDefault
peerYesThe chat the messages are in.
revokeNoDelete for everyone, not just this account. Default true.
confirmNoSet true only when the user asked for exactly this action.
message_idsYesIds to delete.

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true, idempotentHint=false, and readOnlyHint=false, but the description adds materially: the action cannot be undone, and with revoke it removes messages for everyone rather than just the caller. That is exactly the consequence information an agent needs before invoking a destructive 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?

Two short sentences, front-loaded with the operation and immediately followed by the irreversibility warning. No filler, though the second sentence packs two separate consequences together.

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?

For a destructive batch-delete with no output schema, the description covers what matters most: irreversibility and the for-everyone scope of revoke. It leaves permission requirements and the confirm gating unstated, but the structured fields cover those.

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%, so the schema documents peer, revoke, confirm, and message_ids on its own. The description restates revoke's global effect ('removes them for everyone in the chat') but adds no syntax, defaults, or constraints beyond what the schema already provides.

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

Purpose4/5

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

States a specific verb and resource ('Delete one or more messages'), so the agent immediately knows the operation and that it is batched over message_ids. It does not explicitly contrast with siblings like edit or forward, but the scope is unambiguous.

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?

Usage is implied by the irreversibility warning and the revoke explanation, but there is no explicit when-to-use/when-not or pointer to alternatives such as edit. The 'confirm' prerequisite lives only in the schema, not in the description.

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

download_mediaDownload media from a messageA
Read-onlyIdempotent

Save the photo, video, document or voice note attached to a message, and return the local path. The file is written to disk rather than returned inline, because a base64 image in a tool result is enormous and unreadable.

ParametersJSON Schema
NameRequiredDescriptionDefault
dirNoDirectory to save into. Defaults to the working directory.
peerYesThe chat the message is in.
message_idYesId of the message carrying the media.

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare the safe, idempotent read profile, and the description adds the non-obvious side effect that a file is written to disk and a path returned rather than bytes inline, plus the reason. It does not cover overwrite/filename behavior or the failure case when a message carries no media.

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 padding: the action and return value come first, then a single-sentence justification of the disk-write design choice. Every clause earns its place.

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?

With no output schema, the description correctly tells the agent the return value is a local path, and annotations carry the safety profile. Minor gaps remain around naming/overwrite rules and behavior when no media is attached.

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%, so peer, message_id and dir are already documented, including the working-directory default. The description adds only the return-path behavior, which is not a parameter concern, so baseline 3 applies.

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

Purpose4/5

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

States a specific verb and resource with scope: save the photo/video/document/voice note attached to a message and return the local path. This clearly separates it from send_file and the other message-mutation siblings, though it never names an alternative outright.

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?

Usage context is implied by 'attached to a message', and the disk-vs-inline rationale hints at why an agent should prefer this over inlining media. There is no explicit when-not guidance or named alternative, so it stays at implied-usage level.

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

editEdit a messageA

Change the text of a message you sent. Telegram marks it edited.

ParametersJSON Schema
NameRequiredDescriptionDefault
peerYesThe chat the message is in.
textYesThe replacement body.
message_idYesId of the message to edit.

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false, and openWorldHint=true, so the safety profile is covered. The description adds genuine behavioral context beyond that: the mutation is visible to other participants because "Telegram marks it edited," which is a side effect the annotations do not express. It omits failure modes such as edit windows or permission errors, keeping it short of a 5.

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 short sentences with zero filler; the core action is front-loaded and the second sentence contributes non-redundant side-effect information.

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?

For a three-parameter mutation tool with full schema coverage, an explicit safety profile, and no output schema, the description covers ownership scope and the visible edited marker. Nothing critical is missing, though error conditions and edit-window limits are left unaddressed.

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 description coverage is 100% with three documented parameters (peer, message_id, text), so the schema carries the load. The description only gestures at the text parameter and adds no syntax, formatting, or constraints (e.g., length limits or parse modes) beyond what the schema already states.

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

Purpose4/5

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

States a specific verb (change) and resource (the text of a message you sent), which implicitly separates it from send, delete, and forward. It does not explicitly name a sibling or contrast with one, so it lands at clear-but-undifferentiated rather than 5.

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?

"A message you sent" is a real ownership constraint that tells the agent this cannot be used on other people's messages, but there is no explicit when-to-use/when-not framing and no routing to alternatives such as send for new content or delete for removal. Usage is implied rather than stated.

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

forwardForward messagesB

Forward messages from one chat into another.

ParametersJSON Schema
NameRequiredDescriptionDefault
toYesChat to forward into.
fromYesChat to forward from.
message_idsYesIds to forward.

TDQS

B3.2/5.0
Behavior2/5

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

Annotations already declare that this is a non-read-only, open-world, non-idempotent, non-destructive operation. The description adds no behavioral context beyond restating the purpose, such as duplicate handling, permission requirements, rate limits, or what happens to the original messages.

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 a single front-loaded sentence with no wasted words. It communicates the core action efficiently.

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?

For a simple three-parameter mutation tool with full schema coverage and annotations covering the safety profile, the description is nearly complete enough to invoke. It omits edge-case behavior such as permission failures or whether messages remain in the source chat, but there is no output schema requiring return-value explanation.

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 description coverage is 100%, so the schema already documents all three parameters: from, to, and message_ids. The description adds no extra parameter meaning beyond what the schema provides, so the baseline of 3 applies.

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

Purpose4/5

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

The description states a clear verb and resource: 'Forward messages,' with the scope 'from one chat into another.' It is easy to distinguish from read-only siblings like history and search, but it does not explicitly distinguish itself from write-oriented siblings such as send or edit.

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

Usage Guidelines2/5

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

The description gives no guidance about when to use forwarding versus alternatives like send or edit, nor does it mention prerequisites such as needing access to both chats. Usage is only implied by the tool name and description.

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

get_chatGet one chatB
Read-onlyIdempotent

Details of a single chat: name, kind, username, member count and description where the chat has them.

ParametersJSON Schema
NameRequiredDescriptionDefault
peerYesA @username, numeric id, or 'me'.

TDQS

B3.2/5.0
Behavior3/5

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

Annotations already declare readOnly, idempotent, non-destructive, openWorld, so the safety profile is covered. The description adds the return-field inventory ('where the chat has them', signaling optional fields), which is mildly useful, but says nothing about failure behavior for an unresolvable peer or any auth requirements.

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?

A single efficient sentence with the resource front-loaded and no wasted words. Slightly under-informative rather than over-verbose, which is fine for conciseness.

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?

No output schema exists, so the description correctly compensates by listing the returned fields and noting they are conditional. Combined with annotations covering the read-only safety profile, this is close to complete for a simple single-record fetch; only error/not-found behavior is unaddressed.

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 description coverage is 100% and the single 'peer' parameter is fully documented in the schema ('A @username, numeric id, or 'me''). The description adds no further syntax or format detail beyond what the schema already provides, so the baseline of 3 applies.

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

Purpose4/5

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

States a specific resource (a single chat) and enumerates the fields returned (name, kind, username, member count, description), so the agent knows exactly what it gets. It does not explicitly distinguish itself from siblings like list_chats or resolve, but 'a single chat' implies a targeted lookup rather than a listing.

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

Usage Guidelines2/5

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

No when-to-use guidance and no alternatives named, despite several plausible siblings (list_chats for enumeration, resolve for turning an identifier into a chat, history for messages). The agent must infer the selection criteria on its own.

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

historyRead chat historyA
Read-onlyIdempotent

Messages from one chat, newest first. Bodies are truncated to a preview unless full is set, because a long chat returned whole is mostly wasted context.

ParametersJSON Schema
NameRequiredDescriptionDefault
fullNoKeep whole message bodies instead of previews.
peerYesA @username, numeric id, or 'me'.
limitNoHow many messages. Default 20, max 100.
fieldsNoComma separated fields to keep, e.g. 'id,text'. Dotted paths descend. Cuts response size.
before_idNoOnly messages older than this id. Use next_cursor to page.

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/non-destructive/openWorld, so the safety profile is covered. The description adds genuinely new behavioral facts annotations cannot express: results are ordered newest first and bodies are truncated to previews by default, with the rationale for that default. Pagination behavior and response shape are not disclosed, keeping it short of a 5.

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, zero filler, and the resource plus ordering are front-loaded before the truncation caveat. Every clause carries information the agent needs.

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?

For a read-only tool with a fully documented schema and no output schema, the description covers the essentials an agent needs: scope, ordering, and the preview default. It omits paging guidance (the schema mentions next_cursor) and any hint of the returned message shape, but complexity is low enough that 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?

Schema coverage is 100%, so the baseline is 3; the description earns above that by explaining WHY `full` defaults off — a whole long chat mostly wastes context — which directly informs the most consequential parameter decision. The remaining four parameters get no added meaning beyond their schema descriptions.

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

Purpose4/5

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

States a specific resource and scope: messages from ONE chat, returned newest first. That verb+resource+ordering is unambiguous and distinct from list_chats/get_chat. It does not, however, differentiate itself from the sibling `search`, which also returns messages, leaving the boundary between browsing one chat and searching all chats to inference.

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

Usage Guidelines2/5

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

There is no when-to-use or when-not-to-use statement and no alternative is named, despite `search` being an obvious competing tool for retrieving messages. The only implicit steer is the preview default, which hints at casual browsing rather than targeted retrieval, but this is left unstated.

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

list_chatsList chatsA
Read-onlyIdempotent

Recent conversations, newest first. Returns a compact row per chat: id, name, kind, unread count and a short preview of the last message. Use fields to cut it down further.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoOnly this kind of chat.
limitNoHow many chats. Default 20, max 200.
fieldsNoComma separated fields to keep, e.g. 'id,text'. Dotted paths descend. Cuts response size.
unread_onlyNoOnly chats with unread messages.

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, non-destructive, open-world behavior, so the bar is lower. The description adds value beyond them by disclosing the return format (compact row per chat with id, name, kind, unread count, preview) and the newest-first ordering.

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?

Two tight sentences with the ordering and return shape front-loaded. Every sentence carries information, though the closing fields tip is somewhat redundant with the schema.

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?

With no output schema, the description usefully compensates by describing the returned row contents and ordering. It is largely complete for a read-only list tool, with only the sibling-routing context left unstated.

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 description coverage is 100%, so all four parameters are already documented in the schema. The description only reinforces the fields parameter ('Use fields to cut it down further') without adding syntax or format detail beyond what the schema provides, so baseline 3 applies.

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

Purpose4/5

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

States a specific verb and resource ('Recent conversations') and adds ordering ('newest first') plus the returned row shape. It is clear what the tool does, but it never explicitly distinguishes itself from siblings like search, history, or get_chat.

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 phrase 'Recent conversations' implies the browsing use case, but there is no explicit when-to-use guidance, no exclusions, and no named alternatives such as search or get_chat for targeted lookups. Usage is left to inference.

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

mark_readMark a chat readB

Clear the unread count on a chat.

ParametersJSON Schema
NameRequiredDescriptionDefault
peerYesThe chat to mark read.

TDQS

B3.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=false, destructiveHint=false, and openWorldHint=true, covering the safety profile. The description adds the specific effect (clearing the unread count) but omits auth requirements, rate limits, or what happens on repeated calls. With annotations carrying the safety burden, a 3 is appropriate.

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?

A single short sentence with no filler, and the action is front-loaded. It is efficient, though the brevity also reflects the thin guidance rather than tight editing of rich content.

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

Completeness3/5

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

For a simple one-parameter tool with annotations and no output schema, the definition is minimally adequate. It still leaves the when-to-use condition and behavioral specifics (auth, repeat-call effects) unstated.

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 description coverage is 100% for the single 'peer' parameter, so the schema already documents it fully. The description adds no syntax, format, or identifier detail beyond what the schema provides, matching the baseline 3.

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

Purpose4/5

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

States a specific verb and effect ('Clear the unread count') on a specific resource ('a chat'), so the action is unambiguous. However, it does not differentiate itself from siblings such as get_chat or history, leaving the agent to infer the distinction.

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

Usage Guidelines2/5

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

The description gives no when-to-use guidance, no prerequisites, and names no alternative. An agent gets no help deciding between mark_read and reading the chat via get_chat or history.

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

resolveResolve a username or idA
Read-onlyIdempotent

Turn a @username, phone number or numeric id into a chat you can act on. Use it before sending to someone you only know by handle.

ParametersJSON Schema
NameRequiredDescriptionDefault
peerYesA @username, phone number, numeric id, or 'me'.

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint, non-destructive and openWorld, so the safety profile is covered. The description adds only the notion that the output is an actionable chat entity; it says nothing about failure modes for unresolvable handles or about the lookup cost/latency of an open-world operation.

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 short sentences; the capability is front-loaded and the usage condition follows immediately. No filler or redundant restatement.

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?

For a one-parameter, idempotent lookup with no output schema and full annotation coverage, the description supplies enough to invoke it correctly. It could go further by indicating what the resolved chat value looks like or how it is consumed by send, since no output schema defines the return shape.

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 description coverage is 100% and the single 'peer' parameter already documents the accepted forms, including 'me'. The description merely repeats those input forms, adding no format or normalization detail beyond the schema, so the baseline 3 applies.

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

Purpose4/5

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

States a specific verb (turn/resolve) and resource (@username, phone, numeric id → a chat), which is a genuine capability statement rather than a restatement of the title. It does not, however, differentiate from lookalike siblings such as get_chat, whoami, or list_chats, which also return chat/user entities.

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?

"Use it before sending to someone you only know by handle" gives a concrete trigger condition tied to the send sibling. There is no statement of when NOT to use it (e.g. when you already have a known chat id) and no named alternative, so it falls short of the explicit when/when-not/alternatives bar.

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

sendSend a messageA

Send a message to a chat. This is visible to the recipient immediately and posts as you, so only send what was actually asked for.

ParametersJSON Schema
NameRequiredDescriptionDefault
peerYesA @username, numeric id, or 'me' for Saved Messages.
textYesThe message body. Markdown is supported.
silentNoDeliver without a notification sound.
reply_toNoMessage id to reply to.

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false, idempotentHint=false, and openWorldHint=true. The description adds genuinely new behavioral context: the message is 'visible to the recipient immediately' (irreversible external side effect) and 'posts as you' (identity/attribution). It does not mention error cases or that the returned message id feeds reply_to.

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 short sentences, action stated first, caution second. No filler, no repetition of the title.

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?

For a simple 4-parameter send tool with no output schema, the description covers purpose, visibility, and attribution adequately. Minor gap: it doesn't hint that a message id is returned (useful for the sibling reply_to parameter), but nothing essential is missing.

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 description coverage is 100% and all four parameters (peer, text, silent, reply_to) are documented in the schema itself. The description adds no parameter-level detail, so the baseline 3 applies.

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

Purpose4/5

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

Specific verb+resource: 'Send a message to a chat.' An agent can distinguish it from siblings like edit, forward, and send_file by the resource named. It stops short of explicitly contrasting with send_file (file vs text) or forward, but the purpose is unambiguous.

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 closing clause 'only send what was actually asked for' gives an implied usage constraint (don't send unprompted content), but there is no explicit when-to-use guidance and no named alternatives such as edit or forward for modifying/relaying existing messages.

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

send_fileSend a fileA

Send a local file to a chat, with an optional caption.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathYesAbsolute path to the file to send.
peerYesA @username, numeric id, or 'me'.
captionNoCaption to attach.

TDQS

A3.5/5.0
Behavior3/5

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

Annotations already declare the safety profile (readOnlyHint=false, idempotentHint=false, openWorldHint=true, destructiveHint=false), so the bar is lower. The description adds only that the source file is local, and says nothing about auth requirements, upload/size limits, or failure behavior when the path is invalid — modest added value over the structured fields.

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?

A single front-loaded sentence with zero filler; the verb and resource lead. It is arguably too terse for the tool's role next to an ambiguous 'send' sibling, but nothing in it is wasted.

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?

For a low-complexity, 3-parameter tool with full schema coverage, annotations covering the safety profile, and no output schema, the description contains enough to invoke it correctly. Gaps are minor: no mention of upload constraints or error behavior for a bad path.

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 description coverage is 100% ('Absolute path to the file to send', '@username, numeric id, or me', 'Caption to attach'), so the schema carries full parameter meaning. The description only restates that the caption is optional, adding nothing beyond the schema — baseline 3 is correct here.

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

Purpose4/5

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

The description gives a specific verb and resource ('Send a local file'), names the destination ('to a chat'), and notes the optional caption. 'Local file' usefully distinguishes it from the sibling download_media (which moves media the other way), but it does not clarify how it differs from the plain 'send' sibling, which is a real ambiguity for an agent choosing between the two.

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?

Usage is implied by the purpose — an agent reading 'send a local file' knows this is the tool for uploading a file to a chat. However, no when-to-use condition, exclusion, or alternative is stated, and the overlap with the sibling 'send' is left unresolved, so the agent must infer the routing rule.

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

whoamiWho am IA
Read-onlyIdempotent

The Telegram account this session is signed in as. Call it first when it matters whose messages you are about to read or send.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

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

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is fully covered by structured data. The description adds the useful fact that the identity is session-scoped rather than global, but stops short of describing what the returned account record contains. Compare to the calibration case where annotations covered safety and the description's scoping note earned a 3.

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 short sentences, zero waste: identity first, then the actionable usage rule. Front-loaded and appropriately sized for a trivial tool.

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?

For a zero-parameter, read-only, idempotent lookup with annotations carrying the safety profile, nothing an agent needs in order to call it correctly is missing. The lack of an output schema is the only minor gap.

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?

The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline of 4 applies.

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?

States a specific resource and scope: the Telegram account the current session is signed in as. It is immediately distinguishable from every sibling (send, edit, history, etc.), none of which deals with session identity.

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?

"Call it first when it matters whose messages you are about to read or send" gives an explicit triggering condition and an ordering instruction. It does not name any alternative or exclusion, but for an identity tool no plausible alternative exists.

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. 13 tool updatesv0.5.0
    • Changeddelete3 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedInput schema / properties / confirm / description
        Previous value: -"Must be true for this to run. This cannot be undone, so it is refused without it."New value: +"Set true only when the user asked for exactly this action."
    • Changeddownload_media2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changededit2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedforward2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedget_chat2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedhistory2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedlist_chats2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedmark_read2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedresolve2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedsearch2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedsend2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedsend_file2 fields changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedwhoami1 field changed
      • removedInput schema / $schema
        Removed value: -"http://json-schema.org/draft-07/schema#"
  2. 13 tool updatesv0.4.0
    • First observeddelete
    • First observeddownload_media
    • First observededit
    • First observedforward
    • First observedget_chat
    • First observedhistory
    • First observedlist_chats
    • First observedmark_read
    • First observedresolve
    • First observedsearch
    • First observedsend
    • First observedsend_file
    • First observedwhoami

TDQS

A3.6/5.0

Scored across 13 tools

Disambiguation4/5

Most tools have clearly distinct purposes: send is for text, send_file for files, and read-side tools like list_chats, get_chat, history, and search differ by scope. Minor overlap exists between send/send_file and history/search, but the descriptions resolve it well.

Naming Consistency3/5

Names mix bare verbs (send, edit, delete, forward, resolve), verb_noun forms (download_media, send_file, list_chats, get_chat, mark_read), and a noun/whoami. All are lowercase and readable, but there is no single consistent pattern.

Tool Count5/5

13 tools is well within the ideal range and each maps to a distinct Telegram operation. The set feels scoped and no tool appears to be filler.

Completeness4/5

Core messaging lifecycle is covered: identity, resolution, reading, sending, editing, deleting, forwarding, media, and read marking. Minor gaps remain for reply threading, chat/group management, or contact operations, but core agent workflows are supported.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to control a real Telegram user account via MTProto, allowing message sending, chat reading/searching, and message management through MCP tools.
    29 npm
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI assistants to control a personal Telegram account for sending/reading messages, media, group management, and more via the MTProto API.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Gives an AI assistant full control of a real Telegram user account over MTProto, enabling it to read chats, search history, send and manage messages, and dynamically create new tools as needed.
    MIT