Skip to main content
Glama
jigjoy-ai

grokbot-telegram

by jigjoy-ai

Telegram for Cursor

npm CI license

Installable Cursor plugin with two first-party MCP servers:

Mode

MCP server

Identity

Protocol

Bot

telegram-bot

Your @BotFather bot

Official HTTP Bot API

User account

telegram-user

Your personal Telegram account

MTProto via teleproto (maintained GramJS fork)

Use one or both. v0.2.0 kept the v0.1.0 Bot API path and added user-account login; v0.3.0 ships both servers as the single npm package grokbot-telegram and appends a disclaimer footer to every outgoing message.

This is not Bot API–only, and it is not user-account–only. Marketplace copy: a Cursor plugin that can send/read Telegram as a bot and/or as the logged-in user.

Which mode should I use?

Need

Mode

Notifications, CI alerts, channel posts as @mybot

Bot APITELEGRAM_BOT_TOKEN

“Send this in my name”, read my real chats / dialog list

User accountTELEGRAM_API_ID + TELEGRAM_API_HASH + session

Both (bot for alerts, account for DMs)

Configure both variable sets

Bot API cannot list your personal inbox. User-account mode can (list_dialogs), because it is logged in as you.

Related MCP server: Telegram MCP Server

What you must provide

Bot API (telegram-bot)

  1. Create a bot with @BotFather/newbot.

  2. Set TELEGRAM_BOT_TOKEN in Cursor Plugins → Configure.

  3. Open a DM with the bot and tap Start (/start). Bots cannot message you first.

No api_id is required for this mode.

User account (telegram-user) — first run

  1. Open https://my.telegram.org/apps, log in with the same phone as the Telegram account you want to use, and create an app.

  2. Set TELEGRAM_API_ID and TELEGRAM_API_HASH in Plugins → Configure.

  3. Complete one-time login (phone + code, QR / Link Desktop Device, or an existing session string).

  4. Persist the session as TELEGRAM_SESSION and/or the file ~/.grokbot-telegram/user.session (mode 0600).

You will be asked for api_id / api_hash / login on first run. A bot token is not used for this server.

The session is full account access. Treat it like a password. Never commit it.

Message disclaimer

Every message sent through either server carries a footer, so the person on the other end knows an agent — not a human typing — produced it:

your message text

— sent by grokbot-telegram on my behalf

The Bot API server uses — sent by grokbot-telegram (it is already visibly a bot). TELEGRAM_DISCLAIMER controls it:

Value

Result

unset

default wording above

any text

that text is used verbatim

off, false, 0, no, none, empty

no footer

The wording names the package rather than linking to it, on purpose. A URL in the footer would make Telegram attach a link-preview card to every message you send, and a link in someone's personal chat reads as advertising — the name is still searchable on npm and GitHub. Set TELEGRAM_DISCLAIMER to a URL yourself if you disagree.

Two details worth knowing:

  • The footer counts against Telegram's 4096-character limit. If text + footer would exceed it, the send is refused with an error naming the overflow rather than quietly truncating your words or dropping the footer.

  • With parse_mode, the footer is escaped for that mode. This matters for MarkdownV2, where an unescaped . or - makes Telegram reject the whole message.

Why you need your own api_id

Telegram issues api_id/api_hash per developer and rejects credentials that have been published: an app that ships a shared pair earns its users an API_ID_PUBLISHED_FLOOD error at login. So this package deliberately does not ship one. It is a one-time, two-minute detour at my.telegram.org/apps, and it keeps the blast radius at one user instead of everyone at once.

You do not have to put the values in a config file. Hand them to the agent and it calls save_api_credentials, which writes them next to the session at mode 0600. TELEGRAM_API_ID / TELEGRAM_API_HASH still work as environment variables and take precedence, which is the path for developers bringing their own app.

Only user-account mode needs this. Bot API mode needs nothing but a @BotFather token, which takes about thirty seconds inside Telegram. If you only want notifications or to post to a channel, use that.

Forum topics

Groups with topics turned on keep their messages in separate threads. list_dialogs marks those with isForum, list_forum_topics lists the threads, and send_message / get_messages take an optional topic_id to work inside one. Without topic_id nothing changes — the message goes to the chat as before.

A wrong topic_id is worth understanding: Telegram does not reject it, it quietly files the message under General, in front of everyone. So send_message checks the id against the topic list before sending, and refuses a closed topic outright. That costs one extra call, only when a topic is named.

Naming a chat

