tg-recall-mcp
Query a local Telegram archive through five read-only MCP tools for agent-friendly search, reading, stats, exports, and chat listings.
search(query): find messages in allowed Telegram chats with sender, time, context around hits, andtg://citations; optionalchats,since,until,from,media,context,limit,budget.read(): read messages in order. No args: new since last read (first call: last 24h), newest per chat.chats: latest messages.since/until: a whole period.refs: windows around citations, withbefore,after, andfull=true. Optionalmedia,from,limit,budget.stats(): get counts instead of messages: volume per day/week/month, query hits per period, top senders, topics, and chats; optionalchats,since,until,from,media,query,by.export(): write a whole period/topic to a local file in read’s one-line format; returns path, size, and token estimate. Optionalchats,since,until,from,media.chats(): list allowed chats with id, title, message count, last activity, and sync age; optionalqueryas a title fragment.All tools operate only on owner-allowed chats, return compact text with
tg://citations, and do not send or modify Telegram data. The schema exposes no sync, transcribe, config, or auth tools.
Provides local archiving, synchronization, searching, and extractive cited retrieval of Telegram chats, messages, and media, with support for transcription and exports.
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-recall-mcpsearch 'project deadline' in work chat and return citations"
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-recall
A local Telegram archive that your AI agents can query cheaply. tg-recall downloads the chats you choose into a local SQLite database and gives Claude Code, Codex, Cursor and other agents a few small tools over MCP or the CLI: search, read, stats, export, chats and, if you allow them, sync and transcribe. Answers are compact text, one line per message, sized to a token budget, with tg://chat/<id>/message/<id> citations back to the original messages.
It only reads Telegram: it never sends, edits or marks messages as read.
Alpha (current release: v0.8.1). The archive holds private conversations and a Telegram user session: keep the profile local, use full-disk encryption and verify important findings in Telegram. Upgrading from v0.6 or older? v0.7.0 removed many features; read the changelog and make a backup first.
Install
Requires Python 3.13+.
uv tool install https://github.com/Rerowros/tg-recall/releases/download/v0.8.1/tg_recall-0.8.1-py3-none-any.whlInstall the universal wheel from the GitHub Release (compare the SHA-256 digest GitHub shows). To upgrade, run the same command with the newer release URL plus --force. uv tool install tg-recall / pip install tg-recall will work once the package is on PyPI.
Related MCP server: Telegram Agent for Codex
Quick start
Create API credentials at my.telegram.org, then in an interactive terminal:
tg-recall setup
tg-recall config set telegram.api_id 123456
tg-recall config set telegram.api_hash "your_api_hash"
tg-recall config set telegram.phone "+10000000000"
tg-recall telegram auth
tg-recall chats --refresh
tg-recall sync -1001234567890 --since 2026-01-01
tg-recall search "deadline"
tg-recall stats --query deadline --by monthchats --refresh fetches your chat list from Telegram; plain chats lists archived chats with their forum topics (--all also shows chats without messages).
sync takes one or more targets: a chat id, a title fragment, a t.me link (t.me/<username>/<topic>, t.me/c/<id>/<topic>) or <chat>/<topic>. All targets go over one Telegram connection:
A chat that was never synced starts 30 days back.
--since(an ISO date or30d) also fetches older history; later runs fetch only new messages.A forum topic is fetched on its own, not the whole group.
The CLI
syncwaits until it is done and prints progress to stderr every 10 seconds.--max-seconds(default3600) limits one run; an interrupted run is safe, just run it again. A Telegram rate limit (FloodWait) is saved and respected on the next run.A lock file keeps a second process off the same Telegram session; it fails with
busy.Without targets,
syncupdates the chats inai_access.allowed_chat_ids, or every chat that already has messages.--media voice,audio(orall) also queues media; fetch it withmedia downloadand transcribe it withtranscribe run.
search, read, stats, chats and sync print the same compact text that agents get over MCP:
2 hits · 2 chats · tz +04 · archive synced 5m ago · ~120 tok
## Work (-1001234567890)
-- 09-30 --
>1 05:19 Mark: deadline is friday
2 05:24 я: ok, noted
## Partners (-1009876543210)
-- 10-03 --
>7 04:19 Ann: deadline moved to Monday
cite: tg://chat/-1001234567890/message/1 tg://chat/-1009876543210/message/7> marks a hit, ↩N a reply to message N, …[+N] a shortened message (read REF --full shows all of it), and the cite: line lists citations. read without arguments shows what is new since your last read (the first call covers the last 24 hours); read --chat T --since 7d reads a period; read REF reads around a citation. With --json these commands return {"text", "count", "chat_ids"}.
Connect to Claude Code / Codex / Cursor
tg-recall-mcp is a stdio MCP server over the local archive. It returns nothing until you enable AI access.
Claude Code:
claude mcp add --scope user tg-recall -- tg-recall-mcpCodex (~/.codex/config.toml):
[mcp_servers.tg-recall]
command = "tg-recall-mcp"
args = []Cursor (~/.cursor/mcp.json or project .cursor/mcp.json) and other mcpServers JSON clients:
{
"mcpServers": {
"tg-recall": { "command": "tg-recall-mcp", "args": [] }
}
}Set TG_RECALL_PROFILE in the server environment to use a non-default profile. Restart the client after changing its MCP config; ai_access edits are picked up by a running server without a restart.
tg-recall-mcp exits on stdin EOF, when the parent process dies, after TG_RECALL_MCP_UNUSED_TIMEOUT_SEC seconds (default 600) without a tools/call, or after TG_RECALL_MCP_IDLE_TIMEOUT_SEC seconds (default 1800) without a request. Set a timeout to 0 to disable it, or TG_RECALL_MCP_PARENT_WATCHDOG=0 to disable parent reaping. Hosts may restart the server on the next call.
AI access
Agents see nothing until you, the owner, allow specific chats:
tg-recall config set ai_access.enabled true
tg-recall config set ai_access.allowed_chat_ids "-1001234567890,-1009876543210"To allow every archived chat instead, set ai_access.allow_all_chats to true. To let agents fetch missing chats, topics or periods from Telegram themselves:
tg-recall config set ai_access.allow_sync trueMCP tools:
search(query): hits with sender, time, nearby context and citations. Optional:chats,since,until,from,media,context,limit,budget.read(): new messages since this client's last read (first call: last 24 hours), a fair share per chat.read(chats)gives the latest messages,read(chats, since, until)a period,read(refs)windows around citations (full=truefor uncut text).stats(chats, since, until, from, media, query, by): counts instead of messages. Messages per day, week or month (by; picked from the span by default), withquerythe hits per period, plus top senders, forum topics and chats. A few hundred tokens instead of reading thousands of messages.export(chats, since, until, from, media): writes a whole period or topic, full text, to a file in the profile'sexportsdirectory, inread's one-line format with a date on every line. Returns the path, line count, token estimate and a suggested chunk size; the agent reads the file with its own file tools. At mostmax_export_messagesmessages per file.chats(): allowed chats with message counts, last activity, sync age and forum topics.sync(chats, since): only withallow_sync. Downloads chats or topics from Telegram (reads only). A call waits up tosync_max_seconds; a longer download continues in the background in the MCP server process, up tosync_background_minutes, and reports progress, Telegram's message count for the chat or topic, and an ETA. Meanwhilesearchandreadwork with what is already stored and add a note about the download. A baresync()reports the current or last download (the last one for 10 minutes), otherwise it updates all allowed chats. One download runs at a time.transcribe(refs): only withallow_transcribe. Takes up to 5tg://citations of voice, audio or video messages, downloads the media from Telegram and transcribes it with the localtranscription.*provider when one is set up, otherwise with Telegram's own transcription (needs Telegram Premium). Returns the text; transcripts become searchable.
search query syntax (also used by stats with query): words must all match, then messages with any of them follow; a | b takes either side (synonyms, other languages); "exact phrase" matches words in order; -word excludes. For example, deadline | дедлайн -test.
chats accepts ids, title fragments, t.me links and <chat>/<topic>; chat_id works as an alias. Unknown arguments get a did-you-mean error. After tg-recall telegram check the owner's own messages are shown as я. With allow_sync, search, read, stats and export first pull new messages for chats synced more than auto_refresh_minutes ago (not while a background download runs); if that fails (session busy, rate limit), the answer comes from the archive with a note.
How agents should use it:
Find something:
search.Counts, trends, who and when:
stats.A whole period or topic:
export, then read the file in chunks instead of pagingread.Data missing from the archive:
sync, then keep working with what is stored while it runs.A voice message matters:
transcribeits citation.
The CLI follows the same rules. You at a terminal see every archived chat. Inside an AI agent shell (CLAUDECODE, AI_AGENT or CODEX_* without a TTY, TG_RECALL_AI_MODE=1), search, read, stats, chats, sync and export see only ai_access chats.
What agents can do: search, read, count and list allowed chats; export them into the profile's exports directory; sync them when allow_sync is on; transcribe cited voice, audio and video when allow_transcribe is on; from the CLI, also media materialize or transcribe run --citation for one allowed tg:// citation.
What agents cannot do: change configuration or credentials, log in, refresh the chat list from Telegram, purge data, back up or restore, run queue or index maintenance, read the usage log, or send anything to Telegram. Message text reaches them as untrusted data, not instructions.
| Default | Meaning |
|
| Master switch |
| empty | Chats agents may use |
|
| Every archived chat is allowed (the list is ignored) |
|
| Max |
|
| Max messages per |
| none | Date bounds for agents |
|
| Media types agents may see |
|
| Put allowed chat titles into the MCP instructions (costs tokens in every session) |
|
| Enable |
|
| How long one MCP |
|
| Time limit of one background download |
|
| Refresh chats older than this before |
|
| Max messages in one agent |
|
| Enable |
config set accepts list values as 1,2, [1, 2] or 1 2.
Commands
Command | What it does |
| Create the profile config and database |
| Check the archive, schema, Telegram session and transcription tools |
| Show the redacted config or change a value |
| Log in (interactive) or check the saved session |
| List chats and forum topics |
| Download new messages, and older history with |
| Find messages with context and citations |
| New messages, a period, or windows around citations |
| Counts per day, week or month ( |
| Write one chat or forum topic to JSONL in the profile's |
| Owner only: how agents used tg-recall. Per tool: calls, errors, empty results, average and max tokens, average latency; plus error codes, empty searches, identical calls within 120 s, searches retried after an empty result and |
| Media disk usage, download queued media, fetch the media of one message |
| Transcribe voice, audio and video (see local transcription) |
| Inspect, retry or repair the media and transcription queue |
| Rebuild the full-text index |
| Check private file permissions |
| Make a consistent ZIP backup or restore it into a profile |
| Delete local archive data |
Global options go before the command: --json, --profile NAME, --home PATH, --config PATH. For example, tg-recall --json doctor.
Local storage
tg-recall never writes an archive into the repository or the current directory by default.
System | Config | Persistent data | State | Cache |
Windows |
|
|
|
|
Linux |
|
|
|
|
Each Telegram account is a profile. Its SQLite archive, session, media and exports stay below data/profiles/<profile>/. Media is stored by SHA-256 with relative keys, so a profile can be restored on another OS.
Use a self-contained root for an encrypted external disk or a portable setup:
tg-recall --home D:\Private\tg-recall --profile work setupPrecedence is --home, TG_RECALL_HOME, then system defaults. Profile precedence is --profile, TG_RECALL_PROFILE, the configured active profile, then default.
Privacy and security
Only the chats you sync are stored, and only on your machine. Search is local full-text search (SQLite FTS5); no text is sent to any AI provider by
tg-recallitself.Credentials and the session get best-effort private file permissions (
security check --fix). Use BitLocker on Windows or LUKS on Linux for encryption at rest.Agent policy decisions are audited with the operation and scope identifiers only, never the query text, message content, credentials or session.
The usage log behind
tg-recall usagerecords every MCP call and every CLI tool call from an agent shell: tool, client, arguments (query, chats, dates, limits), output tokens, latency and error code. It stores arguments but never message text, and it stays in the local database.Local Whisper is not bundled; the
telegramtranscription provider asks Telegram to transcribe. See local transcription.If a session may have leaked, revoke it in Telegram Settings -> Devices and run
telegram authagain. Report vulnerabilities as described in SECURITY.md.
Back up with the built-in commands rather than copying a live database:
tg-recall backup create --mode essential --output D:\Backups\tg-recall-essential.zip
tg-recall backup create --mode full --include-session --output D:\Backups\tg-recall-full.zip
tg-recall backup restore D:\Backups\tg-recall-essential.zip --profile restoredessential contains the database and profile configuration, full also the media. The session and credentials are included only with --include-session.
Documentation
Development
git clone https://github.com/Rerowros/tg-recall.git
cd tg-recall
uv sync --extra dev
uv run pytest -q
uv buildAvailable Tools
5 toolschatsCRead-only
List allowed chats: id, title, message count, last activity, sync age.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Title fragment. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The phrase 'allowed chats' hints at a permission scoping not otherwise documented, but it is never explained, and nothing is said about pagination, ordering, or what 'sync age' means as a field.
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?
It is one short sentence with no filler, which is good, but the trailing field list ('id, title, message count, last activity, sync age') is a bare enumeration that is not front-loaded and mixes return-shape details into a purpose statement.
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 list tool with no output schema, the description should explain the scoping ('allowed'), ordering, result limits, and how 'sync age' is expressed. None of that is present, and the sibling 'search' is left un-contrasted, so an agent cannot confidently choose between them.
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 100% for the single 'query' parameter, so the schema already explains the title-fragment filter. The description adds nothing about query syntax or matching behavior, so the baseline 3 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?
States a verb (List) and resource (chats), but the word 'allowed' is unexplained and the appended field list reads like a partial output enumeration rather than a purpose statement. It does not distinguish itself from the sibling 'search', which likely also handles chats.
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?
No indication of when to use this versus search, read, stats, or export. The 'query' parameter implies filtering, but the description never states that a query is the way to narrow the list, nor when unfiltered listing is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
exportBIdempotent
Write a whole period/topic (full text, read's format) to a local file and return its path, size and token estimate. For bulk analysis: read the file with your own file tools in chunks.
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | ||
| chats | No | ||
| media | No | ||
| since | No | ||
| until | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=true, and openWorldHint=false. The description adds useful behavioral context by stating it writes a local file and returns path, size, and token estimate, plus advises chunked reading. It still omits details such as overwrite behavior, file location, permissions, and output format specifics.
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 words. The main effect is front-loaded, followed by a compact usage note for bulk analysis.
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 tool with five undocumented parameters and no output schema, the description is incomplete. It covers return values and a post-export workflow, but it leaves parameter meaning, filtering semantics, file format details, and selection behavior largely unexplained.
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% for five parameters. The description mentions a 'period/topic' and 'full text', which loosely relates to date/chat filters, but it never explains from, chats, media, since, or until. It does not compensate for the missing parameter documentation.
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 gives a specific verb and resource: writing a period/topic's full text in read's format to a local file. It also states the return values (path, size, token estimate). It hints at differentiation from the sibling read tool, but does not name or contrast alternatives such as search or stats.
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 gives one implied usage context: bulk analysis, where the agent should read the exported file in chunks. However, it does not explicitly say when to use export instead of siblings like read, search, stats, or chats, nor does it list exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
readARead-only
Read messages in order. No args: new since your last read (first: last 24h), newest per chat. chats: latest. since/until: a whole period. refs: around citations (before/after, full=true).
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | ||
| full | No | ||
| refs | No | tg://chat/<id>/message/<id> or <chat>/<id>; max 8. | |
| after | No | ||
| chats | No | ||
| limit | No | ||
| media | No | ||
| since | No | ||
| until | No | ||
| before | No | ||
| budget | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuinely non-obvious behavior: stateful defaults (new since your last read, first run last 24h, newest message per chat) and that full=true changes result scope, which an agent cannot infer from the schema or annotations.
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?
It is extremely compact and front-loads the purpose before the argument-driven modes, with zero filler sentences. The telegraphic fragments ('chats: latest.', 'refs: around citations') are dense but readable, so 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?
For an 11-parameter tool with 9% schema coverage and no output schema, the description covers the default behavior and four major modes but omits four parameters and any sense of return shape or result limits. Adequate for common paths, incomplete for the full parameter surface.
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 only 9%, so the description carries most of the burden and it does explain chats, since/until, refs, before/after, and full. However 'from', 'limit', 'media' (an enum filter), and 'budget' receive no semantic explanation anywhere, leaving a meaningful gap.
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 opening 'Read messages in order' gives a specific verb plus resource, so the agent knows this retrieves messages rather than searching, exporting, or aggregating. It does not name or differentiate from the sibling 'search' tool, so it stops short of the 5 tier.
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 description lays out explicit invocation modes keyed to arguments: no args means new-since-last-read, 'chats' means latest, 'since/until' means a period, 'refs' means around citations. That is strong conditional guidance, but it never states when to prefer this over 'search' or 'export', so no exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchARead-only
Find messages in the owner's allowed Telegram chats: hits ('>') with sender, time, context around them and tg:// citations, in one call.
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | Sender name fragment, user id, or 'me'. | |
| chats | No | Id, title fragment, or a list. Default: all allowed. | |
| limit | No | Max hits (default 10). | |
| media | No | ||
| query | Yes | Words (all must match, then any); a | b = either (synonyms, other languages); "exact phrase"; -word excludes. | |
| since | No | ISO, 7d, 24h, today, yesterday (local). | |
| until | No | ||
| budget | No | Max output tokens. | |
| context | No | Messages around each hit (default 2, max 8). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=true, openWorldHint=false), so the bar is lower, and the description goes beyond them by disclosing the return shape: hits marked with '>', each with sender, time, surrounding context, and tg:// citations. It does not mention pagination or how 'limit'/'budget' truncation behaves, which is the main remaining gap.
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 information-dense sentence with the core action front-loaded and no filler. It is somewhat long for one sentence, but every clause (scope, hit marker, sender/time/context, citations, single call) earns its place.
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 9 parameters, no output schema, and annotations covering only safety, the description usefully describes what comes back (hits, sender, time, context, citations). It stops short of covering pagination, no-result behavior, or budget interaction, which leaves minor gaps for a search 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 78%, so most of the 9 parameters are already documented in the schema (query syntax, from, chats, limit, since, context, budget). The description adds little parameter-level detail beyond noting that context around hits is returned. Baseline 3 is appropriate given the schema does the heavy lifting.
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 a specific verb and resource ('Find messages') and scopes it to the owner's allowed Telegram chats, so the agent knows exactly what surface is being searched. It does not, however, explain how it differs from close siblings like 'read' or 'chats', which target the same corpus, so sibling differentiation is left to inference.
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?
Usage is implied rather than stated: 'Find messages' with a query parameter makes the search intent obvious, and 'in one call' hints at an efficient multi-chat lookup. But there is no explicit when-to-use versus 'read'/'chats', no stated prerequisites (e.g. chat authorization needed), and no exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
statsBRead-only
Counts instead of messages: volume per day/week/month (with query: hits per period), top senders, topics, chats. For when/how much/who questions over long periods.
| Name | Required | Description | Default |
|---|---|---|---|
| by | No | ||
| from | No | ||
| chats | No | ||
| media | No | ||
| query | No | ||
| since | No | ||
| until | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds that output is aggregated counts rather than raw messages, but says nothing about result shape, ordering, or limits; adequate but not rich beyond the annotations.
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 dense, front-loaded sentences with no filler; the core aggregation purpose and usage trigger lead. Telegraphic phrasing occasionally forces inference, but 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?
For a 7-parameter tool with no output schema and 0% schema description coverage, the description leaves more than half the parameters (media, from, since, until) and the return format unexplained. An agent cannot confidently populate those fields from this text alone.
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% across 7 params, so the description carries the full burden. It only illuminates 'by' (day/week/month), 'query' (hits per period), and 'chats' (top chats); 'media', 'from', 'since', and 'until' are left entirely undocumented in both schema and description.
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?
States a specific verb+resource ('Counts ... volume per day/week/month') and enumerates the aggregation outputs (top senders, topics, chats). The phrase 'Counts instead of messages' implicitly distinguishes it from the message-returning siblings search/read, though it never names them.
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?
'For when/how much/who questions over long periods' gives clear usage context and the contrast with message-returning tools is implied. It stops short of naming an explicit alternative or a when-not-to-use condition, so it is not fully 5-level routing.
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.
14 tool updates
v0.8.1- Removed
ask_archive - Added
chats - Removed
expand_cited_sources - Added
export - Removed
get_message_context - Removed
inspect_research_session - Removed
list_allowed_chats - Removed
list_scopes - Removed
query_knowledge_catalog - Added
read - Removed
retrieve_evidence - Added
search - Removed
search_messages - Added
stats
7 tool updates
v0.5.0- Changed
ask_archive3 fields changed- added
Input schema / properties / media_typeAdded value: +{ + "type": "string" +} - added
Input schema / properties / sinceAdded value: +{ + "type": "string" +} - added
Input schema / properties / untilAdded value: +{ + "type": "string" +}
- Added
expand_cited_sources - Changed
get_message_context2 fields changed- added
Input schema / properties / sinceAdded value: +{ + "type": "string" +} - added
Input schema / properties / untilAdded value: +{ + "type": "string" +}
- Added
inspect_research_session - Added
query_knowledge_catalog - Added
retrieve_evidence - Changed
search_messages3 fields changed- added
Input schema / properties / media_typeAdded value: +{ + "type": "string" +} - added
Input schema / properties / sinceAdded value: +{ + "type": "string" +} - added
Input schema / properties / untilAdded value: +{ + "type": "string" +}
5 tool updates
v0.2.0- First observed
ask_archive - First observed
get_message_context - First observed
list_allowed_chats - First observed
list_scopes - First observed
search_messages
TDQS
Scored across 5 tools
Each tool has a largely distinct purpose: search queries messages, read retrieves messages in order, stats aggregates counts, export writes to a file, and chats lists available chats. The only mild overlap is that search and read both return message content, and export can cover similar bulk-retrieval ground as read, but the descriptions make the intended use cases clear.
All five names are single lowercase words with no separators, which is a consistent and predictable style. However, they mix verbs (search, read, export) and nouns (stats, chats) rather than following a single verb_noun or uniform category convention, which is a minor deviation.
Five tools is well within the appropriate 3-15 range for a Telegram message-recall server. Each tool maps to a distinct capability (query, ordered read, aggregation, bulk export, chat listing) and none feels redundant.
The read-only recall domain is well covered: search for targeted retrieval, read for chronological access, stats for aggregation, export for bulk analysis, and chats for scope discovery. A minor gap is the lack of an explicit sync/refresh or per-message lookup tool, though chats' sync age and read's since/until partially mitigate this.
Maintenance
Related MCP Connectors
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
MCP server for querying Forkast documentation
Read-only MCP server for The Quiet Protocol's engines, benchmarks, proof, and business data.
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP server that exposes any Telegram-Archive instance to LLMs, enabling message search, chat browsing, and access to archived Telegram history.9247 npm5GPL 3.0
- 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.193 npm1MIT
- FlicenseNot gradedqualityBmaintenanceAn MCP server that connects to a Telegram group chat, persists messages to a local SQLite database, and exposes tools to search, retrieve, and send messages via SSE.-
- AlicenseNot gradedqualityCmaintenanceLocal-first MCP server for indexing and searching research materials (papers, notes, logs, READMEs) using SQLite FTS, with tools for memory management and evidence retrieval.MIT