Skip to main content
Glama

termgram

crates.io GitHub release ci license

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/html formatting parsed into real Telegram entities, tappable date chips, photos, documents, voice notes, albums, replies, scheduling, forum topics. All through one send command.

  • Local search mirror. sync once, 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; wait blocks 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 code

Your 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-backup

Full 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

notify { on: true, target: "@someone" }

push only that chat

notify { on: true }

push every chat

notify { on: false, target: "@someone" }

stop pushing that chat

notify { on: false }

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 chat

Each 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

crates/core

—

MTProto client, signals, config, mirror, media, every operation

crates/cli

termgram

the terminal client

crates/mcp

termgram-mcp

MCP server over stdio + push notifications

crates/notify

termgram-notify

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.1 only.

  • 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 surface database 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

MIT

Available Tools

61 tools
add_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.

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

    C2.5/5.0

    Scored across 61 tools

    Disambiguation2/5

    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.

    Naming Consistency2/5

    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.

    Tool Count1/5

    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.

    Completeness4/5

    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

    ActivityMaintained
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      B
      maintenance
      Fast 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-telegram
      8
      369 PyPI
      50
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Privacy-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 npm
      1
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      An 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.
      4
      MIT