send_message and get_messages take an id, me, an @username, or a chat title. Ids and @usernames go straight out. A title is resolved against your dialog list first, and an ambiguous one is refused with the candidates named rather than guessed at.

This exists because handing a title to the underlying client makes it look for a username that was never there, which in a short-lived process means a minute of hanging instead of an error. Prefer an id from list_dialogs when you have one: it is the only form with no lookup at all.

Security

Bot token

Anyone with TELEGRAM_BOT_TOKEN can send as that bot, read updates, and change bot settings. Set it only in Plugins → Configure. The bot MCP redacts token-shaped strings from errors.

User session (stronger warning)

  • A GramJS session string or session file is equivalent to being logged in on a new device.

  • Anyone who has it can read your chats and send as you.

  • Never commit TELEGRAM_SESSION, api_hash, .env, or *.session files.

  • After first login, save the session in Plugins → Configure or keep the 0600 session file. Do not leave the string in chat history if you can avoid it.

  • Revoke: Telegram → Settings → Devices → terminate the unknown session, then delete the session file / clear the variable.

  • Automating a user account is a Telegram ToS gray area. Keep sends human-paced. No spam or bulk broadcast.

The repo never contains real tokens, api hashes, or sessions. mcp.json only has ${VAR} placeholders that match the manifest.

MCP tools

telegram-bot (unchanged Bot API v1)

Tool

Telegram method

Purpose

send_message

sendMessage

Send text as the bot (chat_id or public @username)

get_me

getMe

Confirm the token; bot username

get_updates

getUpdates

Debug recent updates

list_recent_chats

derived from getUpdates

Best-effort recent chats (not a full inbox)

telegram-user (MTProto)

Tool

Purpose

save_api_credentials

Store api_id / api_hash at 0600 so no config file is needed

auth_status

Credentials + whether the session is authorized

start_login / complete_login

Phone + login code (+ optional 2FA password)

start_qr_login / complete_qr_login

QR / Link Desktop Device (+ optional 2FA)

get_me

Logged-in user (not a bot)

list_dialogs

Real dialog / inbox list, isForum marks groups with topics

list_forum_topics

Topics of a forum group, with the ids to send into

search_dialogs

Filter dialogs by title, username, or id

get_messages

Recent history for a chat

send_message

Send text as the user (me, @username, dialog id, or a chat title)

Both servers expose send_message and get_me. Prefer the MCP server name (telegram-bot vs telegram-user). Tool descriptions are prefixed [Bot API] or [User account].

Skills

  • telegram-mode-guide — when to use bot vs user

  • telegram-bot-setup — BotFather, TELEGRAM_BOT_TOKEN, smoke-test

  • send-telegram-message — send as the bot; confirm first

  • telegram-user-setup — my.telegram.org, first login, session persistence

  • send-telegram-user-message — resolve from the dialog list; confirm first

Install

Any MCP client (npx)

Both servers ship as one npm package, grokbot-telegram, behind a single command:

npx grokbot-telegram bot     # Bot API server over stdio
npx grokbot-telegram user    # user-account (MTProto) server over stdio
npx grokbot-telegram login   # interactive login, prints a TELEGRAM_SESSION

With no command the mode is read from the environment: TELEGRAM_BOT_TOKEN selects bot, TELEGRAM_API_ID + TELEGRAM_API_HASH select user. If both are set it refuses to guess and asks for an explicit mode.

Drop this into any MCP client config (Claude Code, Claude Desktop, Cursor, …):

{
  "mcpServers": {
    "telegram-bot": {
      "command": "npx",
      "args": ["-y", "grokbot-telegram@0.4.0", "bot"],
      "env": { "TELEGRAM_BOT_TOKEN": "…" }
    },
    "telegram-user": {
      "command": "npx",
      "args": ["-y", "grokbot-telegram@0.4.0", "user"],
      "env": {
        "TELEGRAM_API_ID": "…",
        "TELEGRAM_API_HASH": "…",
        "TELEGRAM_SESSION": "…"
      }
    }
  }
}

Cursor Marketplace (when listed)

  1. Open Customize → search grokbot-telegram, or visit cursor.com/marketplace.

  2. Install the plugin.

  3. Plugins → Configure → set the variables for the mode(s) you want. For user-account mode you can skip this and let the agent store api_id/api_hash for you.

From this repository

mkdir -p ~/.cursor/plugins/local
ln -s /path/to/grokbot-telegram ~/.cursor/plugins/local/telegram-bot

