Telegram Bridge について
Telegram Bridgeは、ローカルのエージェントがTelegram Bot API経由で送受信するためのstdio MCPサーバーです。チャットの許可リスト、送信内容の秘匿情報除去、更新や呼び出しの制限を備えています。
主な機能
- 01Telegram Bot APIでメッセージを送受信
- 02許可リスト外のチャットを拒否
- 03メッセージやボタンから秘密情報を除去
- 04更新サイズと呼び出し頻度を制限
- 05受信内容に安全性の情報を付与
活用シーン
- 01許可済みグループチャットでAgent入力を受信
- 02ボタン付きのTelegram通知を送信
- 03Telegramグループでトリアージや引き継ぎ
MCP 対応
stdio経由でMCPクライアントにTelegram用ツールを公開し、更新のポーリング、メッセージ送信、インラインボタン管理を行います。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細

mcp-telegram-bridge
Telegram Bot API に接続する stdio MCP ブリッジです。チャットの許可はフェイルクローズ方式で行い、送信データから機密情報を除去します。
ローカルのエージェント(Cursor、Claude Desktop、Windsurf など)がマシン上で起動する、小規模なモデルコンテキストプロトコルサーバーです。会話はエージェントが管理します。このプロセスは Bot API との入出力を行い、送信データから機密情報を除去し、許可していないチャットを拒否します。
バージョン 0.2.0 では許可の仕組みが変更されました。許可リストが空の場合、すべてのチャットが拒否されます。ALLOWED_CHAT_IDS を設定するか、ALLOW_ALL_CHATS=1 でオープンモードを有効にしてください。
クライアントが所有するデプロイ向けに構築されています。このブリッジはホスト型のボットサービスではありません。ゲームやゲームマスターのワークフローはデモのユースケースの一つであり、製品そのものではありません。
所有者:Antonio Castellon / Castellon.CH。
クイックスタート
要件:Python 3.11 以降、@BotFather から取得したボットトークン、ボットに使用させるチャットの数値 ID。
git clone https://github.com/antonio-castellon/mcp-telegram-bridge.git
cd mcp-telegram-bridge
uv sync --extra dev # or: python -m venv .venv && pip install -e ".[dev]"
cp .env.example .env # set TELEGRAM_BOT_TOKEN and ALLOWED_CHAT_IDS
uv run mcp-telegram-bridge # waits on stdin for MCP JSON-RPC; Ctrl+C to stop
uv.lock では、すべての依存関係がハッシュ付きで固定されています。CI はこのロックファイルからインストールします(uv sync --frozen)。pip install -e ".[dev]" も引き続き使用でき、pyproject.toml のバージョン範囲が適用されます。
Cursor または Claude Desktop(mcp.json / claude_desktop_config.json):
{
"mcpServers": {
"telegram-bridge": {
"command": "uvx",
"args": ["--from", "mcp-telegram-bridge", "mcp-telegram-bridge"],
"env": {
"TELEGRAM_BOT_TOKEN": "YOUR_BOT_TOKEN_HERE",
"ALLOWED_CHAT_IDS": "-1001234567890"
}
}
}
}
実際のトークンをコミットしないでください。ALLOW_ALL_CHATS は設定しないでください。
Python ライブラリとして使用する
MCP サーバーを使わずに、同じ操作を利用できます。import mcp_telegram_bridge で読み込まれるのは TelegramBridge と Settings のみです。mcp パッケージはインポートされません。Settings を直接渡してください。上記の環境変数を使用する場合は、デフォルトで Settings.from_env() が使われます。
import asyncio
from mcp_telegram_bridge import Settings, TelegramBridge
async def main() -> None:
settings = Settings(
bot_token="YOUR_BOT_TOKEN_HERE",
allowed_chat_ids=frozenset({-1001234567890}),
)
bridge = TelegramBridge(settings)
await bridge.get_me()
await bridge.send_message(
-1001234567890,
"hello",
buttons=[{"id": "ack", "label": "Ack"}],
)
await bridge.get_updates(timeout=0)
await bridge.aclose()
asyncio.run(main())
TelegramBridge(Settings.from_env()) は TELEGRAM_BOT_TOKEN、ALLOWED_CHAT_IDS、その他の変数を読み込みます。CLI は引き続きアクセスモードに関する警告を stderr に出力します。同じ行を表示したい場合、ライブラリの呼び出し元は mcp_telegram_bridge.config.emit_startup_warnings を使用できます。mcp-telegram-bridge コマンドに変更はありません。
設定
| 変数 | デフォルト | 効果 |
|---|---|---|
TELEGRAM_BOT_TOKEN | 必須 | BotFather から取得したボットトークンです。ログに記録したり、コミットしたりしないでください。 |
ALLOWED_CHAT_IDS | 空 | カンマ区切りのチャット ID です。空の場合、すべてのチャットが拒否されます。 |
ALLOW_ALL_CHATS | オフ | 1 / true / yes / on に設定すると、すべてのチャットが許可されます。許可リストが設定されている場合は無視されます。起動時に標準エラー出力へ警告が表示されます。 |
SAFETY_STRICT | オン | 認証情報をだまし取る行為、性的なコンテンツ、およびいくつかの指示上書きフレーズに対するヒューリスティックなラベル付けです。無効にするには、0 / false / no / off に設定します。これはプロンプトインジェクションフィルターではありません。 |
MAX_INBOUND_CHARS | 4096 | これより長い受信テキストやキャプションを破棄します(1..32768)。本文は返されません。 |
MAX_UPDATE_BYTES | 65536 | JSON のサイズがこれを超える更新を破棄します(1..262144)。 |
INBOUND_CHAT_RATE | 60/60 | 期間あたりのチャットごとのコンテンツを含む更新数(count/seconds)。超過した更新はテキストなしで返されます。off で制限を無効にします。 |
INBOUND_GLOBAL_RATE | 120/60 | 期間あたりのすべてのチャットにおける、コンテンツを含む更新数です。 |
INBOUND_POLL_RATE | 30/60 | 期間あたりの telegram_get_updates 呼び出し数です。超過した呼び出しは Telegram に到達しません。 |
OUTBOUND_CHAT_RATE | 20/60 | チャットごとの送信、マークアップの編集、コールバックへの応答、および getChat の呼び出し数です。 |
OUTBOUND_GLOBAL_RATE | 60/60 | すべてのチャットにおける同じ送信呼び出し数です。コールバックへの応答はグローバル制限にのみカウントされます。 |
MCP_TELEGRAM_BRIDGE_DATA_DIR | ユーザーごとのデータディレクトリ | ボタン ID のマップと初回タップの申告ファイルです。OS が許可する場合、モードは 0700、ファイルは 0600 です。MCP_TELEGRAM_DATA_DIR は旧式のエイリアスです。 |
telegram_get_updates は limit を 1..100 に、timeout を 0..50 秒に制限します。プロセスは呼び出し間で更新の本文をキューに保持しません。配信済みの更新 ID は最大 2048 件、レート制限キーは最大 1024 件まで記憶します。
ツール
| ツール | 目的 |
|---|---|
telegram_get_me | ボットの識別情報です。レート制限はありません。 |
telegram_get_chat | 許可されたチャットのメタデータです。 |
telegram_send_message | サニタイズ済みテキスト。任意の parse_mode と buttons=[{id,label}] を指定できます。 |
telegram_edit_reply_markup | インラインボタンを置き換えるか、クリアします。 |
telegram_answer_callback | callback_query_id を確認します。 |
telegram_get_updates | 上限付きのポーリングを 1 回実行します。オフセットは呼び出し元が管理します。テキストに基づいて行動する前に、セキュリティのセクションを確認してください。 |
getUpdates はプル専用です。このプロセスはウェブフックを待ち受けず、ポートも開きません。
通常の結果は次のようになります。
{
"ok": true,
"untrusted": true,
"trust_boundary": "UNTRUSTED TELEGRAM DATA. ...",
"next_offset": 42,
"summary": {"delivered": 1, "filtered": 0, "ignored": 0, "duplicates": 0, "rate_limited": 0},
"updates": [
{
"update_id": 41,
"untrusted": true,
"trust": "untrusted_telegram_user",
"message": {"text": "...", "content_trust": "untrusted_telegram_user"}
}
]
}
next_offset は、テキストが保留された更新も含め、バッチ内で最も大きい update_id の 1 つ後の値です。これを offset として渡すと、それらの更新が確認されます。レート制限された更新を再試行するには、オフセットを進めず、retry_after_seconds の経過後に同じオフセットで再度呼び出してください。
ボットからのメッセージは省略されます(ignore_reason は bot)。送信者 ID がこのボットであるメッセージも省略されます(self)。Telegram が sender_chat を付けたメッセージ(匿名管理者、チャンネルとしての投稿)は、ボットからのメッセージとして扱われません。
セキュリティモデルと脅威モデル
資産。 ボットトークン、許可されたチャットの内容、ディスク上のボタンマップの状態、エージェントが使用するその他のツールとシークレットです。
信頼境界。 あなたと MCP ホストは境界の内側にいます。Telegram ユーザー、グループメンバー、ボットにメッセージを送信できる人は境界の外側にいます。受信するテキスト、名前、ユーザー名、コールバックデータは、モデルが読み取る信頼できない入力です。
このプロセスで実施されること
- チャットは、リストに登録されていない限り、または
ALLOW_ALL_CHATSを設定していない限り拒否されます。オープンモードでは警告が stderr に記録されます(stdout は MCP プロトコル用です)。 - 送信メッセージのテキスト、コールバックのトースト、ボタンのラベルから、設定済みのシークレット値とトークン形式の文字列が除去されます。
- httpx および httpcore のリクエスト行や例外トレースバックを含むログレコードは、URL 内のボットトークンがメッセージに残らないよう書き換えられます。ホストに送信されるトランスポートエラーには URL が含まれません。
- 更新のバッチサイズには上限があります。ポーリング、配信される更新、送信呼び出しにはレート制限が適用されます。テキストがすでに返された更新 ID は再度返されません。キャッシュには上限があります。
SAFETY_STRICTが有効な場合(デフォルト)、一部のパターンについて、更新にsafety.kind、safety.blocked、safety.warningが追加されます。フラグが付いたテキストも引き続き結果に含まれます。その後の対応はホストが判断します。
引き続き必要な対策。 プロセスは一般ユーザーとして実行し、トークンはシークレットストアまたはアクセス権を制限した .env に保管して、許可リストを設定してください。受信するすべての文字列をデータとして扱ってください。信頼できないチャットからアクセスできる場合は、認証情報を読み取るツールを同じエージェントに与えないでください。メッセージを送信できるようにする前に、プロンプトを確認してください。
デプロイ時のチェックリスト、ディスクに保存されるデータ、残存リスクに関する詳しい説明は SAFETY.md にあります。脆弱性は SECURITY.md の説明に従って報告してください。
制限と残存リスク
これらの制御は影響範囲を縮小しますが、エージェントが読み取って返信するボットを、悪意のある送信者から安全にするものではありません。
- モデルは信頼できないというラベルを無視することがあります。正規表現では、言い換えられた指示を検出できません。エージェントには引き続き送信ツールがあります。
SAFETY_STRICTは一部のフレーズを対象とするヒューリスティックです。他の言語、エンコーディング、信頼できない一般的なリクエストは検出できません。- レート制限はプロセスごとのメモリ内で管理されます。再起動するとリセットされます。
offにすると、その制限はなくなります。1024 個のキーを持つキャッシュからチャット ID が削除されると、そのチャットの予算は新たに設定されますが、全体の制限は引き続き適用されます。 - レート制限に達した更新、または長すぎる更新を飛び越えて
next_offsetを進めると、その更新は破棄されます。Telegram はその更新を再配信しません。 - 重複排除では 2048 個の ID を記憶します。ホストが再度ポーリングした場合、古い ID が再表示されることがあります。
- テキストの除去とログの秘匿化はベストエフォートです。フィールドをまたいで分割されたトークンや、パターンに一致せず環境変数にも含まれていないシークレットは、そのまま通過する可能性があります。
- このブリッジには読み取り専用のツールセットがありません。すべてのツールを公開するホストは、メッセージを送信できます。
- ボタンマップとクレームファイルは経過時間ではなく件数で整理されます(マッピング 2000 件、クレーム 500 件)。メッセージのテキストは保存されません。これらを削除するには、データディレクトリを削除してください。
- 監査ログはありません。MCP ホストが保存するデータ(トランスクリプト、プロバイダーログなど)は、このプロセスの対象外です。
- httpx のデバッグログは無効にしておくことを推奨します。秘匿化は、このパッケージが設定するログレコードの経路を対象としており、他のすべてのトレーサーを網羅する保証はありません。
アーキテクチャ
+---------------------------+
| MCP host / agent | conversation, offset, product policy
+-------------+-------------+
| MCP (stdio)
v
+---------------------------+
| mcp-telegram-bridge | allowlist, scrub, bounds, untrusted labels
+-------------+-------------+
| HTTPS Bot API (getUpdates poll)
v
+---------------------------+
| api.telegram.org |
+-------------+-------------+
v
Telegram chats
使い方
グループまたは運用チャネル。 ボットごとにブリッジを 1 つ使用します。グループはメモ、トリアージ、引き継ぎに使用してください。取り消しが難しい操作では、必ず人が確認してください。
ボタン。 buttons=[{id,label}, ...] はインラインキーボードになります。コールバックを受け取ったら応答し、その後マークアップを編集するかクリアしてください。長い ID はデータディレクトリ内で短いコールバックデータに変換されます。
通知チャネル。 確認/スヌーズ/エスカレーションボタン付きのアラートを送信します。Telegram はページング手段であり、信頼できる情報源ではありません。
モデレーションの下書き。 このブリッジには、禁止、制限、削除のツールはありません。そのことをエージェントのプロンプトに明記してください。
エージェントスキル
補完スキルを使うと、エージェントにこれらのツールを呼び出すタイミングと、オフセットを管理するのが自分であることを伝えられます。Telegram Bridge on Agensi として公開されているスキルがあります。このスキルは指示のみを提供します。このサーバーは引き続き I/O と安全性を担います。
これは何ではないか
- ホスト型またはマルチテナント型のボットサービスではありません
- 特定の MCP ホストに限定されません
- ゲームエンジンではありません
- 管理者用ボットではありません
- Webhook の受信先ではありません
関連デモ
任意です。このプロジェクトに必須ではありません。
- grokgame は卓上ゲームのデモ用インターフェイスです
- grok2telegram は初期の実験で、そのサニタイズルールは
SAFETY.mdの作成に役立ちました
開発
uv sync --extra dev
uv run pytest
テストでは respx を使って Telegram をモックします。実際のトークンは必要ありません。
依存関係を変更した後は、uv lock を実行して uv.lock をコミットしてください。CI ではロックファイルを使用し、Python 3.12 で pip-audit による監査を行い、作業ツリーに対して gitleaks を実行します。Markdown、docs/、または LICENSE のみを変更するプルリクエストでは、このワークフローは開始されません。
MCP レジストリ
正式名称:io.github.antonio-castellon/mcp-telegram-bridge
mcpservers.org、MCP Marketplace、Agensi にも掲載されています。
マーケットプレイス向けの掲載文は LAUNCHGUIDE.md にあります。
お問い合わせ
- 一般:[email protected]
- サポート:[email protected]
- セキュリティ:[email protected](SECURITY.md)
ライセンス
MIT (c) Antonio Castellon / Castellon.CH
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。