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

@osqi/mteam-mcp

v0.2.1

Published

MCP server for searching M-Team torrents.

Downloads

605

Readme

@osqi/mteam-mcp

用于查询 M-Team 种子数据的 MCP Server,接口地址为 https://api.m-team.cc

安装

npm install
npm run build

发布到 npm 后,可以通过 mteam-mcp 这个二进制入口启动。

配置

创建 .env 文件:

MTEAM_API_KEY=your_mteam_api_key
MTEAM_CATEGORY_IDS=419,423
MTEAM_SEARCH_MODE=normal
MTEAM_PUSH_FETCH_SIZE=100
MTEAM_API_BASE_URL=https://api.m-team.cc
TELEGRAM_BOT_TOKEN=your_telegram_bot_token
TELEGRAM_CHAT_ID=your_telegram_chat_id
QBITTORRENT_URL=http://127.0.0.1:8080
QBITTORRENT_USERNAME=admin
QBITTORRENT_PASSWORD=your_qbittorrent_password
MTEAM_PUSH_STATE_PATH=.mteam-push-state.json

MTEAM_API_KEY 会作为 x-api-key 请求头发送,不会进入请求 body。

MTEAM_CATEGORY_IDS 是逗号分隔的分类 ID 列表,会作为每次请求里的 categories 字段。工具入参不接受 categories,分类始终来自这个环境变量。

MTEAM_SEARCH_MODE 是搜索模式,例如 normal。两个搜索工具都不接受 mode 入参,请求始终使用这个环境变量;未配置时默认使用 normal

MTEAM_PUSH_FETCH_SIZEpushTorrentSearch 每次扫描的记录数,默认及最大值均为 100。工具入参不能覆盖这个值。

TELEGRAM_BOT_TOKEN 用于 pushTorrentSearch 调用 Telegram Bot API 发送消息。

TELEGRAM_CHAT_ID 是 Telegram 推送目标,可以是用户、群组或频道。bot token 只代表机器人本身,不能决定消息发送到哪里,所以这个配置是必须的。

QBITTORRENT_URLQBITTORRENT_USERNAMEQBITTORRENT_PASSWORD 用于登录 qBittorrent WebUI 并添加下载任务。三个参数必须同时配置;配置完整后 Telegram 消息会显示“推送”按钮,并启用 addTorrentToQbittorrent 工具。

按钮回调使用 Telegram 长轮询,由同一个监听器处理所有消息。请使用一个没有配置 webhook 的 Bot,并保持 MCP 进程运行;消息数量不会增加监听器数量。

MTEAM_PUSH_STATE_PATH 用于保存已经成功推送过的种子 ID,避免重复推送。状态记录上限与 MTEAM_PUSH_FETCH_SIZE 相同;成功加入新 ID 后会删除 pushedAt 最早的记录。

MCP 客户端配置

多数 MCP 客户端都支持 commandargsenv 这种 stdio server 配置方式。推荐直接通过 npx 运行已发布的 npm 包:

{
  "mcpServers": {
    "mteam": {
      "command": "npx",
      "args": ["-y", "@osqi/mteam-mcp"],
      "env": {
        "MTEAM_API_KEY": "your_mteam_api_key",
        "MTEAM_CATEGORY_IDS": "419,423",
        "MTEAM_SEARCH_MODE": "normal",
        "MTEAM_PUSH_FETCH_SIZE": "100",
        "MTEAM_API_BASE_URL": "https://api.m-team.cc",
        "TELEGRAM_BOT_TOKEN": "your_telegram_bot_token",
        "TELEGRAM_CHAT_ID": "your_telegram_chat_id",
        "QBITTORRENT_URL": "http://127.0.0.1:8080",
        "QBITTORRENT_USERNAME": "admin",
        "QBITTORRENT_PASSWORD": "your_qbittorrent_password",
        "MTEAM_PUSH_STATE_PATH": ".mteam-push-state.json"
      }
    }
  }
}

opencode

在 opencode 的 MCP 配置中新增一个名为 mteam 的 server,使用上面的 mcpServers.mteam 配置即可。

如果 opencode 使用界面添加 MCP,字段对应关系如下:

  • name: mteam
  • command: npx
  • args: -y, @osqi/mteam-mcp
  • env: 填入上方环境变量

Hermes Agent

在 Hermes Agent 的 MCP 配置中新增 mteam server,使用同样的 stdio 配置:

{
  "name": "mteam",
  "command": "npx",
  "args": ["-y", "@osqi/mteam-mcp"],
  "env": {
    "MTEAM_API_KEY": "your_mteam_api_key",
    "MTEAM_CATEGORY_IDS": "419,423",
    "MTEAM_SEARCH_MODE": "normal",
    "MTEAM_PUSH_FETCH_SIZE": "100",
    "MTEAM_API_BASE_URL": "https://api.m-team.cc",
    "TELEGRAM_BOT_TOKEN": "your_telegram_bot_token",
    "TELEGRAM_CHAT_ID": "your_telegram_chat_id",
    "QBITTORRENT_URL": "http://127.0.0.1:8080",
    "QBITTORRENT_USERNAME": "admin",
    "QBITTORRENT_PASSWORD": "your_qbittorrent_password",
    "MTEAM_PUSH_STATE_PATH": ".mteam-push-state.json"
  }
}

如果客户端支持读取 .env,也可以只配置 commandargs,把敏感信息放在运行目录的 .env 文件中。

MCP 使用

在 MCP 客户端中配置运行:

npx @osqi/mteam-mcp

本地开发时可以运行:

npm run dev

工具:torrentSearch