Reload the window (Developer: Reload Window). Team / Enterprise admins may need to allow local plugin imports.

Note that mcp.json launches the servers through npx grokbot-telegram, so a symlinked clone still runs the published build, not your working tree. To exercise local changes, either npm run build && npm link in the repo root, or point mcp.json at ${PLUGIN_ROOT}/dist/bot.js and ${PLUGIN_ROOT}/dist/user.js with "command": "node" while you work (npm run validate will flag that, which is the reminder to change it back).

Submit the public repo at cursor.com/marketplace/publish and/or list it on cursor.directory.

Configure

The plugin declares variables in .cursor-plugin/plugin.json and substitutes ${VAR} placeholders in mcp.json. None are required in the schema so you can enable only one mode.

Variable

Mode

Where to get it

TELEGRAM_BOT_TOKEN

Bot

@BotFather

TELEGRAM_API_ID

User

my.telegram.org/apps — or let the agent store it, see below

TELEGRAM_API_HASH

User

my.telegram.org/apps — or let the agent store it, see below

TELEGRAM_SESSION

User

Returned after first login (optional if the session file exists)

TELEGRAM_DISCLAIMER

Both

Optional. Footer wording, or off to disable (see below)

Optional env (not a marketplace variable): TELEGRAM_SESSION_PATH overrides the default session file ~/.grokbot-telegram/user.session.

Login is two calls — start_login sends the code, complete_login redeems it — and some MCP hosts start a fresh process per call. So the in-flight state is written next to the session file as user.session.pending.json (mode 0600) and picked back up by the next process. It holds a pre-authorization session: it cannot read or send anything, but it is the auth key the code is bound to, so it is deleted the moment login succeeds and discarded after 15 minutes.

QR login does not survive a restart, and cannot. Telegram announces the scan on the connection that exported the code, and the authorization only exists once that same connection redeems it. The process that called start_qr_login has to stay alive until the scan lands. On a host that starts a process per tool call, use phone login. complete_qr_login still adopts an already-authorized session if there is one, and otherwise hands back a fresh login_url, because exporting again yields a different code and re-showing the old one can never work.

The project was called cursor-telegram-plugin before it became grokbot-telegram. A session left in the old ~/.cursor-telegram-plugin/user.session is still read, so an existing login keeps working; new sessions are written to the new path.

Example prompts

Bot

  • “Verify my Telegram bot with telegram-bot get_me. Do not print the token.”

  • “I just /start’ed the bot. List recent chats, then send ‘hello from Cursor’ to my DM after I confirm.”

User

  • “I want messages sent as me, not as a bot. Walk me through my.telegram.org and first login.”

  • “Search my Telegram dialogs for ‘Ada’, then send this text after I confirm.”

  • “Show recent messages in Saved Messages (me) using the user account.”

How to test

Bot API send_message

  1. /start the bot (or add it to a group/channel).

  2. Set TELEGRAM_BOT_TOKEN.

  3. In Agent chat: get_melist_recent_chats → confirm → send_message.

  4. Optional:

export TELEGRAM_BOT_TOKEN="…"   # local shell only
curl -sS "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe"

User-account send (as you)

  1. Set TELEGRAM_API_ID and TELEGRAM_API_HASH.

  2. Login once:

export TELEGRAM_API_ID="…"
export TELEGRAM_API_HASH="…"
npx grokbot-telegram login

From a clone, the equivalent is node dist/login.js after npm run build.

Or use start_login / start_qr_login from the agent.

For login through a chat, prefer start_login. A QR token lives about 30 seconds and that clock starts when the tool returns, not when the code reaches the screen — which is usually not enough time in a conversation. The token cannot be extended; it is Telegram's limit. What the tools do instead is remove the round trips. start_qr_login and every waiting reply from complete_qr_login return the code as a scannable PNG in the tool result, ahead of the JSON, so the agent forwards an image rather than rendering one itself — and login_url stays in the payload as a fallback for clients that show no images. Each waiting reply also carries a fresh code and expires_in_seconds, so a retry gives the user a full window instead of a dead code.

The QR is drawn locally. A login token is a credential, so it never goes to an external image service.

Not every MCP host paints tool-result images on its own; where it does not, the agent forwards the base64 it was handed. Either way the code is generated once, here, rather than round-tripped through the agent.

The session shows up in Telegram → Settings → Devices as grokbot-telegram, so it is easy to find and revoke.

  1. Confirm get_me is your user (isBot: false).

  2. list_dialogs / search_dialogs, confirm destination + text, then send_message.

