macOS · open source · MIT

Your Telegram, as Markdown files

tg-archive keeps a copy of your own Telegram chats on your own disk — readable in any text editor, searchable, and updated within seconds of a message arriving. Claude can read and write it too.

This is what ends up on your disk — one file per chat per month:

## 2026-08-19
14:32 · Anna ↳ replying to “are you around tomorrow?”: yes, after 6
14:33 · me [voice 12s] 👍
14:41 · Anna (edited): make it 7, actually
Is this allowed? Yes. Telegram publishes the protocol its own apps use, and this is a normal client signing in as you, on your account, reading your own messages. It is not scraping anyone else's data.

Part 1 — Install

1

Get Homebrew, if you don't have it

Homebrew installs command-line software on a Mac. Open Terminal (press ⌘ Space, type “Terminal”, hit Enter) and paste:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Already have it? Skip to step 2. To check, type brew --version.

2

Install tg-archive

brew install tggo/tap/tg-archive

Verify it landed:

tg-archive version
“command not found”? Close the Terminal window and open a new one — Homebrew adds itself to your PATH only for new sessions.
On Linux instead?

Homebrew is a Mac thing, but the same program is built for Linux — useful for keeping the archive current on a server:

curl -LO https://github.com/tggo/tg-archive/releases/latest/download/tg-archive_0.2.0_linux_amd64.tar.gz
tar -xzf tg-archive_0.2.0_linux_amd64.tar.gz
sudo install tg-archive /usr/local/bin/

Use arm64 instead of amd64 on ARM machines. Everything below works the same, except brew services — run tg-archive live under systemd or in a container.

Part 2 — Get your API keys

Telegram hands out API credentials per account. Every client needs a pair, and yours are not shared with anyone — not even with this project. It takes about two minutes.

1

Open my.telegram.org

Go to my.telegram.org and type your phone number in international format, including the country code: +380671234567, +12025550123.

2

Take the code from Telegram itself

The confirmation code is not an SMS. It arrives as a message inside Telegram, in the chat called Telegram — open the app on your phone or desktop and look there.

Never give that code to anyone. Telegram support will never ask for it, and anyone who does is trying to take your account. You are typing it into Telegram's own website here, which is the one place it belongs.
3

API development tools → create an app

After signing in, click API development tools. Fill the short form:

FieldWhat to put
App titletg-archive — any name, only you see it
Short nametgarchive
URLleave empty
PlatformDesktop
Descriptionleave empty

Press Create application. The next page shows two values:

ValueLooks like
api_ida number, e.g. 2040815
api_hash32 letters and digits
Treat api_hash like a password. Don't post it in issues, screenshots, or chats. If it leaks, you can create a new application.

Part 3 — First run

1

Answer the setup questions

tg-archive setup

It asks, one at a time — press Enter to accept anything in brackets:

QuestionAnswer
api_id / api_hashpaste what you just got
where to write the archiveEnter for ~/TelegramArchive, or your own path
timezoneEurope/Kyiv, America/New_York… or Local
private chats / groups / Saved Messagesy — the useful stuff
channels you follow / bot chatsn unless you want the noise
2

Sign in

tg-archive login

Phone number, then the code (again: it arrives inside Telegram), then your cloud password if you use two-step verification. You do this once — the session is stored on your Mac.

3

Pull your history

tg-archive backfill

This walks every chat from newest to oldest. Years of chats take a while — tens of minutes to a few hours, and Telegram will slow it down on purpose at times, which the tool waits out. You can stop it any time with Ctrl-C and run it again later; it resumes where it left off rather than starting over.

Want a taste first? Grab the last 200 messages of each chat:

tg-archive backfill --limit 200
4

Keep it up to date

Run it as a background service, so new messages land in the archive within seconds:

brew services start tggo/tap/tg-archive

Or run it in a window while you watch:

tg-archive live

What you get

~/TelegramArchive/
├── index.md                      ← table of every chat
└── chats/
    └── anna-smith-428424641/
        ├── 2017-05.md
        └── 2026-08.md            ← one file per month

Point Obsidian at that folder and it becomes a searchable, linkable notebook of your conversations. Or just use Spotlight, grep, or any editor — they are ordinary text files.

Why edits and deletions are honest

Messages go into a small database first, and the Markdown is redrawn from it. So when someone edits a message, the archive updates that line and marks it (edited); when someone deletes one, the archive keeps it and marks it (DELETED). You can rebuild every file at any time, with no internet:

tg-archive rerender
Media is not downloaded. Photos, files and voice notes leave a marker like [voice 12s] or [file report.pdf 2.1MB]. That keeps years of chats down to tens of megabytes instead of hundreds of gigabytes.

Search runs on a full-text index, so it is instant even on hundreds of thousands of messages, and it is not fooled by capital letters in Ukrainian, Russian or Greek — which plain substring search is.

tg-archive search "delivery address"
tg-archive search "фундамент" --chat VABRAM --from 2026-01-01