只查询 M-Team 数据,不推送 Telegram。

入参:

{
  "visible": 1,
  "pageNumber": 1,
  "pageSize": 30
}

所有字段都是可选的,默认值:

  • visible: 1
  • pageNumber: 1
  • pageSize: 30

当前版本不支持 keywordcategories 也不是工具入参,它始终来自 MTEAM_CATEGORY_IDS

发送到 M-Team 的请求 body 示例:

{
  "mode": "normal",
  "visible": 1,
  "categories": ["419", "423"],
  "pageNumber": 1,
  "pageSize": 30
}

请求 body 中的 mode 始终来自 .env

MTEAM_SEARCH_MODE=normal

工具调用者不能传入或覆盖 mode

请求地址:

POST https://api.m-team.cc/api/torrent/search

请求头:

content-type: application/json
x-api-key: <MTEAM_API_KEY>

工具:addTorrentToQbittorrent

根据 M-Team 种子 ID 生成临时下载 URL,并提交到 qBittorrent。这个工具适合在 MCP Inspector 中单独调试完整下载链路。

入参:

{
  "id": "1167644"
}

成功返回:

{
  "id": "1167644",
  "status": "submitted",
  "stages": {
    "downloadUrlGenerated": true,
    "qbittorrentAuthenticated": true,
    "torrentSubmitted": true
  }
}

失败结果会包含 stage 和经过脱敏的错误信息,不会返回 M-Team 下载 URL、API key、qBittorrent 密码或 SID。

本地构建后可运行 MCP Inspector:

npx @modelcontextprotocol/inspector node dist/index.js

在 Inspector 的 Tools 页面选择 addTorrentToQbittorrent,输入种子 ID 后调用。Inspector 的 stdio 启动方式可参考其官方说明

工具:pushTorrentSearch

查询 M-Team,按创建时间从早到晚排序,跳过已经推送过的 ID,并把最早的未推送记录发送到 Telegram。每次调用最多发送一条。

入参:

{
  "visible": 1,
  "pageNumber": 1
}

所有字段都是可选的,默认值:

  • visible: 1
  • pageNumber: 1

读取数量不属于工具入参,固定从 MTEAM_PUSH_FETCH_SIZE 读取。

提取后的数据结构:

{
  "id": "123",
  "name": "完整种子标题",
  "smallDescr": "完整描述",
  "cover": "https://example.com/cover.jpg",
  "category": "423",
  "size": "1073741824",
  "discount": "FREE",
  "createdDate": "2026-06-26 12:00:00"
}

字段来源:

  • id: item.id
  • name: item.name
  • smallDescr: item.smallDescr
  • cover: item.imageList?.[0] ?? null
  • category: item.category
  • size: item.size
  • discount: item.status.discount
  • createdDate: item.createdDate

推送文案示例:

📌 完整种子标题(可复制代码样式)
📝 完整描述(正常字体)

🏷️ 类型: 游戏 · 💾 大小: 1.00 GB 🆓 FREE
🔗 ID: 123
🕒 创建时间: 2026-06-26 12:00:00

第一行直接显示完整 name,不添加标题前缀。smallDescr 非空时完整显示。当 discountFREE 时,会在大小后面追加 FREE;其他值不显示。已内置常用分类 ID 的中文映射,未知分类会显示原始 ID。

Telegram 消息使用紧凑的 HTML 样式和克制的表情符号:标题使用可复制的代码样式,字段名加粗,描述使用正常字体,类型与大小合并为一行,大小与创建时间使用普通文本,FREE 会以 🆓 FREE 单独强调。smallDescr 最多显示 100 个 Unicode 字符,超出后添加省略号。ID 数字通过 HTML anchor 链接到 https://kp.m-team.cc/detail/{id},点击后可打开对应的 M-Team 详情页。🔗 ID: 不在链接内,只有完整 ID 数字可点击。图文 caption 和纯文本消息都会使用相同样式;长度超限时优先截断描述并保留 ID 链接及其他固定字段。

如果 cover 存在,MCP 会携带 M-Team Referer 将图片下载到内存,检查响应类型和 10 MB 大小限制,再通过 multipart/form-data 调用 Telegram sendPhoto。图片不会写入磁盘,上传完成后由内存自动释放,不会留下临时文件。

如果没有封面,或者封面下载、内容检查、图片上传任一步失败,会自动调用 sendMessage 发送相同文案。纯文本发送成功后仍会标记该 ID,避免坏封面阻塞后续记录;纯文本也失败时才保留未推送状态。

qBittorrent 配置完整时,图文和纯文本消息都会带有“推送”按钮。按钮数据只包含种子 ID;点击后会调用与 addTorrentToQbittorrent 相同的内部下载服务。目标聊天中的用户均可点击,结果通过 Telegram 提示,按钮会保留。

抓取结果会按 createdDate 从早到晚稳定排序;创建时间相同的记录保持接口原顺序,日期缺失或无效的记录排在最后。每次调用只发送排序后的第一条未推送记录,成功后写入状态文件并结束。发送失败时不会标记该 ID,也不会继续发送后面的记录,下次调用会重新尝试。若本次读取的记录全部已经推送,则正常结束且不发送消息。

状态文件最多保留 MTEAM_PUSH_FETCH_SIZE 条记录。成功推送新记录后,如果超过容量,会删除 pushedAt 最早的记录。

返回摘要示例:

{
  "fetched": 100,
  "alreadyPushed": 12,
  "pending": 88,
  "sent": 1,
  "failed": 0,
  "sentIds": ["123"],
  "failedItems": []
}

开发

npm run typecheck
npm run build
npm test