Automated tests mock Telegram (no live token or account). Node.js 20+ is required.

npm install --prefix packages/mcp-server
npm install --prefix packages/mcp-user-server
npm test          # both packages
npm run typecheck
npm run build     # per-package bundles, then collected into the root dist/
npm run validate  # manifest + wiring invariants

Working on this with a coding agent? Start from AGENTS.md.

Chat list limitation (Bot API only)

The Bot API cannot list every chat a bot belongs to. list_recent_chats only inspects recent getUpdates events. If nothing shows up: the user has not /started the bot, the group is quiet, or a webhook is set.

User-account mode uses the real dialog list and does not have this limitation.

Why first-party servers (not a random npm MCP)

Public packages exist (Bot API wrappers; user MCPs such as @overpod/mcp-telegram / mcp-telegram/mcp-telegram). They are real, but they are either very large or a different product.

This plugin ships two small stdio servers:

  • Bot: official HTTP Bot API only (packages/mcp-server)

  • User: teleproto MTProto user client (packages/mcp-user-server), tools limited to login, dialogs, history, and send

Both are bundled with esbuild — every dependency (including teleproto) is inlined, so the published package installs with zero runtime dependencies. npm run build produces the per-package bundles and collects them into the publishable root dist/:

  • dist/bot.js, dist/user.js, dist/login.js — the bundles

  • dist/cli.js — the grokbot-telegram dispatcher that picks between them

npm run build

mcp.json launches both:

{
  "telegram-bot": {
    "command": "npx",
    "args": ["-y", "grokbot-telegram@0.4.0", "bot"],
    "env": { "TELEGRAM_BOT_TOKEN": "${TELEGRAM_BOT_TOKEN}" }
  },
  "telegram-user": {
    "command": "npx",
    "args": ["-y", "grokbot-telegram@0.4.0", "user"],
    "env": {
      "TELEGRAM_API_ID": "${TELEGRAM_API_ID}",
      "TELEGRAM_API_HASH": "${TELEGRAM_API_HASH}",
      "TELEGRAM_SESSION": "${TELEGRAM_SESSION}"
    }
  }
}

Marketplace notes

  • Single Cursor Plugin (.cursor-plugin/plugin.json), not a multi-plugin marketplace.json repo.

  • MTProto user client + Bot API, not Bot API alone.

  • Plugin name is grokbot-telegram, matching the npm package and the repository.

  • MIT. Version lives in package.json; .cursor-plugin/plugin.json and the pin in mcp.json are checked against it by npm run validate.

  • Logo at assets/logo.svg — a plain outline mark, deliberately not Telegram's own logo or brand colour, since this is a third-party plugin.

  • mcp.json pins the version it launches, so what a reviewer reads is what runs.

  • Variables: TELEGRAM_BOT_TOKEN, TELEGRAM_API_ID, TELEGRAM_API_HASH, TELEGRAM_SESSION, TELEGRAM_DISCLAIMER (all optional in the schema).

  • Submit: cursor.com/marketplace/publish.

Layout

.
├── .cursor-plugin/plugin.json
├── mcp.json
├── skills/
│   ├── telegram-mode-guide/SKILL.md
│   ├── telegram-bot-setup/SKILL.md
│   ├── send-telegram-message/SKILL.md
│   ├── telegram-user-setup/SKILL.md
│   └── send-telegram-user-message/SKILL.md
├── assets/logo.svg
├── AGENTS.md                   # guidance for coding agents (CLAUDE.md points here)
├── src/cli.js                  # grokbot-telegram dispatcher (bot | user | login)
├── dist/                       # published bundles, built (gitignored)
├── packages/mcp-server/        # Bot API MCP + dist bundle
├── packages/mcp-user-server/   # GramJS user MCP + dist bundle
├── LICENSE
└── README.md

License

MIT © Lotus / Lotus015 (GitHub)

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to interact with Telegram accounts through MCP, supporting messaging, contacts, groups, media, and admin functions.
    4
    Apache 2.0
  • F
    license
    B
    quality
    C
    maintenance
    Enables MCP clients to interact with Telegram user accounts, providing tools for messaging, contacts, groups, channels, and media management through the Telegram API.
    85
    3
    -
  • A
    license
    A
    quality
    B
    maintenance
    Enables use of a personal Telegram account within MCP clients for reading and sending messages, searching chats, and managing media, all running locally.
    16
    3 npm
    MIT