npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

telegram-send-mcp

v0.2.0

Published

MCP server for Telegram Bot API: send text/photo, edit and delete messages. Multi-bot, multi-group, purpose-based targeting baked into config.

Readme

telegram-send-mcp

MCP server:通过 Telegram Bot API 发送文本 / 图片、编辑与删除消息。目标固化在配置里(支持多 bot、每个 bot 多群、按用途选群),Agent 调用时只传内容,不需要每次给 chat_id。

lark-tg-mcp 拆分而来:本包只管 Telegram;Lark 建档见姊妹包 lark-send-mcp

安装

# 推荐 pnpm
pnpm add -g telegram-send-mcp     # 全局安装
pnpm dlx telegram-send-mcp        # 免装、一次性执行

# 或 npm
npm install -g telegram-send-mcp
npx telegram-send-mcp

接入 MCP 客户端

~/.claude.json(Claude Code)或 ~/.cursor/mcp.json(Cursor):

{
  "mcpServers": {
    "telegram-send": {
      "command": "npx",
      "args": ["-y", "telegram-send-mcp@latest"],
      "env": {
        "TG_BOT_TOKEN": "1234567890:AA...",
        "TG_CHAT_ID": "-1001234567890"
      }
    }
  }
}

配好即用:TG_CHAT_ID 是全局默认群,所有机器共用这一份配置模板,发消息只传文本。

配置:env 凭据 + 项目文件

固定凭据走 环境变量,项目专属参数走 cwd 的 ./.telegram.json(与 lark-send-mcp / apifox-url-mcp 一致)。

env(跨项目共用一份)

| env 变量 | 必填 | 说明 | |---|---|---| | TG_BOT_TOKEN | ✅* | 单 bot 写法的 token;多 bot 写法里给 default_bot 兜底(也可写进 .telegram.json 兜底,env 优先) | | TG_BOT_TOKEN_<BOT> | ⬜ | 多 bot 写法的 per-bot token,<BOT>bots 键名大写、非字母数字转 _。例:bots.alertTG_BOT_TOKEN_ALERT | | TG_CHAT_ID | ⬜ | 默认目标群(仅单 bot 写法、且无配置文件时生效) | | TG_CONFIG | ⬜ | 配置文件的显式路径,优先于 cwd 的 .telegram.json |

* 每个 bot 必须能从「文件内 bot_token → 对应 env」拿到 token,缺任何一个启动即报错。

目标配置文件(与 airouting-mcp 的 AIROUTING_CONFIG 同款约定)

| 优先级 | 来源 | 说明 | |---|---|---| | 1 | env TG_CONFIG | 显式指定配置文件路径,任何 cwd 都生效——想全局共用一份配置,就在 MCP 客户端 env 里指到那个文件 | | 2 | ./.telegram.json(cwd) | 项目级点文件 |

不做合并、没有其他隐式落点;TG_CONFIG 指向的文件不存在时启动即报错。全局用法示例:

"env": { "TG_CONFIG": "/Users/you/path/to/.telegram.json" }

多 bot 写法(一对多:每个 bot 管自己的一批群):

{
  "default_bot": "notify",
  "bots": {
    "notify": {
      "title": "通知机器人",
      "purpose": "日常通知、进度同步",
      "tg_chat_id": "-1000000000000",
      "tg_groups": {
        "daily_report": {
          "chat_id": "-1001111111111",
          "title": "工作日报群",
          "purpose": "提交每日/每周工作汇报、进度同步。Agent 在用户说『发日报』『写周报』时应使用此群。"
        }
      }
    },
    "alert": {
      "title": "告警机器人",
      "bot_token": "987654321:BB...",
      "tg_groups": {
        "prod_alerts": {
          "chat_id": "-1002222222222",
          "title": "线上告警群",
          "purpose": "生产环境告警、故障通报。Agent 在用户说『发告警』『线上出事了』时应使用此群。"
        }
      }
    }
  }
}

| 字段 | 必填 | 说明 | |---|---|---| | default_bot | ⬜ | 多 bot 时不传 bot/group 的默认落点;只有一个 bot 时自动就是它 | | bots.<key>.bot_token | ⬜ | 该 bot 的 token;不写则找 env TG_BOT_TOKEN_<KEY>(default_bot 还能用 TG_BOT_TOKEN) | | bots.<key>.tg_chat_id | ⬜ | 该 bot 的默认群(没配 tg_groups 时用) | | bots.<key>.tg_groups | ⬜ | 该 bot 的多群按用途配置,值为 { chat_id, title, purpose }purpose 给 Agent 看 |