Several words must all appear. "in quotes" is an exact phrase, word* matches a prefix, and you can narrow by --chat, --sender, --from, --to.

Photos, voice notes and files

By default only markers are stored. To keep the files themselves, set "media": "small" (or "all") in the config and run:

tg-archive media

They land in attachments/, and the Markdown starts showing the picture inline in Obsidian instead of the word [photo].

Is anything missing?

tg-archive doctor          # what is missing
tg-archive doctor --fix    # fetch it
It tells you two separate things: chats it never walked back to the very first message, and gaps inside supergroups and channels. It deliberately does not report gaps in private chats — Telegram numbers those messages per account, so a jump in numbering there means you wrote somewhere else in between, not that anything was lost.

A second account

tg-archive --profile work setup
tg-archive --profile work backfill

Separate settings, separate login, separate archive.

Part 5 — Let Claude use it

The same program can act as an MCP server, which is how Claude connects to tools on your machine. One command:

claude mcp add tg-archive -- tg-archive mcp

Now you can ask Claude things like “what did Anna say about the trip in June?” or “find every message where someone sent me an address”. It reads the local archive, so answers are instant and work even with no connection.

If you also want Claude to send messages

claude mcp add tg-archive -- tg-archive mcp --allow-send
Think before enabling this. A tool that can message your contacts is a different kind of risk from one that reads a local file. Sending is off unless you pass that flag, and the tool is marked so Claude asks before using it.
What Claude can doWhere the data comes from
list_chats, read_chat, search_messages, archive_statusyour local archive — instant, offline
sync_chat, download_media, check_archiveTelegram, to fetch what is new or missing
send_messageTelegram — only with --allow-send

Claude Desktop instead of Claude Code

Claude Desktop doesn't have the claude mcp add command — it reads its own config file instead. Open (or create):

~/Library/Application Support/Claude/claude_desktop_config.json

and add tg-archive under mcpServers:

{
  "mcpServers": {
    "tg-archive": {
      "command": "/opt/homebrew/bin/tg-archive",
      "args": ["mcp"]
    }
  }
}
Use the full path to the binary, not just tg-archive — Desktop apps don't see your shell's PATH. Run which tg-archive in Terminal to find it (Homebrew on Apple Silicon installs to /opt/homebrew/bin, Intel Macs to /usr/local/bin). Add "--allow-send" to the args list if you also want sending, then quit and reopen Claude Desktop.

Command cheat sheet

CommandWhat it does
tg-archive setupAsk the setup questions again
tg-archive loginSign in to Telegram
tg-archive chatsList your chats and their ids
tg-archive backfillPull history (resumable)
tg-archive liveWatch for new messages
tg-archive search "words"Search the archive
tg-archive mediaDownload attachments
tg-archive doctorCheck for missing history
tg-archive statusHow much is archived
tg-archive send --chat "Anna" --text "on my way"Send a message
tg-archive rerenderRebuild all files from the database
tg-archive mcpServe the archive to Claude

When something goes wrong

“no config … run `tg-archive setup`”

You skipped Part 3, or you are running as a different user than the one you set up. Run tg-archive setup.

macOS says the app “cannot be opened” or is from an unidentified developer

Installing through Homebrew avoids this entirely — Homebrew doesn't mark downloads as quarantined. If you downloaded the tarball with a browser instead, macOS holds it until the build is notarized by Apple. Use brew install tggo/tap/tg-archive.

The login code never arrives

It is sent inside Telegram, not by SMS — open the app and look for the chat named Telegram. If you are signed out everywhere, Telegram falls back to SMS, which can take a few minutes.

It asks for a password after the code

That is two-step verification (a “cloud password”) that you set up in Telegram earlier. It is not your phone passcode and not the login code. Forgot it? Telegram can reset it from Settings → Privacy and Security → Two-Step Verification.

backfill is slow, or pauses for minutes

Normal. Telegram rate-limits history requests and asks clients to wait; tg-archive waits instead of hammering, which is what keeps your account in good standing. Leave it running, or stop it and continue later — progress is saved.

A chat shows a number instead of a name

That account was deleted, so Telegram no longer serves a name for it. The messages are still archived.

My secret chats are missing

Secret chats are end-to-end encrypted and stored only on the two devices that created them. No client can export them — not this one, not Telegram Desktop. Nothing to fix.

I want to start over

Delete ~/.config/tg-archive (settings and session) and your archive folder, then run tg-archive setup again. Removing the session here does not log you out of Telegram elsewhere; to revoke it from Telegram's side, use Settings → Devices.

Fair warnings

Don't bulk-messageThis signs in as you. Telegram bans accounts for mass sending, and a ban takes your archive's access with it.
The archive is plain textAnyone with access to your Mac (or your backups) can read it. Put it on an encrypted disk — FileVault covers your internal drive.
Other people are in itYour chats contain their words too. Publishing them is your call and your responsibility.