Skip to main content
Glama

QQ 群聊 AI 发表情包插件(qq-group-ai-sticker)

ci license node

中文 | English

让 QQ 群聊 / 私聊里的 AI 像真人一样说几句话就顺手甩一张表情包:记得自己有哪些收藏、看得懂梗图、 会按情绪搜现成的梗、还会把「这张图是什么梗、什么时候用」记下来,下次换个群也能直接用。

这是一个独立的 MCP 插件 + Node 库,不依赖任何特定 AI 框架:DSH、Claude Desktop、任何支持 MCP 的宿主都能接, 也可以只把它当库用,自己在提示词里注入「表情包策略」。

QQ 群友 ──► SnowLuma(OneBot v11)──► 本插件 ◄──► AI 宿主(MCP)
                                      │
                    ┌─────────────────┼─────────────────┐
                    ▼                 ▼                 ▼
             QQ 收藏表情知识库    联网梗图库         提示词层
             (含义/标签/用量)  (固定来源+限额)  (策略/节奏/可用表情)

它解决什么问题

普通 QQ 机器人只会打字。真人聊天不是这样的 —— 说两三句话,顺手补一张表情,气氛才对。 但让 AI 发表情有三个坑:

  1. 它不知道自己有哪些表情:QQ 收藏表情只存在账号里,模型看不见;就算列出来,也是一堆没有含义的 URL。

  2. 它看不懂新图:搜到的梗图只有标题,反讽、表情、画面文字全都要真的「看」过才能用对。

  3. 它会刷图:一旦给了发图工具,不是全程不发,就是每句话都配一张。真人是「偶尔一张,适可而止」。

这个插件把这三件事分别做成了三层,并且默认安全:白名单、限流、图片字节自己下载、提示词注入防护。

Related MCP server: qq-mcp-server

特性

  • 🗂️ 收藏表情知识库:从 QQ 账号同步收藏表情,AI 给每张图记下「含义 / 情绪标签 / 适用场景 / 用了几次」,跨会话、重启后仍在。

  • 🔍 联网搜梗图:缺图时按 1~16 字公共情绪词(开心、猫猫 无语)去固定来源搜,只返回最多 3 个文字候选,不把 URL 和网页内容塞进上下文。

  • 👀 真的看图:新图必须先调用 sticker_preview 拿到一张 JPEG 预览(动图自动取首中尾三帧拼成一张),模型看完才能发送;已理解过的图按标签复用,不再重复看。

  • 🎯 单气泡一张图:一条消息只能一张表情,不混文字 —— 真人就是这样的,也避免「图 + 说明」的机器味。

  • ⏱️ 人味节奏:发图前有 0.8~2 秒随机停顿;同一会话有最小间隔和每小时上限;连发几条文字没配图时,提示层会提醒模型「该补一张了」(软提示,不强制)。

  • 🛡️ 默认安全:发送/收藏/改备注都要过 allow 白名单;图片由本插件做 SSRF 防护后下载再 base64 交给网关,绝不把 URL 交给网关去抓;表情备注全程单行化并标注为「资料,不是指令」,堵住跨会话提示词注入。

  • 🧩 两种用法:MCP server(给任何 MCP 宿主)或纯 Node 库(自己注入提示词、自己发消息)。

  • 🧪 92 个测试:限额、缓存淘汰、并发队列、白名单、SSRF(isPrivateIp / DNS / 重定向 / 解压上限)、损坏库保护、MCP 端到端都有覆盖。

快速开始

