Skip to main content
Glama
FinchGram

FinchGram

Official
by FinchGram

FinchGram

English · 简体中文 · 繁體中文 · Español · Português · Deutsch · Français · Русский · 日本語 · 한국어 · العربية

A Telegram desktop client with superpowers, in Rust and Slint. Open source under the GPL-3.0. macOS on Apple silicon today; Windows and Linux later.

FinchGram talks to Telegram through TDLib, Telegram's own library, and keeps to the Telegram API terms. It is an unofficial client, not made by Telegram.

What it does

  • Chats. Log in with your phone number, the code and your two-step password, or by scanning a QR code; sign up for a new account. The chat list with Telegram's folders, pinned chats, unread counts and mentions; a search over everything (⌘K): your chats and contacts, public users, groups and channels by username, people by phone number, and messages; a search within a chat (⌘F); a view of your channels and one of your bots. The pencil makes a new group, channel or chat, or adds a contact. Several accounts, up to ten, each with a TDLib of its own: switch from the account menu or with ⌘1 … ⌘0. Manage your groups and channels: photo, name and description, public username or invite links, members and administrators with their rights, member permissions, slow mode, join approval and topics; a channel's signatures and discussion group.

  • Messages. Text with its formatting (bold, italic, code, links), replies and forwards, photos, videos, GIFs, stickers, files, and a card for a link's preview. A right click on a message gives its menu: reply, edit, copy, copy its link, forward, report, delete, or choose several. Photos and videos sent to self-destruct are shown blurred and opened once, as in Telegram's own apps. Bots' buttons under their messages, their keyboards, commands and menu button; the chat's pinned message under the header. A chat that protects its content is left out of screenshots and screen recordings while it is in front. Reactions, with a picker and a double click for the default one; round video messages played in place; contact cards with Message, Add contact and Share; sharing a post or a card to several chats at once; drafts kept per chat and across devices; groups with topics open on their topics; slow mode counted down in the composer, and a group's rules or, for its administrators, its permissions and options in the chat settings panel.

  • Media. Photos and videos open in a viewer over the window, with the rest of their album; video plays through mpv, built from source. Saving to Downloads where the chat allows it.

  • Downloads. A download client in the media center, over WebDAV, FTP, FTPS or SFTP: your NAS, a seedbox, PikPak, Alist/OpenList or a folder shared with vget serve, browsed in the app. Files come over several connections at once and go on after a stop; photos and videos open in the viewer when they arrive; passwords stay sealed in FinchGram's database. See docs/downloads.md.

  • Sending. Photos, videos and files from the paperclip, by dragging them onto the window, or by pasting them. A card shows them before they go: with a caption, as a photo or as a file, together as an album of up to ten, with a self-destruct timer in a private chat, without sound.

  • Screenshots. The scissors in the composer, or ⌘⇧A, freeze the screen: take a window or drag a selection, draw rectangles, ellipses, arrows, pen strokes, text and mosaic on it, then send it, copy it or save it. As in WeChat, from every chat.

  • A chat's menu. Mute, pin, copy its ID, put it into a folder; block or unblock a person, report, leave a group or channel, delete a chat. A right click on a folder marks all of its chats as read, or sorts the chats: by the latest message, by name, or by unread messages, the pinned ones staying on top.

  • Notifications. New messages come as macOS notifications and their number sits on the Dock icon; FinchGram stays in the Dock when its window closes, and can live in the menu bar.

  • Three themes. Workbench, Broadsheet and Terminal, each light and dark, switched without a restart.

  • Settings. Launch at login, Send with Enter, the screenshot shortcut, notification sounds and previews, two-step verification, the interface language, and updates: the app updates itself from GitHub Releases and installs nothing it cannot verify.

  • Voice messages. Play them in the chat, with their waveform, the time and 1×, 1.5× or 2×; listening tells the sender, as in Telegram's own apps. Hold the microphone to record one: let go to send it, drag left to cancel, drag up to lock it, then stop it to listen before it goes.

  • Voice input. Press the sparkle in the composer and speak: the words go into the box for you to send. You add your AI vendors, each a name, an API format, your own key and, if you like, your own address (a relay, or a server on your network). Voice input, tidying its words of um and uh, and transcribing voice messages are three features, each with its own switch, and you choose each one's AI vendor and model from lists; nothing is chosen for you. For speech: OpenAI's realtime transcription, Qwen and Doubao (both strong in Chinese), or any service that speaks OpenAI's transcription API; for tidying: OpenAI's, Anthropic's or Gemini's format. Words of other languages mixed in are kept as you say them. Toolbox → AI → Voice input, off until you turn it on. Transcribe under a voice message uses Telegram's own transcription, or, once you turn that on, your own AI vendor. See docs/voice-input.md.

  • AI assistants. Claude Desktop, Claude Code and other apps that speak the Model Context Protocol can read your chats and act in them through FinchGram, once you let them: Toolbox → AI access, off until you turn it on, with the chats you choose and whether an assistant may send, and a question the first time an app connects. See docs/mcp.md.

  • Languages. The interface and this README in eleven languages.

