Telegram OSINT
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| TELEGRAM_API_ID | Yes | Telegram app API ID from https://my.telegram.org (API development tools). Required. Identifies the app, not your account. | |
| TELEGRAM_MCP_DB | No | Database path. | $TELEGRAM_MCP_HOME/monitor.db |
| TELEGRAM_MCP_LOG | No | Watcher log level. | INFO |
| ANTHROPIC_API_KEY | No | Anthropic API key. Required for judging; if not set, judging is unavailable and every rule hit becomes an alert. | |
| TELEGRAM_API_HASH | Yes | Telegram app API hash from https://my.telegram.org (API development tools). Required. Identifies the app, not your account. | |
| TELEGRAM_MCP_HOME | No | Directory for the database and session files. | ~/.telegram-mcp |
| TELEGRAM_MCP_JUDGE | No | Set to 0 to disable judging. | 1 |
| TELEGRAM_MCP_NOTIFY | No | Set to 0 to silence desktop notifications. | 1 |
| TELEGRAM_MCP_SESSION | No | The server's session name. | mcp |
| TELEGRAM_MCP_JUDGE_MODEL | No | The judging model. | claude-opus-5 |
| TELEGRAM_MCP_JUDGE_EFFORT | No | Judging effort, low…max; raise if verdicts look shallow. | low |
| TELEGRAM_MCP_WATCHER_SESSION | No | The watcher's session name. | watcher |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| auth_statusA | Check whether Telegram is logged in, and as whom. Reports both sessions: the watcher's (the one that must be logged in for monitoring to work) and this server's (needed only for the read tools). Call this before anything else if alerts or reads are failing. |
| set_api_credentialsA | Save the Telegram app credentials needed before any login. The user gets these from https://my.telegram.org under "API development tools" — they identify the application, not the account, and are not secret in the way a login code is. Stored owner-only in /.env. Args: api_id: numeric App api_id from my.telegram.org. api_hash: 32-character App api_hash from my.telegram.org. |
| login_request_codeA | Start logging in: ask Telegram to send a login code. Telegram delivers the code in the Telegram app itself if the user is signed in elsewhere, otherwise by SMS. Follow with login_submit_code. Ask the user for their phone number rather than guessing it. Args: phone: phone number in international format, e.g. +14155550123. session: which session to log in — 'watcher' (default, the one monitoring needs) or 'mcp' (for this server's read tools). |
| login_submit_codeA | Finish logging in with the code Telegram sent. If the account has two-factor authentication, this returns an error asking for the password; call it again with both. Args: code: the login code the user received. password: two-factor password, only if the account has one. session: the session being logged in; must match login_request_code. |
| list_dialogsA | List your Telegram chats/channels, most recently active first. Use this to find the numeric chat ids you need for alert rule scopes. Args: limit: max number of dialogs to return. unread_only: only return dialogs with unread messages. include_archived: include archived chats (excluded by default). |
| read_messagesA | Read the most recent messages from a chat/channel. Args: chat_id: numeric dialog id, as returned by list_dialogs. limit: max number of messages to return (most recent first). |
| search_messagesA | Search your Telegram messages for a keyword. Searches history, unlike alert rules which only see new messages. Args: query: text to search for. chat_id: restrict search to one chat; omit to search all chats. limit: max number of results. |
| unread_summaryA | Summarize unread chats: for each, the unread count and the last few unread message previews. Args: limit_per_chat: how many recent messages to preview per chat. max_chats: max number of unread chats to include. |
| preview_ruleA | Test a candidate rule against real message history before creating it. Shows what the rule would have matched, so the user can judge whether it is too broad or too narrow while they are still writing it. Creates nothing. Use this during setup, before add_alert_rule, and show the user the samples — a rule that looks sensible in the abstract often turns out to match mostly noise. The matched samples are also the right input for testing draft criteria: read them and decide which ones a criterion should keep, then tell the user which would have been surfaced and which filtered out. Args: pattern: the candidate pattern. match_type: 'substring', 'word', or 'regex'. case_sensitive: match case exactly. chat_ids: restrict to these chats; omit to search everywhere. search_hint: a plain word to search Telegram for when match_type is 'regex' — Telegram cannot search by regex, so this narrows what gets scanned locally. Required for an unscoped regex preview. limit: max samples to return. scan: how many messages to pull and test. |
| add_alert_ruleA | Create an alert rule. The watcher picks it up within a few seconds — no restart needed. Rules only match messages that arrive after they are created; use search_messages to look backwards. Args: name: unique label for the rule, used in alerts and notifications. pattern: what to look for. match_type: 'substring' (default), 'word' (whole-word only), or 'regex'. case_sensitive: match case exactly (default: case-insensitive). chat_ids: only watch these chats; omit to watch every chat. exclude_chat_ids: never match in these chats; applied before chat_ids. include_outgoing: also match messages you send (default: incoming only). notify: fire a macOS desktop notification on match. |
| list_alert_rulesB | List alert rules with their hit counts. Args: include_disabled: include rules that are currently turned off. |
| set_alert_rule_enabledA | Turn an alert rule on or off without deleting it or its alerts. Args: rule_id: id from list_alert_rules. enabled: True to resume matching, False to pause. |
| delete_alert_ruleA | Delete an alert rule and every alert it produced. Irreversible — prefer set_alert_rule_enabled(rule_id, False) to just pause it. Args: rule_id: id from list_alert_rules. |
| list_alertsA | List recorded alerts, newest first. By default this hides alerts the judge ruled irrelevant — that filtering is the whole point of the judge. Pass include_irrelevant=True to audit what it rejected and why (each one keeps its reasoning). Args: limit: max number of alerts to return. unacked_only: only alerts you haven't acknowledged yet (default). rule_id: restrict to one prefilter rule. chat_id: restrict to one chat. since_hours: only alerts matched within this many hours. verdict: exact verdict — relevant, irrelevant, pending, skipped, error. min_severity: lowest severity to include (low, medium, high, critical). include_irrelevant: include alerts the judge rejected. |
| ack_alertsA | Mark alerts as acknowledged so they drop out of the default list_alerts view. Pass exactly one of the three selectors. Args: alert_ids: specific alert ids to acknowledge. rule_id: acknowledge every unacked alert from this rule. all_alerts: acknowledge every unacked alert. |
| add_criterionA | Add a natural-language criterion the judge uses to decide whether a prefiltered post actually matters. The watcher picks it up on the next judged alert — no restart needed. Rules decide what gets looked at; criteria decide what gets surfaced. Write a criterion the way you'd brief someone doing the triage for you: say what qualifies and what doesn't. "A specific open remote backend role that names the company" beats "jobs". Args: name: short unique label, shown on matching alerts. description: what qualifies, in plain language. |
| list_criteriaA | List the judging criteria and how often each has matched. Args: include_disabled: include criteria that are currently turned off. |
| set_criterion_enabledA | Turn a criterion on or off without deleting it. Args: criterion_id: id from list_criteria. enabled: True to resume judging against it, False to pause. |
| delete_criterionA | Delete a criterion. Alerts already judged against it keep their verdicts. Prefer set_criterion_enabled to pause one. Args: criterion_id: id from list_criteria. |
| monitor_statusA | Check whether the watcher daemon is running and what it has seen. Reports liveness from the daemon's heartbeat, so a 'stale' result means watcher.py has stopped and no new alerts are being recorded. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 20 tools
Each tool targets a distinct action/resource: auth flow (status, credentials, request/submit code), dialog reading, search, alert-rule CRUD, criterion CRUD, alert listing/acking, and a monitor status check. The two-tier design (rules prefilter, criteria judge, alerts result) is explicitly documented, so even similar-sounding pairs like list_alert_rules/list_alerts and set_alert_rule_enabled/set_criterion_enabled are clearly separated.
The vast majority follow a clean verb_noun pattern (list_alert_rules, add_alert_rule, delete_criterion, search_messages, ack_alerts). A few deviate to noun-phrases with no verb (auth_status, unread_summary, monitor_status), which is a minor inconsistency but still readable and predictable.
At 20 tools this is on the heavier side, but the surface spans several genuinely distinct concerns (auth, reading, rules, criteria, alerts, monitoring), and each tool maps to a real operation without obvious redundancy. It sits just above the ideal band rather than being bloated.
Coverage is strong: full login/auth flow, dialog listing, reading, searching, preview-before-create, and CRUD for both rules and criteria, plus alert listing/acking and daemon status. Minor gaps remain (no delete/prune or un-ack for alerts, no fetch-by-id), but these are workaroundable.