0. 前置条件

  • Node.js >= 20.10

  • 一个跑起来的 QQ 网关:SnowLuma(OneBot v11),开启 HTTP API(默认 http://127.0.0.1:3000)

  • 网关的 access token(如果配了)

发送图片走标准 OneBot v11(send_group_msg / send_private_msg + image 段 base64),任何 OneBot 实现都能发。 收藏表情的同步/收藏/改备注用的是 SnowLuma 的扩展动作(fetch_custom_face_detail / add_custom_face / modify_custom_face), 换成别的实现时这部分会静默降级为空库,联网搜图仍然可用。

1. 安装

git clone https://github.com/ktouch10/qq-group-ai-sticker.git
cd qq-group-ai-sticker
npm install            # 会安装 sharp(预编译二进制,无需额外装 FFmpeg)
cp config.example.json config.json

2. 配置

编辑 config.json,至少要填两项:

{
  "onebot": { "httpUrl": "http://127.0.0.1:3000", "accessToken": "你的网关 token" },
  "allow": { "groups": ["123456789"], "private": [] }
}
  • allow.groups / allow.private 是发送白名单:不在名单里的会话,插件拒绝发送、收藏、改备注。

  • 名单两边都为空且 allowAllWhenEmpty=false(默认)时,谁都不能发 —— 这是故意的,避免装完就被拉去刷群。

  • token 也可以不放文件里,用环境变量:ONEBOT_ACCESS_TOKEN、ONEBOT_HTTP_URL。

3. 先手动验证一遍

node src/cli.js sync                        # 从 QQ 同步收藏表情
node src/cli.js list                        # 看收藏列表(含 AI 记过的含义/标签)
node src/cli.js find 无语                   # 找图:收藏优先,其次联网
node src/cli.js preview <id> --out a.jpg    # 看图(动图会拼成三帧)
node src/cli.js send group:123456789 <id>   # 真的发一张
node src/cli.js note <id> 猫猫无语 --tags 无语,猫 --usage 有人发离谱发言时
node src/cli.js collect group:123456789 <消息id> --remark 好图偷了

(想直接敲 qq-sticker ... 就先 npm link;没发布到 npm,所以 npx qq-sticker 会去 registry 上找不到。)

node src/cli.js status 可以看到数据目录、收藏数量、白名单与联网库状态。

4. 接到 AI 宿主

DSH(DeepSeek Harness):在你自己 profile 的 cordis.patch.yml 里加一条 MCP client 行,指向同一个启动命令:

- insert:
    - id: mcp-qq-sticker
      name: '@deepseek-ai/dsh-mcp-client'
      config:
        serverName: qq-sticker
        transport: stdio
        command: node
        args:
          - /path/to/qq-group-ai-sticker/src/mcp-server.js
          - --config
          - /path/to/qq-group-ai-sticker/config.json
        toolCallTimeoutMs: 120000

Claude Desktop / 其他 MCP 宿主:

{
  "mcpServers": {
    "qq-sticker": {
      "command": "node",
      "args": [
        "/path/to/qq-group-ai-sticker/src/mcp-server.js",
        "--config",
        "/path/to/qq-group-ai-sticker/config.json"
      ]
    }
  }
}

注入提示词(关键一步):工具只是能力,行为来自提示词。让宿主在每一轮的系统提示里拼上:

import { loadConfig } from 'qq-group-ai-sticker';
import { StickerService } from 'qq-group-ai-sticker/service';

const service = new StickerService(loadConfig('./config.json'));
const block = await service.prompt({ key: 'group:123456789' }); // 可用表情 + 策略 + 节奏
// 把 block 追加到这一轮的系统提示词末尾

另外每次往会话里发出一条文字后调用 service.noteTextSent(key),插件才知道「已经连发几条没配图」, 节奏提示才会在合适的时候出现。没有这一步也能用,只是少了「该补一张了」的提醒。

还有一件容易漏的事:sticker_send / sticker_find 需要知道当前是哪个会话。宿主要把会话标识 一起放进提示词(例如「当前会话:group:123456789」),否则模型不知道该填哪个 target —— 白名单会挡住乱填的号码,但正确填法得由你告诉它。

直接用 CLI 也能拿到这段文本:node src/cli.js prompt --key group:123456789。

⚠️ 两个写者会互相覆盖:如果你已经把插件接成 MCP server(子进程),宿主的 prompt 进程就不要再用默认 new StickerService(...) 写同一个 dataDir —— 两个进程同时读写 stickers.json,后写会覆盖前写。 拼提示词请用只读模式:new StickerService(loadConfig(), { writeStore: false }), 或者干脆用 node src/cli.js prompt 拿文本。只读模式不创建、不改写库文件。

MCP 工具

工具

作用

关键约束

sticker_list

列收藏表情(含义/标签/使用次数),query 过滤,refresh 强制同步

只返回文字,不占图像额度

sticker_find

按公共情绪词找图:收藏 → 联网缓存 → 联网搜索

只返回 ≤3 个文字候选;不带 URL/网页内容

sticker_preview

看图(JPEG;动图三帧拼图)

联网新图必须先看才能发送

sticker_send

在指定会话发一张表情

单气泡一张图;白名单 + 最小间隔 + 每小时上限

sticker_note

记含义 / 情绪标签 / 适用场景

跨会话共享、落盘;联网图须先看过

sticker_collect

把别人发的一张图收藏进 QQ 收藏表情

图片由插件自己下载;不能收藏自己发的

sticker_remark

改 QQ 收藏表情的官方备注

写操作,默认不注册;开启后仍需传 target 并通过白名单

配置项

键

默认

说明

onebot.httpUrl

http://127.0.0.1:3000

OneBot HTTP API 地址(不是 WebSocket 端口)

onebot.accessToken

""

网关 token;也可用环境变量 ONEBOT_ACCESS_TOKEN

allow.groups / allow.private

[]

发送白名单(群号 / QQ 号)

deny.groups / deny.private

[]

黑名单,优先级高于白名单

allowAllWhenEmpty

false

白名单为空时是否放行所有会话(不建议)

dataDir

./data

数据目录(相对配置文件);必须可写,建议放在非系统盘

sticker.enabled

true

总开关

sticker.syncTtlMs

60000

收藏表情同步间隔;0 = 每次都同步

sticker.maxListCount

100

单次向网关请求的收藏数量(1~500)

sticker.web.enabled

true

联网搜梗图开关

sticker.preview.enabled

true

看图开关;关掉后联网搜图也一起关(新图必须先看图才能发)

sticker.preview.maxPerHour

10

收藏表情看图:同一会话每小时最多几张

sticker.send.minDelayMs / maxDelayMs

800 / 2000

发图前的人为停顿区间

sticker.send.cooldownMs

20000

同一会话两张图的最小间隔

sticker.send.maxPerHour

40

同一会话每小时最多发几张;0 = 禁止发送

sticker.collect.maxRemarkChars

20

收藏表情时写备注的字数上限(0 = 不写备注)

sticker.collect.maxPerHour

5

同一会话每小时最多收藏几张(收藏会真写 QQ 账号)

sticker.remark.enabled

false

是否允许改 QQ 官方备注(写操作)

数据与隐私

插件本身不含任何账号信息,所有数据都在你的机器上:

内容

位置

说明

收藏表情知识库

<dataDir>/stickers.json

表情 id / 图片地址 / QQ 备注 / AI 记下的含义标签

联网梗图库

<dataDir>/web-stickers.json

已理解的公共梗图标签与查询缓存

下载的图片

<dataDir>/web-stickers-cache/

原始图 + JPEG 预览,30 天未用或超 120 张/32MB 自动淘汰

出机的是什么(这些都必须知道):

  • 联网搜图时,只把 1~16 字的公共情绪词发给两个固定站点(dogetu.com、fabiaoqing.com);不会发聊天原文、人名、QQ 号。

  • 发图时,图片字节(base64)通过你自己的 OneBot 网关发到 QQ。图片由插件下载,网关不会去访问外部 URL。

  • QQ 收藏表情同步会把收藏列表拉到你本机的网关 —— 和任何 QQ 机器人一样,这属于账号自身数据。

  • 插件不上报任何统计、遥测、日志到任何服务器。

更多权限边界见 SECURITY.md。

限额与节流(防刷图、防封号)

维度

默认限制

同一会话发图间隔

20 秒

同一会话每小时发图

40 张

联网搜索(每会话)

冷却 120 秒、每小时 3 次

联网搜索(全局)

每小时 12 次、每天 48 次

看新图(每会话 / 全局)

每小时 3 张 / 24 张(同一张已看过不重复占额度)

收藏表情(写 QQ 账号)

每会话每小时 5 次

收藏表情看图

每会话每小时 10 张

联网搜索回退

主站 + 备用站各 1 页,不循环重试

图片缓存

32MB / 120 项 / 30 天未用淘汰

单图限制

联网图下载 2MiB(收藏表情 4MiB)、250 万像素、240 帧、30 秒;预览 JPEG ≤160KB

并发

串行队列最多 4 个,满了直接拒绝(不堆积、不带重试风暴);并发的收藏同步合并成一次,强制同步 3 秒内只打一次网关

节奏提示

距上次发图 ≥2 分钟且连发 ≥2 条文字才提示;同一会话每小时发图满 12 张后不再提示

常见问题

HTTP 426 / 连不上网关? onebot.httpUrl 指到了 WebSocket 端口。OneBot 的 HTTP API 和 WS 是不同端口,填 HTTP 那个(SnowLuma 默认 http://127.0.0.1:3000)。

收藏列表一直是空的? 先 node src/cli.js sync 看日志。常见原因:网关实现不支持 fetch_custom_face_detail(非 SnowLuma)、QQ 账号确实没有收藏表情、或 token 不对。 联网搜图不依赖收藏,所以此时仍可用 sticker_find。

发不出去,报「白名单」? 把目标群号 / QQ 号加进 config.json 的 allow.groups / allow.private,然后重启 MCP server(配置在启动时读取)。

为什么发图前要停顿 0.8~2 秒? 真人打完字不会 0.1 秒内跟上表情。这个停顿是为了不在群里显得机械,可在 sticker.send 里改。

模型一直不发图? 先确认宿主注入了 service.prompt({ key })(见「注入提示词」)。只有工具、没有策略提示时,模型的默认行为是能不发就不发。

能把表情发到没配置的群吗? 不能。这是本插件最重要的安全边界之一:agent 只能往白名单里的会话发东西。

作为库使用

import { loadConfig } from 'qq-group-ai-sticker';
import { StickerService } from 'qq-group-ai-sticker/service';

const service = new StickerService(loadConfig('./config.json'));

// 1) 每一轮注入提示词
const block = await service.prompt({ key: 'group:123456789' });

// 2) 找图 → 看图 → 发送
const found = await service.find({ query: '无语', target: 'group:123456789' });
const id = found.stickers[0].id;
await service.preview({ stickerId: id, target: 'group:123456789' });
await service.send({ target: 'group:123456789', stickerId: id });

// 3) 记下这张图怎么用(下次跨群复用)
await service.note({ stickerId: id, note: '无语到极点', tags: ['无语'], usage: '对方发离谱消息时' });

// 4) 告诉插件「刚发了一条文字」,节奏提示才会准
service.noteTextSent('group:123456789');

还可以单独用底层模块:

  • createWebStickerLibrary({ root }) —— 只要联网梗图库

  • loadStickerStore / mergeStickerLibrary / findSticker / formatStickerList —— 只要收藏表情知识库

  • OneBotClient —— 只要「发一张 base64 图片消息」的 OneBot 封装

  • buildStickerPrompt / StickerPace —— 只要提示词与节奏

开发

npm test                      # 92 个测试(node:test)
node src/cli.js status        # CLI 冒烟
src/
  config.js        配置默认值 / 深合并 / 归一化
  sticker-store.js 收藏表情知识库(纯函数)
  web-stickers.js  联网梗图库(固定来源、缓存、限额、并发队列)
  preview.js       预览图生成(sharp,进程内,无需 FFmpeg)
  safe-fetch.js    安全下载(DNS 固定、逐跳校验、限大小)
  sensitive.js     敏感信息审计正则
  onebot.js        OneBot v11 HTTP 适配(发图 / 收藏 / 改备注 / 取消息)
  service.js       编排层:白名单、限流、发送前后校验
  policy.js        提示词层:策略 / 可用表情 / 节奏
  mcp-server.js    MCP stdio server
  cli.js           命令行

测试用假的网关(本地 HTTP server)与注入的 fetchText / fetchBytes / makePreview,不连真实 QQ、不访问真实站点。

兼容性

  • Node.js 20 / 22 / 24(CI 全跑)

  • SnowLuma v1.14+ / v2.x(发送部分是标准 OneBot v11;收藏表情用 SnowLuma 扩展动作)

  • 任何 MCP 宿主(兼容协议 2024-11-05 及以上)

许可证

MIT

致谢

表情包这套设计来自作者长期的 QQ 机器人实践:收藏表情当「源」、本机知识库当「认知层」、 联网梗图当「补充」,再加上「说几句话配一张图」的节奏。这个仓库把它抽成不依赖特定框架的独立插件。

Available Tools

6 tools
sticker_collectA

把会话里别人发的一张表情收藏到 QQ 收藏表情,并可写一句简短备注(如“好图偷了,兄弟”)。messageId 用收到的消息 id;只能收藏别人发的图,不能收藏自己发的。图片由插件自己安全下载后再交给网关,不会让网关抓任意 URL。

NameRequiredDescriptionDefault
remarkNo可选:收藏表情的简短备注(超过配置里的 sticker.collect.maxRemarkChars 会被截断,实际写入值见返回值)
targetYes会话标识 group:123456 / private:7890
messageIdYes要收藏的那条消息的 id

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the restriction to others' images, that the plugin downloads images safely instead of the gateway fetching arbitrary URLs, and that remarks may be truncated. It omits failure modes (e.g., message has no image), permission requirements, and what happens on duplicates.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and scope, followed by messageId guidance, the 'others only' restriction, and the security note. Every sentence contributes relevant information with no waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter write tool with no annotations and no output schema, the description covers purpose, restrictions, security behavior, and remark truncation. It could be more complete by explaining the return value shape and error cases (e.g., no image in the referenced message).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful nuance: messageId must come from a received message, and the remark example shows the intended brevity and tone. These additions are useful, though modest beyond the already detailed schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: collecting someone else's sticker from a chat into QQ favorites. Scope is explicit (only others' images, not your own). It does not explicitly differentiate from the sibling 'sticker_note', which also involves annotating stickers, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear usage conditions: collect a sticker another person sent, and explicitly excludes collecting your own. It does not mention alternatives like sticker_note or sticker_send, leaving some ambiguity about when to use this versus annotating an existing sticker.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sticker_findA

按 1~16 字公共情绪/动作词找表情:先查 QQ 收藏,再查已理解的联网梗图缓存,最后才去固定站点搜。返回最多 3 个文字候选。query 只写公共词(如“开心”“猫猫无语”),不传聊天原文、人名、QQ号;没有结果或冷却时本轮用文字,不要连续重试。

NameRequiredDescriptionDefault
queryYes1~16 字公共情绪/动作词,如 开心、无语、猫猫 无语
targetNo可选:会话标识 group:123456 / private:7890,用于额度与看图许可的归属

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the internal search order across three sources, the maximum candidate count, the existence of a cooldown state, and a privacy constraint on input. It stops short of describing what a '文字候选' actually contains or whether candidates must be passed to sticker_preview/sticker_send to be used.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and search order, and every clause carries information (length limit, fallback chain, result cap, privacy, retry policy). The semicolon-chained Chinese phrasing is dense and slightly run-on, but nothing is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-parameter tool with no output schema and no annotations, the description covers behavior, source priority, result volume, and error handling. The only missing piece an agent would want is the handoff to sticker_preview/sticker_send for the returned candidates.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, and the description adds a real constraint beyond the schema: query must contain only public emotion/action words and must not carry chat text, names, or QQ numbers. It says nothing about the optional 'target' parameter, relying entirely on the schema for that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('找表情' by a 1–16 character public emotion/action word) and adds the resolution chain (QQ favorites → meme cache → fixed sites) plus a result cap of 3. It is clearly distinguishable from sticker_collect/list/send, but it never explicitly contrasts itself with those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use input rules (public emotion/action words only), explicit prohibitions (no chat transcripts, person names, or QQ numbers), and an explicit failure path ('没有结果或冷却时本轮用文字,不要连续重试'). The agent knows what to do both on success and on empty/cooldown outcomes.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sticker_listA

查看这个 QQ 账号收藏的表情包(含 AI 记下的含义/标签/使用次数)。query 可按备注、标签、用途过滤;refresh=true 立即从网关重新同步。返回文字清单,不占图像额度;没有备注的表情先用 sticker_preview 看图,再用 sticker_note 记下含义。

NameRequiredDescriptionDefault
limitNo最多返回几个,默认 12
queryNo按备注/标签/用途过滤的关键词,可省略
refreshNotrue = 立即从 QQ 网关强制重新同步收藏

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses that the output is a text list, that it does not consume image quota (a genuine behavioral trait an agent would otherwise guess wrong), and that refresh=true triggers an immediate forced resync. It stops short of warning about the cost/latency of a forced resync or how large result sets are paged.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded: capability, then filters, then the quota-saving return property, then the preview/note workflow. Every clause carries information, though the final workflow tip runs a little long relative to the rest.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description does the necessary work by stating the return is a text list containing meanings, tags and usage counts. It does not cover pagination behavior beyond the limit parameter, which is the only remaining unknown for an agent calling this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already defines limit, query and refresh. The description restates query's filter dimensions and refresh's resync semantics, adding emphasis but no new meaning, and it never mentions limit or its default of 12. Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('查看这个 QQ 账号收藏的表情包') and adds the payload detail an agent cares about (含义/标签/使用次数), which distinguishes it from a plain listing. It also names the follow-up siblings sticker_preview and sticker_note for un-annotated stickers, so the agent knows where this tool sits in the workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit conditions: use query to filter by 备注/标签/用途, use refresh=true to force a gateway resync, and for stickers lacking notes, preview first then record with sticker_note. The only gap is that it never positions this against the closest sibling, sticker_find, leaving that choice to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sticker_noteA

记录这张表情的含义(note)、情绪 tags 和适用场景(usage)。这是本机记忆、跨会话复用,不会改 QQ 官方备注。联网新图必须先 sticker_preview 看过才能记;note/usage 各 ≤60 字,tags ≤6 个、每个 ≤12 字。

NameRequiredDescriptionDefault
noteYes短梗意,如“猫猫得意偷笑”
tagsNo情绪/动作标签,如 ["得意","笑"]
usageNo适用场景,如“赢下比赛时接梗”
targetNo可选:会话标识
stickerIdYes表情标识

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the load and discloses key traits: it is local memory, reused across sessions, and does NOT modify the official QQ note — a meaningful side-effect clarification. It omits any mention of response format or failure behavior, keeping it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded, followed by constraints and the preview prerequisite in a compact two-sentence block. Efficient, with only minor redundancy in restating schema limits.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-output-schema, no-annotation local-memory write tool, the description covers the essentials: what is recorded, that it is local and non-destructive to official data, the preview prerequisite, and field limits. Only the post-write response behavior is unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all five parameters with examples and constraints. The description's character/count limits (note/usage ≤60, tags ≤6 each ≤12) merely repeat constraints already in the schema, adding little beyond baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource: it records a sticker's meaning (note), emotion tags, and usage scenarios into local memory. This is clear and distinguishable, though it never explicitly contrasts with sibling sticker_collect, so an agent might wonder about overlap with the collection tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit prerequisite/alternative: brand-new online stickers must first be viewed via sticker_preview before recording. This is a concrete when-to-use rule, but it does not say when to prefer this over other siblings like sticker_find or sticker_list.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sticker_previewA

看一张表情/梗图(联网新图必须先看):动图会取首中尾三帧拼成一张 JPEG。结合画面、表情、文字和反讽理解梗意,再用 sticker_note 记录含义。已标注过含义的图不必重复看。stickerId 用 sticker_list / sticker_find 返回的 id。

NameRequiredDescriptionDefault
targetNo可选:会话标识,用于看图额度的归属
stickerIdYes表情标识,来自 sticker_list / sticker_find

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the full burden, and it does disclose the key non-obvious behavior: animated images are reduced to a 3-frame JPEG composite, and stickers already annotated need not be re-viewed. It omits cost/quota implications (the schema mentions '看图额度' but the description does not warn about it) and does not say how the image is returned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action and the mandatory-preview rule are front-loaded, and each clause adds real information (GIF handling, interpretation guidance, next step, id source). It is dense with parenthetical asides, which slightly reduces readability but no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-parameter read tool with no annotations and no output schema, the description covers the essential behavior (composite frame output, interpretation guidance, dedupe rule) and the id source. It could have mentioned the preview quota tied to 'target', which remains undisclosed in prose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented. The description restates the stickerId provenance (sticker_list / sticker_find) but adds no format or constraint detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb and object ('看一张表情/梗图') and immediately specifies the output form for animated stickers (first/mid/last frames combined into one JPEG). An agent can tell this apart from sticker_note (which records meaning) and sticker_send (which sends) without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use ('联网新图必须先看'), explicit when-not-to-use ('已标注过含义的图不必重复看'), and the follow-up step ('再用 sticker_note 记录含义'). Alternatives are named by their purpose, leaving little inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sticker_sendA

在指定会话发一张表情:一条消息只能一张图,不能在同一气泡里附带文字;想说的话请用文字消息单独发。target 形如 group:123456 或 private:7890,必须在 allow 白名单里。发出前插件会校验白名单、最小间隔与每小时上限,越权或过频会被拒绝。

NameRequiredDescriptionDefault
targetYes会话标识 group:123456 / private:7890
atUserIdNo可选:要 @ 的 QQ 号(仅群聊)
stickerIdYes表情标识,来自 sticker_list / sticker_find
replyToMessageIdNo可选:要引用的消息 id(非零整数,可为负数)

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the safety burden well: it discloses pre-send validation of the allow whitelist, minimum interval, and hourly quota, plus that violations are rejected. It does not describe what a successful or rejected call returns, which leaves a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action, then constraints, then the target format and validation rules. It is dense but every clause carries a constraint the agent needs; it stops just short of ideal tightness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter mutation tool with no annotations and no output schema, it covers the key call-time risks (whitelist, rate limits, one-sticker-per-message, stickerId source). Return shape and error payload remain unspecified, which is the remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description adds meaning beyond the schema by stating target must match group:123456/private:7890 form AND be in the allow whitelist. The optional atUserId and replyToMessageId parameters are left to the schema, which is acceptable given full coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening clause states a concrete verb and resource (send one sticker into a specified conversation) and immediately adds the payload constraint. This makes it obviously distinct from the sibling read/inspect tools (sticker_list, sticker_find, sticker_preview, sticker_note).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly rules out combining a sticker with text in the same message and tells the agent to send text separately, and it points to sticker_list/sticker_find as the source of stickerId. What is missing is routing guidance against alternatives (e.g. when to use sticker_note vs this), but for a send tool the usage condition is clear.

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.

  1. 6 tool updatesv0.1.3
    • First observedsticker_collect
    • First observedsticker_find
    • First observedsticker_list
    • First observedsticker_note
    • First observedsticker_preview
    • First observedsticker_send

TDQS

A4.2/5.0

Scored across 6 tools

Disambiguation4/5

The tools have mostly distinct purposes: collect saves others' images, note records meaning, send posts, and preview displays an image. The only mild overlap is between sticker_list (filtering favorites by query) and sticker_find (searching favorites plus external sources by emotion/action), but the descriptions clarify the difference reasonably well.

Naming Consistency5/5

All six tools follow a predictable sticker_verb pattern: collect, list, find, preview, send, note. The prefix and verb style are uniform throughout.

Tool Count5/5

Six tools is well-scoped for a QQ sticker-management server. Each tool covers a distinct part of the workflow: collect, inspect, annotate, search, and send.

Completeness4/5

The tool surface covers the main lifecycle: collecting stickers, listing and searching them, previewing, annotating meaning, and sending. A notable gap is the absence of a remove/unfavorite operation, so agents cannot delete stickers from the collection.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    An MCP server that enables AI clients to send and receive QQ messages through NapCatQQ (OneBot v11) for both private and group chats. It supports message context management, real-time WebSocket listening, and human-like typing simulation.
    7
    26
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A MCP server that exposes QQ bot capabilities over Streamable HTTP, enabling clients to query bot status, read group and friend info, fetch chat history, and send group/private text messages.
    3
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Local-first custom sticker library for MCP agents, enabling image import, auto-tagging, search, and context-aware retrieval via standard MCP tools.
    31
    MIT