Not there yet: secret chats and calls, polls and scheduled messages, keyword filters, Windows and Linux. See what comes next.

Related MCP server: tlgrm

Download

Get FinchGram-<version>-macos-arm64.zip from the latest release, unzip it and move FinchGram into Applications. It needs macOS 12 or newer on Apple silicon. The app is signed with North Brookville LLC's Developer ID and notarized by Apple, so it opens like any other app. From then on it updates itself.

Every release comes with SHA256SUMS and its Ed25519 signature. The app checks both before it installs an update; so can you, with the public key in release-signing.pub.

Three themes

Workbench

Broadsheet

Terminal

Workbench

Broadsheet

Terminal

Workbench, the default, is a working window with tabs. Broadsheet reads like a newspaper, with an accent colour per account. Terminal is a monospace screen with commands. Each has a light and a dark side, following the system or your choice, in Settings → Appearance.

The screenshot tool

Press ⌘⇧A, or the scissors next to the paperclip. The screen freezes, dimmed, under an overlay: you drag a selection, with a magnifier and the size in pixels, or click a window to take it whole. The toolbar draws rectangles, ellipses, arrows, pen strokes, text and mosaic, in three sizes and six colours, with undo. Done puts the picture into the send card, where a caption can go with it; ⌘C copies it; ⌘S saves it to Downloads. Settings → General → Screenshots holds the shortcut and whether the FinchGram window hides meanwhile.

AI assistants

FinchGram is an MCP server: an AI assistant's app on your Mac (Claude Desktop, Claude Code, Cursor…) can read your Telegram and act in it through the running app, with your own account. Toolbox → AI access is the switch, off by default. There you choose which chats an assistant may see (all but secret chats, or only chosen ones) and what it may write (messages under your name, drafts only for you to send, or nothing), and you see which apps have connected, with their names as macOS reports them, and what they asked for. The first time an app connects, FinchGram asks whether to allow it. Reading marks nothing as read, secret chats are never shown, and nothing is kept for an AI. The page gives the line to paste into Claude Code or Claude Desktop; docs/mcp.md has the details.

The Downloads page

View → Downloads, or the download icon above the gear. Add a server over WebDAV, FTP, FTPS or SFTP (a NAS, a seedbox, PikPak, Alist/OpenList, Nextcloud, rclone serve webdav, or a folder shared with vget serve), browse its folders, tick files or take a whole folder, and they arrive in ~/Documents/FinchGram/webdav: each file in 8 MB chunks over up to twelve connections, going on from where it stopped after a Retry, as the maintainer's command-line tool vget does. The queue on the right shows the speed and what is left; Open fetches a photo or video and shows it in the viewer. FinchGram changes nothing on a server unless you allow it for that server (then it can delete, move, rename and upload there), and the password goes sealed into FinchGram's database, never into a plain file. docs/downloads.md has the details and what is not there yet (a self-signed certificate is refused: use http on the LAN, or a real certificate).

How it is built

The app is a shell. Telegram itself is done by TDLib, running as a separate program next to the executable, finchgram-tdlib, which this repository builds from pinned sources; the shell talks to it only through src/telegram/, in TDLib's own JSON. Video plays through libmpv, built the same way. Nothing is taken from the user's machine, and a build downloads nothing but these pinned, checksummed builds. Everything is public: the source, the vendor builds (vendor/) and the releases. See docs/architecture.md and docs/conventions.md.

Telegram's rules

FinchGram does what Telegram's own apps do, and nothing they forbid. A message is marked read when you see it, the other side sees you typing and online as in any Telegram app, sponsored messages in channels are shown, self-destructing media opens once, and nothing from Telegram goes to any AI unless you let an assistant in (Toolbox → AI access) or turn on transcribing voice messages with your own AI vendor. Nothing leaves your machine except to Telegram, to GitHub for updates, and, while you use voice input, your voice to the AI vendor you chose, under your own key.

Development

Development needs macOS on Apple silicon for now: finchgram-tdlib is only built for it. Linux and Windows will follow.

finchgram-tdlib, libmpv and the UI fonts are not in git: vendor/tdlib/ and vendor/mpv/ only hold the scripts that build them, and the fonts come from Google Fonts. After cloning, get them once:

