tg-archive
Provides search and retrieval over an archive of public Telegram channel posts, including keyword and semantic search, fetching individual posts, listing recent posts and topics, and viewing archive statistics.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@tg-archivesearch for posts about AI regulation"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
tg-ml-archive
tg-ml-archive copies the posts of public Telegram channels into a SQLite database. An OpenAI model tags each post by topic and writes a one-line English summary. An MCP server lets Claude search the archive by keywords and by meaning. A digest page shows the news of the last 3 days.
systemd timer (hourly) ── ingest.py ──► archive.db (SQLite: posts + FTS5 + sqlite-vec)
├─ enrich.py ─┘ (OpenAI: tags + summary + embeddings)
└─ media.py ──► /var/www/tg-digest/media (pictures and videos for the digest)
systemd timer (daily) ──── digest.py ──► /var/www/tg-digest/index.html + feed.xml
Claude ──HTTPS + token──► Caddy ──► mcp_server.py --httpFile | What it does |
| Gets new posts of each channel in |
| Tags each post with OpenAI (topics, kind, availability, entities, summary) and stores an embedding. |
| Downloads the pictures and videos of new posts for the digest page. |
| Builds the digest page for the latest finished 3-day window. |
| MCP tools: |
| The channel list, the channel descriptions, the topic list, and the digest settings. |
| Scripts and systemd units for the VPS. |
Setup guide
This guide is written so that a person or an AI agent can do it from start to end. Do the parts in this order:
Collect the accounts and values (Part A).
Install the project on your computer and fill the archive (Part B).
Deploy to the VPS (Part C).
Make the MCP server and the digest public over HTTPS (Part D).
Connect Claude (Part E).
If you only want local search on your computer, do Part A, Part B, and step E1.
Rules for AI agents
Do not print, copy into chat, or commit
.env,tg.session, or/etc/tg-archive-mcp.env.tg.sessiongives full access to the Telegram account. Treat it as a password.Only the owner of the Telegram account can type the phone number and the login code. Ask the owner to run step B4 in a terminal.
After the VPS has
tg.session, do not runingest.pyon the local computer. Telegram can revoke a session that runs in two places at the same time.
Part A. Collect the accounts and values
You need these items before you start:
Item | Where to get it | Goes into |
Telegram API ID and API hash | https://my.telegram.org → API development tools |
|
A Telegram account with a phone number | Your own account. The code reads channels as this user. | Login in step B4 |
OpenAI API key |
| |
A VPS with Ubuntu and root SSH key login | Any provider. Tested on Ubuntu 24.04 with 2 GB of memory. |
|
A domain or subdomain that you control | Your DNS provider |
|
The public channels to archive | The |
|
The local computer needs git, ssh, rsync, sqlite3, and uv. macOS and Linux both work.
Part B. Install locally and fill the archive
B1. Clone the repo and install the dependencies:
git clone <repo-url> tg-ml-archive
cd tg-ml-archive
uv syncB2. Make the .env file:
cp .env.example .envThen open .env and set these keys: TG_API_ID, TG_API_HASH, OPENAI_API_KEY, DEPLOY_HOST, DOMAIN.
Leave MCP_TOKEN empty. Step D1 makes the token on the server.
B3. Edit channels.toml:
Put your channels in the
channelslist (public usernames, with or without@).In
[about], write one description for each channel. Use the username in lowercase as the key. The tagger reads this text, so describe what the channel posts and how its posts look.In
[strip], remove the entries of channels that you do not archive. Add a regular expression only if a channel repeats an ad footer.Change
[topics],[kinds], and[availability]only if you need a different taxonomy.
B4. Get the posts (the account owner must do this step):
uv run ingest.pyOn the first run, Telethon asks for the phone number and the login code. Then it saves tg.session and downloads the full history of each channel. A large channel can take some minutes.
Expected result: ingest.py prints the number of new posts for each channel.
B5. Tag a small sample, then examine the tags:
uv run enrich.py --sample 20
sqlite3 archive.db "select summary, topics, kind from posts where enriched_at is not null order by random() limit 20"If the tags are wrong, improve [about] and [topics] in channels.toml. Then run the sample again.
B6. Tag and embed all posts:
uv run enrich.pyThis step sends every post to OpenAI once. The cost depends on the number of posts and on TAG_MODEL (default gpt-5-mini).
B7. Do a test of the local search:
claude mcp add tg-archive -- uv run --directory "$PWD" mcp_server.pyThen ask Claude a question about the channels. Claude must call the tg-archive tools.
Part C. Deploy to the VPS
C1. Make sure that SSH key login to the VPS works without a password prompt:
ssh -o BatchMode=yes "$(grep '^DEPLOY_HOST=' .env | cut -d= -f2)" true && echo okC2. Copy the code, the secrets, and the database to the VPS:
deploy/push.sh --with-dataThe script does these steps:
It makes the system users
tgarchiveandtgmcp, and the grouptgarchive-db.It installs
ffmpeganduvon the VPS if they are not there.It copies the files that git tracks to
/opt/tg-ml-archive.It copies
.envandtg.sessionto/opt/tg-ml-archive(mode 600), andarchive.dbto/var/lib/tg-archive/.It installs and starts the hourly sync timer and the daily digest timer.
Run --with-data only one time. Later runs of --with-data overwrite the server database with your old local copy.
C3. Make sure that the sync works on the VPS:
ssh <DEPLOY_HOST> 'systemctl start tg-archive-sync && systemctl show -p Result --value tg-archive-sync'Expected result: success. To read the log, run journalctl -u tg-archive-sync -n 50 on the VPS.
From now on, the VPS is the only place that runs ingest.py. Your local archive.db does not get new posts.
Part D. Public HTTPS endpoint and digest page
D1. Run the setup script one time:
deploy/go-public.shThe script does these steps on the VPS:
It stops the sync for a short time. If the database is still in
/opt/tg-ml-archive, it makes a backup in/rootand moves the database to/var/lib/tg-archive/.It makes
/etc/tg-archive-mcp.env(root only) with a new randomMCP_TOKENand the OpenAI key. The script does not print the token.It deploys the code again and starts
tg-archive-mcp.serviceas usertgmcp. This user cannot readtg.sessionor.env.It installs Caddy and writes
/etc/caddy/sites/tg-ml-archive.caddyforDOMAIN. The main Caddyfile only imports/etc/caddy/sites/*.caddy.It does a test of the MCP server: 401 without the token, 200 with the token.
You can run the script again. Each step checks the state before it changes something.
D2. At your DNS provider, add an A record: DOMAIN → the IP address of the VPS.
D3. If the VPS has a firewall, open TCP ports 80 and 443. Caddy needs them to get the TLS certificate.
D4. When the DNS record works, do a test of the endpoint:
curl -s -o /dev/null -w '%{http_code}\n' "https://<DOMAIN>/mcp"Expected result: 401. This shows that HTTPS works and that the server refuses requests without the token.
D5. The first digest page comes after the first 3-day window is finished. The windows start on DIGEST_EPOCH (default 2026-10-17) at 00:00 UTC. To build a page now for a past window, run this on the VPS:
cd /opt/tg-ml-archive && runuser -u tgarchive -- env ARCHIVE_DB=/var/lib/tg-archive/archive.db .venv/bin/python digest.py --window 2026-10-17Change the date to the first day of a finished window. Then open https://<DOMAIN>/.
Part E. Connect Claude
E1. Claude Code on the local computer, local database: see step B7. This uses your local archive.db, which stops getting new posts after Part C.
E2. Claude Code, VPS database (recommended): get the token from the VPS into a shell variable, then add the server:
TOKEN=$(ssh <DEPLOY_HOST> "grep '^MCP_TOKEN=' /etc/tg-archive-mcp.env | cut -d= -f2")
claude mcp add --transport http -s user tg-archive "https://<DOMAIN>/mcp" --header "Authorization: Bearer $TOKEN"
unset TOKENE3. claude.ai (web, desktop, and phone): go to Settings → Connectors → Add custom connector. Use this URL:
https://<DOMAIN>/mcp?token=<MCP_TOKEN>claude.ai connectors cannot send headers, so the token goes in the URL. Caddy keeps no access log, so the token is not written to disk on the server.
E4. Do a test: ask Claude "Show the archive stats". Claude must call the stats tool and show the post count of each channel.
Related MCP server: Telegram Bot MCP Server
Daily operation
Task | Command (run on the VPS unless noted) |
Deploy code changes (on the local computer) |
|
Show the timers |
|
Run a sync now |
|
Read the sync log |
|
Read the MCP server log |
|
Add a channel | Edit |
Change the topics | Edit |
Rotate the MCP token | Edit |
Run Python commands on the VPS as the user tgarchive, with the database path:
cd /opt/tg-ml-archive && runuser -u tgarchive -- env ARCHIVE_DB=/var/lib/tg-archive/archive.db .venv/bin/python <script>.py <flags>Configuration
All settings are in .env. .env.example lists them with their defaults.
Key | Default | Use |
| (required) | Telegram API credentials |
|
| Session file path without the |
| (required) | Tagging, embeddings, and the digest |
|
| The tagger |
|
| Embeddings. Set |
|
| Database path. The systemd units set |
| (required for | The HTTP MCP server |
| (required for deploy) | SSH target of the VPS, for example |
| (required for Part D) | Public domain of the MCP endpoint and the digest page |
|
| Base URL in the Atom feed |
|
| First day of the first digest window |
|
| The model that writes the digest text |
|
|
|
Digest page
https://<DOMAIN>/ shows the latest finished 3-day window. The server keeps no old digests, and /digest/... links go to /. /feed.xml is an Atom feed with one entry for each new digest.
media.pyruns in the hourly sync. It saves the pictures, videos, and GIFs of new posts (full albums too) to/var/www/tg-digest/media/. ffmpeg converts videos to H.264 at 720p or less, with a poster frame. Posts that have only topics from[digest] no_mediaget no downloads.digest.pyruns daily at 01:30 UTC (timertg-archive-digest). When a new window is finished, it does these steps:It removes humor, off-topic posts, and empty posts (less than 60 characters and no useful links).
It puts posts about the same thing into one item and gives each item an importance (gpt-5-mini). Then it merges items whose posts link the same GitHub repo.
It writes each item in the language of its sources, and writes again each item that comes back in the wrong language.
It writes the overview as short lists by theme, in Russian. To change the language, edit
OVERVIEW_SYSTEMindigest.py.It saves the result to
/var/www/tg-digest/data.json, renderstemplates/toindex.htmlandfeed.xml, and deletes the media of posts from before the new window.
[digest]inchannels.tomlsets the section order and the sections without media.After a template change, run
digest.py --render-only. This makes no AI calls. To write only a new overview, rundigest.py --redo-overview.Cost: all calls use the OpenAI Flex tier at half price. If OpenAI refuses a Flex call, the code sends it again on the standard tier. One digest costs about $0.12 with
gpt-6-sol.data.jsonstores the real cost underusage.Media on disk: the current window and the next window, 250 MB at most.
Security model
tg.sessionand.envare readable only bytgarchive(mode 600).The public MCP server runs as
tgmcp. systemd blocks its access totg.session,.env,/root, and/home. Its secrets are in/etc/tg-archive-mcp.env, which only root can read.The database is in
/var/lib/tg-archive/. The grouptgarchive-dbgives both users access.Clients send
Authorization: Bearer <MCP_TOKEN>, or?token=when they cannot send headers.Caddy keeps no access log, so tokens in URLs are not written to disk.
Notes
Keyword search uses prefix matching, not stemming. Semantic search (embeddings) finds paraphrases and works across Russian and English.
The sync uses about 4 s of CPU per hour. The database is about 73 MB for 17,000 posts.
License
MIT. See LICENSE.
Available Tools
5 toolsget_postA
Full text and metadata of one post (use after search_posts returns a snippet).
| Name | Required | Description | Default |
|---|---|---|---|
| msg_id | Yes | ||
| channel | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses that the tool returns full text and metadata and positions it as a follow-up to search, but it does not state read-only behavior, error handling, or any access constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence with the key purpose and usage cue front-loaded. There is no redundant or wasted text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter retrieval tool with no output schema, the description adequately describes the return content and usage context. However, it leaves required parameter meanings and basic behavioral expectations unstated, which is a clear gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not explain what channel or msg_id mean or how they identify the post. It only implies that the parameters come from a prior search_posts result, leaving the parameter semantics largely undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool returns the full text and metadata of one post, clearly differentiating it from search_posts, which only returns snippets. The purpose is evident, though it relies on the tool name for the explicit retrieval verb.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use this after search_posts returns a snippet, giving clear context for when it is appropriate. It does not cover exclusions or other alternatives, but the primary workflow is well signaled.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_topicsB
Topics, post kinds and availability values (with descriptions and post counts), plus the author's most used hashtags. Call this to pick filters for search_posts.
| Name | Required | Description | Default |
|---|---|---|---|
| top_hashtags | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations and no output schema, so the description carries the disclosure burden; it does usefully enumerate what the response contains (descriptions and post counts for topics, top hashtags). It does not state that this is a read-only operation, whether it is paginated or cached, or how large the result set may be.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences, return payload front-loaded and the recommended action second; nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no annotations and no output schema, the description does cover the return shape adequately, but it leaves the only parameter unexplained and gives no sense of result size or ordering, which matters for a discovery tool feeding search_posts.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter top_hashtags has 0% schema description coverage and a default of 150. The description's phrase 'most used hashtags' only obliquely implies this is a count/limit parameter and never states that the integer controls how many hashtags are returned.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description is a noun list of returned data ('topics, post kinds, availability values... plus hashtags') rather than a verb+resource statement, so the agent must infer this is a lookup/list tool. The second sentence clarifies its role as a filter-discovery helper, which rescues it from tautology, but it is not a clean purpose statement.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Call this to pick filters for search_posts' explicitly names the downstream tool and the condition that selects this one over get_post, recent, or stats. It stops short of stating when not to use it or whether it must be called before search_posts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recentB
Posts from the last N days, newest first, optionally filtered by topics/channels. Good for "what happened this week in agents".
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | ||
| limit | No | ||
| topics | No | ||
| channels | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden. It discloses newest-first ordering and optional filtering, but omits read-only confirmation, pagination/limit behavior, and any auth or rate-limit context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no wasted text. The core behavior is front-loaded, and the example use case is brief and helpful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema covers return values, and the description conveys the main retrieval behavior. Still, with no annotations and no schema parameter descriptions, the omitted limit/default semantics leave meaningful gaps for a simple but four-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for all four parameters. It mentions the days window and topics/channels filters, but does not explain the limit parameter, default values, or the expected array format for topics/channels.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the resource and scope: posts from the last N days, newest first, with optional topic/channel filters. It does not explicitly distinguish this from the sibling search_posts tool, which keeps it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The example 'what happened this week in agents' implies a useful recency-based use case, and the optional filters suggest narrowing by topic/channel. However, it does not say when to use this instead of search_posts or other siblings, nor does it state exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_postsA
Hybrid keyword + semantic search over all archived posts.
query: natural-language or keyword query (any language; exact names like "Qwen3" or arXiv ids work too).
channels: restrict to these channel usernames.
since / until: ISO dates, e.g. "2026-09-01" (until is exclusive).
topics: any-of filter, values from list_topics().
kind: one post type from list_topics() (e.g. model-release, tool-release, paper, tutorial, humor).
hashtags: any-of filter on the author's own hashtags, e.g. ["text2video", "gaussian"] (very precise).
availability: any-of filter, e.g. ["open-weights", "code-only"] for things you can run locally.
Returns posts with date, channel, summary, topics, links, text snippet and permalink.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | ||
| limit | No | ||
| query | Yes | ||
| since | No | ||
| until | No | ||
| topics | No | ||
| channels | No | ||
| hashtags | No | ||
| availability | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden; it does disclose exclusive-until semantics, cross-language query handling, and the returned fields. It says nothing about the default/limit result cap, ranking or ordering, or pagination behavior, which matter for a search tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the one-line purpose, then a tight per-parameter list, then the return shape. Nearly every line carries information an agent cannot get from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 9 parameters, zero schema descriptions, and an output schema that covers return values, the description is close to sufficient. The only real hole is `limit` and result-cap behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, and it does for 8 of 9 parameters: it gives the semantics (any-of vs single value), formats (ISO dates, until exclusive), valid-value sources (list_topics), and examples ('Qwen3', arXiv ids). The `limit` parameter is not addressed at all.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource plus the retrieval method: 'Hybrid keyword + semantic search over all archived posts.' That is clearly distinct from get_post (single item) and recent (latest feed), though no sibling is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains what each filter is for and when to prefer it ('hashtags ... very precise', 'availability ... for things you can run locally'), and routes to list_topics() for valid values. It does not state when to use this instead of `recent`, leaving that to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
statsB
Per-channel post counts, date range and enrichment progress.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the burden. It does disclose the kind of data produced (counts, date range, enrichment progress), which implies a non-destructive read, but it never states read-only behavior, scope of aggregation, or whether 'enrichment progress' indicates an in-flight background job.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single compact phrase with no filler, and the most informative element (per-channel post counts) is front-loaded. It is terse to the point of under-specification, which slightly caps the score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and no parameters, the definition doesn't need to explain return values, and it names the key metrics. However, it omits the aggregation scope (all channels vs. a default window) that an agent needs to interpret the numbers correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The fragment names specific returned content (per-channel post counts, date range, enrichment progress), which lets an agent distinguish it from get_post/recent/search_posts as an aggregate reporting tool. It lacks an explicit verb and never says it is a read-only summary, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to call this versus recent, search_posts, or list_topics, and no mention of scope (which channels, what window). The agent must infer that this is the overview/metrics endpoint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
get_post - First observed
list_topics - First observed
recent - First observed
search_posts - First observed
stats
TDQS
Scored across 5 tools
get_post, list_topics, and stats are clearly distinct, and the descriptions even prescribe a workflow (list_topics → search_posts → get_post). The only mild overlap is between recent (time-windowed browsing) and search_posts (query-based retrieval), both returning filtered post lists, but the time-vs-query distinction is documented well enough to separate them.
Two tools use the verb_noun pattern (get_post, list_topics) while the other three are bare nouns or adjectives (recent, stats, search_posts), and 'recent' in particular reads more like a parameter than a tool name. The set is still readable and unambiguous, but the convention is mixed.
Five tools is a tight, well-scoped surface for a read-only archive server: discovery (list_topics, stats), retrieval (search_posts, recent), and expansion (get_post). Each tool has a clear job and none feels redundant.
The read-only lifecycle is covered end to end: find filters, search, browse recent, expand full text, and inspect corpus stats. Minor gaps remain — no explicit channel-enumeration tool (channels must be guessed or inferred from stats) and no pagination/offset control on search or recent results for large result sets.
Maintenance
Related MCP Connectors
Search your newsletter and YouTube archive, drafted actions and working context from any MCP client.
Live Telegram data: trending topics, channel profiles & metrics, post history incl. edits/deletions.
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
Personal knowledge MCP: capture bookmarks, notes & todos by chat; archive pages; search memory.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables Claude to interact with Telegram channels and groups through API or web scraping for reading posts and searching.1538 npmMIT
- AlicenseAqualityDmaintenanceEnables AI assistants to publish, edit, search, and manage messages in Telegram channels via a set of MCP tools.8MIT
- AlicenseBqualityDmaintenanceEnables users to read, search, and manage Telegram messages in channels, groups, and private chats through MCP tools.8MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants like Claude to read, search, and send messages through your personal Telegram account via MCP tools.MIT