单 bot 写法(旧版扁平结构,继续兼容):

{
  "tg_chat_id": "-1001234567890",
  "tg_groups": {
    "daily_report": { "chat_id": "-1001111111111", "title": "工作日报群", "purpose": "…" }
  }
}

token 走 env TG_BOT_TOKEN,内部等价于一个名为 default 的 bot。

Telegram 侧前置准备

  1. 私聊 @BotFather/newbot 创建,拿 bot_token
  2. 把 Bot 拉进群(或让接收用户先私聊 /start 过它)
  3. chat_id:发一条消息后访问 https://api.telegram.org/bot<token>/getUpdates,看 chat.id

工具

| 名称 | 说明 | |---|---| | tg_send(text, url?, title?, bot?, group?, chat_id?) | 发文本(HTML parse mode),可附带链接。返回 {message_id, chat_id, bot},留着可编辑/删除 | | tg_send_photo(photo, caption?, bot?, group?, chat_id?) | 发图片。photo 支持本地文件路径(multipart 上传)、http(s) URL、Telegram file_id | | tg_edit(message_id, text, bot?, group?, chat_id?) | 按 message_id 编辑。文本消息走 editMessageText,图片消息自动降级改 caption。Bot 只能编辑自己发的消息 | | tg_delete(message_id, bot?, group?, chat_id?) | 按 message_id 删除。Telegram 限制:Bot 只能删 48 小时内的消息 |

四个工具的目标解析规则一致(见下);tg_edit / tg_delete 要传消息当初发出时的那组 bot / group / chat_id

多群 / 按用途选群

tg_groups 让 Agent 按"语义用途"选群,而不是死记 chat_id。三种触发路径:

  1. Agent 自动选(推荐):Agent 看 tg_groups[*].purpose 描述,自己决定 group 参数。例:你说「把今天的进度发一下」→ Agent 调 tg_send(text=..., group="daily_report")
  2. 用户显式选:调用时传 group="daily_report"chat_id="-100xxx",跳过弹窗。
  3. 弹窗选群(fallback):多群配置且没传 group/chat_id 时,server 通过 MCP elicitation 弹一个单选对话框,让用户当场选。

弹窗的限制(⚠️ 关键)

弹窗能力依赖 MCP client 实现 elicitation。当前情况:

| Client | 支持? | |---|---| | Claude Code ≥ 2.1.76 | ✅ | | Cursor / Trae / 其他 | ❌(多数还未实现) |

在不支持 elicitation 的 client 上,多群配置 + 没传 group 会直接报错,提示用户必须显式传 groupchat_id。如果你只在 Cursor 用,配置上要么只配一个群、要么始终显式传 group

兜底逻辑(resolveTarget 优先级)

  1. 调用时显式传 chat_id → 直接发(bot 取显式 bot > default_bot > 唯一 bot),最高优先级
  2. 调用时显式传 group → 在所有 bot(或显式 bot 限定的那个)里找该群名;跨 bot 唯一时自动定位到对应 bot;多个 bot 撞名则报错要求传 bot
  3. 都没传 → 收敛到 default_bot(或唯一 bot);该 bot 没配 tg_groups 时用它的 tg_chat_id 兜底
  4. 收敛后只剩一个候选目标 → 自动选中,不弹窗
  5. 仍有多个候选 → 弹窗选群(client 支持时,多 bot 下选项形如 bot/group)/ 报错(不支持时)

自检

# 只读诊断:逐 bot 验身份(getMe)+ 每个配置目标的可达性(getChat)
pnpm diagnose

# 端到端:发文本 → 编辑 → 发图 → 删图(会真实发消息)
pnpm e2e [chat_id] [photo_url_or_path] [bot_key]

常见错误

| 报错 | 原因 | |---|---| | 403 bot can't initiate conversation with a user | 接收用户没 /start 过 Bot | | 403 bot was blocked by the user | 用户屏蔽了 Bot | | 400 chat not found | chat_id 错误,或 Bot 没被拉进群 | | 400 message can't be deleted | 超过 48 小时,或 Bot 无删除权限(群里需管理员或删自己的消息) | | 400 message can't be edited | 不是 Bot 自己发的消息,或消息过旧 | | 400 can't parse entities | 文本走 HTML parse mode,含未转义的 < > & 时会被当成非法标签;需转义成 &lt; &gt; &amp; 或避免尖括号 |

License

MIT