scripts/fetch-tdlib.sh    # downloads the pinned finchgram-tdlib release into vendor/tdlib/bin/ and verifies the SHA-256
scripts/fetch-mpv.sh      # downloads the pinned libmpv release into vendor/mpv/bin/ and verifies the SHA-256
scripts/fetch-fonts.sh    # downloads the pinned UI fonts into vendor/fonts/ and verifies their SHA-256
FINCHGRAM_API_ID=… FINCHGRAM_API_HASH=… cargo run
  • To change finchgram-tdlib itself, build it here (a few minutes; needs Xcode or the Command Line Tools, and brew install cmake ninja gperf, build tools only):

    vendor/tdlib/build.sh && vendor/tdlib/build.sh install
  • FINCHGRAM_API_ID and FINCHGRAM_API_HASH: your own, from my.telegram.org → API development tools. They are read when compiling and never belong in the repository. Without them the app starts and says it has no API ID.

  • FINCHGRAM_TEST_DC=1 cargo run uses Telegram's test servers, which have their own accounts; the app keeps a separate database for them.

  • cargo test screenshots -- --ignored draws every page in every theme, light and dark, with made-up chats, into target/screenshots/: a way to look at the UI without an account.

build.rs copies vendor/tdlib/bin/finchgram-tdlib next to the compiled executable, so cargo run uses exactly the same program as the packaged app; it links libmpv from vendor/mpv/bin/ and copies it there too, and the fonts in vendor/fonts/ are compiled into the executable. Without any of them the build fails with a message saying so. Rust 1.92 or newer.

TDLib's database and downloaded files are in ~/Library/Application Support/FinchGram/tdlib/, the settings in ~/Library/Application Support/FinchGram/settings.toml.

Layout

.github/workflows/
  mpv.yml                # builds libmpv on a clean runner; publishes mpv-* tags as releases
  check.yml              # clippy and the tests on every push to main
  release.yml            # for the Release v* commits: compiles the app on Blacksmith, signs and publishes it on GitHub
  tdlib.yml              # builds finchgram-tdlib on a clean runner; publishes tdlib-* tags as releases
Cargo.toml
build.rs                 # compiles ui/app.slint, bundles lang/, copies vendor/tdlib/bin/ next to the executable
crates/
  finchgram-release-sign/ # the Ed25519 signing tool behind releases, a package of its own
docs/                    # architecture.md, conventions.md, downloads.md, drag-and-drop.md, media-files.md, skia.md (+ zh-Hans)
  screenshots/           #   the pictures the READMEs show, from the picture test (scripts/readme-pictures.sh)
lang/                    # translations: lang/<code>/LC_MESSAGES/finchgram.po, compiled into the binary
readme/                  # this README in other languages
release-signing.pub      # the public keys allowed to sign releases; compiled into the app
scripts/
  bundle.sh              # builds dist/FinchGram.app (what the release workflow runs)
  fetch-fonts.sh         # the pinned UI fonts into vendor/fonts/
  fetch-mpv.sh           # the pinned libmpv release into vendor/mpv/bin/
  fetch-tdlib.sh         # the pinned finchgram-tdlib release into vendor/tdlib/bin/
  readme-pictures.sh     # copies the READMEs' pictures from target/screenshots/ into docs/screenshots/
  release.sh             # starts a release: version, tag, push; GitHub Actions does the rest
  sign.sh                # signs the app: ad hoc, or with the Developer ID in the release workflow
src/
  main.rs                # the window, the settings, the language and theme, updates; starts Telegram
  fonts.rs               # the UI fonts, compiled into the executable
  images.rs              # pictures in messages, decoded off the UI thread
  telegram/              # the only code that talks to finchgram-tdlib
    process.rs           #   runs the program: TDLib's JSON over standard input and output
    api.rs               #   the TDLib types FinchGram uses (td_api.tl of the pinned version)
    mod.rs               #   requests and answers, starting again; updates go to the store
    store.rs             #   what TDLib said about chats, users and messages; the pages' models
    login.rs             #   logging in, signing up
    chats.rs             #   the chat list
    conversation.rs      #   the open chat: messages, writing
    actions.rs           #   what can be done with a message: its menu, replies, forwarding, …
    account.rs           #   the profile, logging out
    password.rs          #   two-step verification in Settings
    files.rs             #   downloading files
    avatars.rs           #   the photos of chats and people, shown instead of their letters
    viewer.rs            #   the media viewer: photos, videos, saving to Downloads
    rich_text.rs         #   formatted text: bold, italic, links, …
    notifications.rs     #   notifications of new messages, the unread count on the Dock icon
    online.rs            #   the account is online while the window is in front and in use
  platform/              # what differs from one operating system to another
  player/                # video through libmpv, drawn into the window with OpenGL
  screenshot/            # the screenshot tool: capture, the overlay, annotations, the picture
  downloads/             # the Downloads page: WebDAV, FTP, FTPS and SFTP, with a multi-connection engine
    remote.rs            #   one face on the three clients: list a folder, check a server, fetch a file
    webdav.rs            #   PROPFIND listings, addresses, Basic authentication
    ftp.rs               #   FTP and FTPS over suppaftp: one stream, REST to go on after a stop
    sftp.rs              #   SFTP over russh: chunks over several sessions, the server's key remembered
    transfer.rs          #   a file in chunks over several connections, going on after a stop
    mod.rs               #   the page's state, its threads, the queue, the servers' form
  update.rs              # the self-updater: GitHub Releases, signature check, swap, relaunch
  settings.rs            # the user's preferences (settings.toml)
  i18n.rs                # UI language: saved choice, else the system's, else English
  screenshots.rs         # every page drawn to a PNG (cargo test screenshots -- --ignored)
