termgram
Provides tools for interacting with Telegram over MTProto, including sending text and rich media, scheduling messages, replying, searching chats via a local mirror, managing chats and contacts, and receiving new-message push notifications through the MCP server.
termgram
Telegram in the terminal. A complete MTProto client, an MCP server, and a push stream, in one place.
termgram talks to Telegram natively over MTProto (via the grammers stack).
No Bot API, no external services. One unified command sends text, rich media,
tappable date chips and scheduled messages. A local mirror makes search
instant. And two hooks let your own tools react the moment a message lands:
termgram-mcp, an MCP server: every CLI command becomes a tool, and new messages are pushed to the client as server→client notifications.termgram-notify, an SSE stream: a plain HTTP endpoint any script can subscribe to.
For people who live in the terminal and want AI on top of their chats.
Highlights
One unified send pipeline. Text,
plain/markdown/htmlformatting parsed into real Telegram entities, tappable date chips, photos, documents, voice notes, albums, replies, scheduling, forum topics. All through onesendcommand.Local search mirror.
synconce, then search offline-instant across every chat. Missing chats auto-sync on demand, with a live API fallback.Full chat tooling. Polls, reactions, drafts, pins, folders, contacts, members, kick/ban/promote, export/import/wipe.
Push, not polling. New messages arrive through a broadcast signal;
waitblocks server-side on a real Telegram push and returns instantly.Per-chat notification filter. Tell the MCP server which chats to push, or push everything.
One auth for everything. A single session drives the CLI, MCP server and notifier. Multiple accounts supported.
Related MCP server: Fast MCP Telegram
Getting started
1. Register an app
Telegram needs an API ID and hash per client. Create one at my.telegram.org (any value works; it's your own account).
2. Configure
termgram keeps everything under ~/.config/termgram/. On first run it writes
a config.toml template; fill it in:
# ~/.config/termgram/config.toml
api_id = 123456
api_hash = "0123456789abcdef0123456789abcdef"3. Login
termgram login # enter your phone number, receive a code
termgram login 12345 # verify the codeYour session is stored in ~/.config/termgram/session.db. One login is shared
by the CLI, the MCP server and the notifier.
4. Install the binaries
Build the workspace and copy the three binaries into your PATH:
cargo build --release
cp target/release/termgram ~/.local/bin/
cp target/release/termgram-mcp ~/.local/bin/
cp target/release/termgram-notify ~/.local/bin/Or install each crate from crates.io with cargo install termgram-cli termgram-mcp termgram-notify, or from source with cargo install --path crates/cli,
cargo install --path crates/mcp, cargo install --path crates/notify.
Prebuilt binaries are attached to every GitHub
release.
CLI
Send anything, one command
termgram send saved 'hello' # plain text
termgram send saved '**bold** text' --format md # rich text
termgram send saved 'see you' --date '14/09 17:00' --date '15/09 09:00'
termgram send saved 'photo' --file shot.png # photo / document / voice
termgram send saved --file a.png --file b.png # album
termgram send someone --at '16:00' # scheduled
termgram send saved 'into a topic' --topic 42 # forum topic
termgram send saved 'reply me' --reply 1108131 # reply--date repeats to add more tappable date chips. Formats are plain, md,
and html.
Everyday commands
termgram dialogs # all chats, unread counts, last message
termgram messages saved # recent messages, newest last
termgram watch saved # tail a chat live
termgram watch --unread # survey chats with unread messages
termgram read saved # mark as read
termgram sync # index everything locally
termgram search 'query' # search the local mirror
termgram search --chat someone 'query'
termgram poll saved 'which one' red green blue --multi --anon
termgram react saved 1108131 🎉 # Premium required to send
termgram profile someone # full profile
termgram status someone # online status
termgram kick group user # and: ban, unban, promote, members, pinned
termgram export ~/termgram-backupFull surface: me men dialogs messages read watch send edit delete forward pin react reactions drafts draft profile set block unblock typing status scheduled cancel contacts folders folder-new folder-rm pinned members kick ban unban promote grab export import wipe poll topics search searchin searchall sync cached.
Text formats
Markdown and HTML are parsed into real Telegram entities before sending. Dates rendered this way become tappable chips, not raw text.
Local search mirror
termgram sync # index dialogs + recent messages
termgram search 'query' # offline search across all chats
termgram cached someone 50 # last 50 cached messages
termgram searchall 'x' # global Telegram search (API)
termgram searchin someone 'x' # search inside one chat (API)Chat names match case-insensitively (someone = SOMEONE). Searching a chat that
isn't mirrored auto-syncs it; if the mirror still has nothing, it falls back to
a live API search.
MCP server
termgram-mcp speaks the Model Context Protocol over stdio. Register it
with your MCP client; for opencode:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"termgram": {
"type": "local",
"command": ["/home/you/.local/bin/termgram-mcp"],
"enabled": true
}
}
}Or in any standard MCP client:
{
"mcpServers": {
"termgram": {
"command": "/home/you/.local/bin/termgram-mcp",
"args": []
}
}
}termgram-mcp --catalog starts a session-less mode that answers only MCP
discovery calls (no Telegram connection). It exists so directory services can
introspect the server without credentials.
Tools
Every CLI command is exposed as a tool. send accepts the same unified model
(text, files, format, dates, reply, topic, at), plus poll,
topics, watch, upload, album, voice, schedule, scheduled,
cancel, edit, draft, drafts, react, reactions, search /
searchin / searchall, sync, mirror access, admin tools, and
export / import / wipe.
Push notifications
The MCP server pushes every new incoming message to the client as a server→client custom notification:
method: notifications/termgram/message
params: {
"chat": "-1001234567890", // dialog id (negative = group/channel)
"id": 423,
"at": 1770000000, // unix timestamp
"out": false, // true when the message is your own
"from": "Alice", // sender display name
"text": "hey, check this",
"media": "photo" // photo|document|sticker|contact|poll|…, null if none
}Pushes are off by default. Control them with the notify tool:
Call | Effect |
| push only that chat |
| push every chat |
| stop pushing that chat |
| stop all pushes |
SSE stream
termgram-notify is a tiny standalone HTTP server (no extra deps, one
process). It streams the same new-message events as text/event-stream:
termgram-notify & # binds 127.0.0.1:6837
curl -N http://127.0.0.1:6837/events # all chats
curl -N 'http://127.0.0.1:6837/events?chat=178220800' # one chatEach event is a single data: line with the same JSON shape as the MCP
notification, followed by a blank line. A : ping comment heartbeat arrives
every 15 seconds to keep the connection alive. Override the port with
TERMGRAM_NOTIFY_PORT, filter with the query string, and connect from a
browser, curl, or any SSE client.
A note on streams
An MCP or SSE connection streams the account's incoming events. Messages tied
to an exchange that happens on a different live session (for example, another
terminal's running termgram process replying to a bot) can stay on that
session's feed instead of reaching your stream. In the common case the same
process that sends also pushes, so nothing is missed. The MTProto layer
guarantees constant streaming, not per-session lockstep.
How it's built
Single Rust workspace, four crates:
Crate | Binary | Role |
| — | MTProto client, signals, config, mirror, media, every operation |
|
| the terminal client |
|
| MCP server over stdio + push notifications |
|
| SSE HTTP push server |
All three binaries share one session and config. The core exposes a broadcast
Update stream so the CLI, MCP server and notifier all wake instantly on new
messages.
Security
Credentials (
api_id,api_hash) and your session live only in~/.config/termgram/, never in this repository.The notifier binds to
127.0.0.1only.Nothing in the push payloads stores or forwards your secrets.
Notes
Reacting with new emoji requires Telegram Premium; reading reactions works for everyone.
Two termgram processes on the same account share one
session.db. Run long-lived watchers on their own; concurrent write commands may surfacedatabase is locked.
Contributing
This project is actively looking for maintainers. The current maintainer uses termgram daily but isn't adding features; if you want it to keep evolving, the maintainer seat can be yours. Report bugs, open issues for direction, send PRs, or volunteer to co-maintain. Start with CONTRIBUTING.md. Small PRs merge fast; big ones get discussed in an issue first.
License
Available Tools
61 toolsadd_contactC
Add a contact by phone number
Inputs: no named parameters.
albumB
Send multiple files as one media album (caption is plain text)
Inputs: no named parameters.
banC
Ban a user in a channel
Inputs: no named parameters.
blockC
Block a user
Inputs: no named parameters.
block_listC
List blocked users
Inputs: no named parameters.
cachedB
Read cached messages of a chat from the local mirror
Inputs: no named parameters.
cancelB
Cancel a scheduled message of a chat
Inputs: no named parameters.
contactsB
List contacts of the account
Inputs: no named parameters.
deleteC
Delete messages from a chat
Inputs: no named parameters.
delete_contactC
Delete a contact
Inputs: no named parameters.
del_photoB
Remove the profile photo of a chat
Inputs: no named parameters.
dialogsB
List chats with unread count and last message preview
Inputs: no named parameters.
downloadA
Download media from a chat message to the local media dir
Inputs: no named parameters.
draftC
Save or clear a draft in a chat
Inputs: no named parameters.
draftsB
List all saved drafts
Inputs: no named parameters.
editC
Edit a message you sent
Inputs: no named parameters.
exportB
Export the account session, mirror and config to a folder
Inputs: no named parameters.
export_contactsB
Export all contacts of the account
Inputs: no named parameters.
folder_newC
Create a chat folder with the given chats
Inputs: no named parameters.
folder_rmB
Delete a chat folder
Inputs: no named parameters.
foldersB
List chat folders
Inputs: no named parameters.
forwardC
Forward messages between chats
Inputs: no named parameters.
grabC
Download every media of a chat into the local media dir
Inputs: no named parameters.
importB
Import an exported account folder into this session
Inputs: no named parameters.
import_contactsB
Import contacts by phone number
Inputs: no named parameters.
kickB
Kick a user from a group
Inputs: no named parameters.
loginA
Check login state; interactive OTP login only via termgram login in a terminal
Inputs: no named parameters.
logoutB
Log out the current session
Inputs: no named parameters.
meA
Show the logged-in account identity
Inputs: no named parameters.
membersB
List members of a group or channel
Inputs: no named parameters.
messagesB
Show recent messages in a chat, newest last
Inputs: no named parameters.
notifyC
Control the server-to-client push filter for new-message notifications
Inputs: no named parameters.
photoB
Send a photo to a chat (caption is rich text)
Inputs: no named parameters.
pinB
Pin or unpin a message in a chat
Inputs: no named parameters.
pinnedB
List pinned messages of a chat
Inputs: no named parameters.
pollC
Create a poll in a chat with 2 to 10 answer options
Inputs: no named parameters.
profileC
Show a user's full profile
Inputs: no named parameters.
promoteB
Promote a user to admin in a channel
Inputs: no named parameters.
reactB
React to a message with an emoji, or remove the reaction
Inputs: no named parameters.
reactionsC
List the reactions on a message
Inputs: no named parameters.
readB
Mark a chat as read
Inputs: no named parameters.
scheduleB
Schedule a rich text message for a future unix timestamp
Inputs: no named parameters.
scheduledC
List scheduled messages of a chat
Inputs: no named parameters.
searchB
Search the local sync mirror for messages
Inputs: no named parameters.
searchallB
Search all chats in the local sync mirror
Inputs: no named parameters.
searchinC
Search messages within one chat
Inputs: no named parameters.
sendC
Send text and/or files to a chat
Inputs: no named parameters.
setbioB
Set your account bio
Inputs: no named parameters.
setnameC
Set your account first and last name
Inputs: no named parameters.
setphotoB
Set your account profile photo from a local file
Inputs: no named parameters.
statusC
Show a user's online status
Inputs: no named parameters.
syncB
Sync dialog list and recent messages into the local search mirror
Inputs: no named parameters.
topicsB
List forum topics in a forum-enabled chat
Inputs: no named parameters.
typingB
Broadcast a typing action in a chat
Inputs: no named parameters.
unbanC
Unban a user in a channel
Inputs: no named parameters.
unblockC
Unblock a user
Inputs: no named parameters.
uploadB
Upload a file to a chat (sends a photo, document, or voice note by type; caption is rich text)
Inputs: no named parameters.
voiceC
Send an audio file as a voice message
Inputs: no named parameters.
waitA
Wait (push, no polling) until a new message arrives
Inputs: no named parameters.
watchC
Snapshot the last messages of a chat, or the latest dialogs when target is omitted
Inputs: no named parameters.
wipeA
Delete the session, mirror and media of the current account
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 61 tools
Several clusters overlap heavily: send/upload/photo/voice/album all send media, search/searchall/searchin all search the mirror, and export/export_contacts, import/import_contacts, ban/kick/block, schedule/scheduled/cancel, draft/drafts, pin/pinned, and react/reactions blur boundaries. Descriptions help somewhat, but an agent could easily misselect among these near-duplicates.
Mostly lowercase, but patterns are inconsistent: some compounds use underscores (add_contact, delete_contact, block_list, del_photo), others concatenate (setname, searchall, searchin, setbio, setphoto), and some are noun_verb (folder_new, folder_rm) while others are verb_noun (add_contact). The abbreviation mix of 'del_photo' versus 'delete_contact' further breaks consistency.
61 tools is excessive for a chat client MCP. Many are micro-operations (typing, status, notify, wait, watch) or near-duplicate media/search/contact commands, inflating the surface far beyond a well-scoped set.
The surface is broad—auth, messaging, media, contacts, groups/channels, folders, profiles, sync/search, scheduling, drafts, and session export/import/wipe. Gaps include creating/joining/leaving chats, inviting members, archiving/muting, and detailed chat info, but these are minor for most workflows.
Maintenance
Related MCP Connectors
Multi-tenant Telegram gateway for AI agents — HTTP+stdio, 8 tools, MTProto User API
Telegram bridge for your MCP-compatible agent. Bidirectional, no LLM in our stack.
Real-time chat for AI agents. Claude Code, Cursor, Cline and Codex join channels over MCP.
Real-time chat hub for AI agents — Claude Code, Cursor, Cline, Codex over MCP or REST.
Related MCP Servers
- MIT
- AlicenseAqualityBmaintenanceFast MCP Telegram — Production-grade Telegram MCP server with direct MTProto API, multi-user ACL, dual transport (stdio + HTTP SSE), voice transcription, and context-optimized design. One-command setup with uvx fast-mcp-telegram8369 PyPI50MIT
- AlicenseNot gradedqualityDmaintenancePrivacy-first Telegram MCP server enabling maintainers to triage chats, inspect context, search messages, draft replies, and send authorized messages locally without a cloud relay.57 npm1MIT
- AlicenseAqualityCmaintenanceAn MCP server that lets an LLM send messages, photos, and documents to Telegram through a bot. Provides four tools: get_me, send_message, send_photo, and send_document.4MIT