tgfmcp is an open-source Telegram stdio MCP server built on top of telegraf, commander, and @modelcontextprotocol/sdk.
It lets MCP-compatible clients interact with the Telegram Bot API through Telegraf and optionally subscribe to incoming Telegram events through an MCP notification channel.
- Exposes Telegram as an MCP server over stdio.
- Uses
telegrafdirectly for polling and Bot API operations. - Supports interactive configuration via
tgfmcp configure. - Provides direct Bot API tools for bot identity and chat lookups.
- Includes mutating tools for sending, replying, reacting, editing, deleting, forwarding, and typing.
- Can emit incoming message events over an optional MCP notification channel.
- Stores downloaded incoming media attachments under
~/.tgfmcp/attachments/.
- Node.js
24+ - A Telegram bot token
Use it without installing globally:
npx tgfmcp mcpOr with Bun:
bunx tgfmcp mcpIf you prefer a global install:
npm install -g tgfmcpFor local development:
npm install
npm run build
npm run dev -- mcp- Run the interactive configuration:
tgfmcp configureThis writes:
~/.tgfmcp/config.json
- Start the MCP server:
npx tgfmcp mcp- If your MCP host supports notifications and you want incoming Telegram events, enable channels:
npx tgfmcp mcp --channelsThe server uses stdio, so it is meant to be launched by an MCP client or wrapper rather than browsed directly in a terminal.
npx tgfmcp mcp
bunx tgfmcp mcpStarts the stdio MCP server for the configured Telegram bot.
npx tgfmcp configureThen opens an interactive configure UI (Ink) to manage:
Bot tokenAllowed usersAllowed chats
Allowlist items are toggled from menu screens (select an entry to toggle it, then choose Back).
For enrolling users/chats, configure can generate a short code per screen and watch incoming Telegram updates. Send the code from the target user/chat and the matching ID is auto-added to allowlist.
Everything is persisted to:
~/.tgfmcp/config.json
The server currently exposes these tools:
telegram_get_metelegram_get_statustelegram_get_chattelegram_get_chat_administratorstelegram_lookup_chattelegram_send_messagetelegram_send_media_from_base64telegram_send_media_from_pathtelegram_reply_to_messagetelegram_react_to_messagetelegram_edit_messagetelegram_delete_messagetelegram_forward_messagetelegram_send_typing
When started with --channels, the server:
- advertises the experimental MCP capability
hooman/channel - advertises
hooman/userwith pathmeta.user - advertises
hooman/sessionwith pathmeta.session - advertises
hooman/threadwith pathmeta.thread - advertises
hooman/channel/permissionfor remote daemon approvals - emits
notifications/hooman/channelfor incoming Telegram message events
If allowlist entries are configured, notifications/hooman/channel events are emitted only when either:
meta.session(chat ID) is inallowlist.chats, ormeta.user(sender user ID) is inallowlist.users
When no allowlist is configured (or both arrays are empty), all inbound channel events are emitted.
Each notification includes:
content: a JSON-encoded event payloadmeta.source: alwaystelegrammeta.user: the sender identity seed for the incoming messagemeta.session: the chat identity seed for the incoming messagemeta.thread: the Telegram message ID for the incoming message
The JSON-decoded content payload includes:
sourceselfmessagetext
If an incoming message contains downloadable media, the file is downloaded and included as a local attachment path in the event payload. Files are stored under ~/.tgfmcp/attachments/.
When Hooman sends notifications/hooman/channel/permission_request, tgfmcp posts the request back into the originating Telegram chat with inline approval buttons derived from params.options (defaults: allow once, always allow, deny). Button selections are relayed back over notifications/hooman/channel/permission.
Approvals are handled through inline buttons rendered from the permission request options.
tgfmcp stores local state under ~/.tgfmcp/:
config.jsonfor bot token and allowlistattachments/for downloaded incoming media attachments
- Telegram bots cannot access arbitrary private chats; they can only interact where the bot has been added, contacted, or is otherwise permitted.
- Message mutation tools that target an existing message require explicit
chatIdandmessageIdinputs.
MIT. See LICENSE.