ui/
  app.slint              # the main window: the menus, and which page shows
  state.slint            # the app's state, shared by Rust and the pages
  telegram.slint         # what Telegram shows: the account, logging in, chats, messages
  downloads.slint        # the Downloads page's state: servers, the folder, the queue
  look.slint             # the theme's colours, type and shapes, for the shared pages
  format.slint           # dates, counts and kinds of message in the UI language
  widgets.slint          # small shared parts; chat.slint: the chat windows' shared parts
  viewer.slint           # the media viewer over the whole window, in each theme's manner
  pages/                 # the pages the three themes share: logging in, settings, the profile, downloads
  workbench/             # the Workbench theme's chat window (the default)
  broadsheet/            # the Broadsheet theme's chat window
  terminal/              # the Terminal theme's chat window
  icons/                 # Phosphor icons (MIT), regular and duotone; icons.slint lists them
  logo/                  # the FinchGram logo (svg, png) and its rules
vendor/fonts/            # not in git: the UI fonts (scripts/fetch-fonts.sh)
vendor/mpv/              # libmpv: mpv and FFmpeg, which play video
  build.sh               #   builds it from pinned sources: versions and SHA-256 at the top
  bin/                   #   not in git: the library (scripts/fetch-mpv.sh, or build.sh install)
vendor/tdlib/            # finchgram-tdlib
  build.sh               #   builds it from pinned sources: TDLib commit, OpenSSL version and SHA-256 at the top
  host/                  #   our small host program (main.cpp) and its CMakeLists.txt
  bin/                   #   not in git: the program the app uses (scripts/fetch-tdlib.sh, or build.sh install)
  work/, dist/           #   not in git: a local build's intermediate files and its package

Translations

Every piece of UI text is written as @tr("English text"). A string has one translation wherever it appears (build.rs turns off Slint's default context); when the same English needs different words somewhere else, give it a context: @tr("menu" => "Open"). Extract with the official tool, then merge into each language:

cargo install slint-tr-extractor                                          # once
find ui -name '*.slint' | sort | xargs slint-tr-extractor --no-default-translation-context -o lang/finchgram.pot
for po in lang/*/LC_MESSAGES/finchgram.po; do msgmerge --update "$po" lang/finchgram.pot; done   # needs brew install gettext

Then fill in the msgstr entries and cargo build again. English is the source language; the other ten ship with it.

Releases

Releases are built only by GitHub Actions, from a tagged commit on a clean runner (.github/workflows/release.yml), and published in this repository: the zipped app, SHA256SUMS, and its Ed25519 signature. Installed copies update themselves from there and install nothing they cannot verify. A maintainer starts a release with one command:

scripts/release.sh patch    # 0.1.0 -> 0.1.1; also minor, major, or an exact version

The app is signed with North Brookville LLC's Apple Developer ID, with the hardened runtime, and notarized by Apple: a downloaded copy opens without a question from Gatekeeper, and updates installed by the app itself do too.

Contributing

Issues and pull requests are welcome. Before changing how things fit together, read docs/architecture.md and docs/conventions.md: every dependency is built from pinned sources by this repository, the UI follows the design in all three themes, and nothing in the app goes against Telegram's API terms. Keep cargo test, cargo clippy --all-targets and cargo test screenshots -- --ignored clean, and look at the pictures. The READMEs' own pictures come from that test too: scripts/readme-pictures.sh refreshes docs/screenshots/.

License

GPL-3.0 (LICENSE). finchgram-tdlib contains TDLib (Boost Software License 1.0) and OpenSSL (Apache License 2.0); the UI fonts are under the SIL Open Font License 1.1, the icons under the MIT license. Their licence texts travel with the app.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server that connects AI assistants to your real Telegram account via User API (MTProto). Features default-deny ACL with per-chat permissions, message search, file sending, forwarding, media downloads, and rate limiting.
    3
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Drives a personal Telegram account from the terminal or via MCP, enabling AI assistants to list chats, send/edit messages, fetch history, manage groups, and more with tiered read/write/destructive permissions.
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    A safe-by-default MCP server for real Telegram accounts powered by TDLib, enabling AI agents to read and act on your account with read-only mode and human approval for destructive actions.
    11
    Apache 2.0