pwa-sticker-mcp
PWA Sticker MCP · 共享表情包
让人和 AI 共用同一个 PWA 表情包库:人在抽屉里点一下发送,模型通过 MCP 调同一张图发送。
The human-facing PWA drawer and the AI-facing MCP server share one sticker library and one attachment contract.
这个公开版从真实家庭 PWA 的现役功能中独立抽出,保留了最有用的部分:
PWA 表情包抽屉:上传、懒加载、最近使用排序、长按或键盘进入管理、删除
iOS 友好的正方形网格:不依赖滚动 grid 中容易塌陷的
aspect-ratio静态 WebP 抽屉预览:有
ffmpeg时自动生成 192px 首帧,实际发送仍是原图或原 GIFMCP 三工具:
list_stickers、send_sticker、add_sticker图片-only 消息:发送
{ text: "", attachments: [...] },不必伪造一段占位文字一个可以直接运行的本地 Relay/demo,方便先看完整闭环再接自己的聊天后端
仓库不包含我们家的表情图片、聊天记录、域名、账号或凭据。
先跑起来
需要 Node.js 20+;ffmpeg 可选。
npm install
npm run demo打开 http://127.0.0.1:8787,添加一张图片并点它,页面会显示刚发出的 image-only 消息。
数据默认写在项目内的 .data/,已经被 .gitignore 排除。
这次运行同时给 MCP 提供了可用 Relay。另开一个终端:
STICKER_RELAY_URL=http://127.0.0.1:8787 npm run mcpRelated MCP server: Firmament Open Brain
接入 MCP 客户端
Claude Desktop、Claude Code 或其他支持 stdio MCP 的客户端可使用:
{
"mcpServers": {
"stickers": {
"command": "node",
"args": ["/absolute/path/to/pwa-sticker-mcp/src/mcp-server.js"],
"env": {
"STICKER_RELAY_URL": "https://chat.example.com",
"STICKER_TOKEN": "your-relay-token",
"STICKER_STICKERS_PATH": "/api/stickers",
"STICKER_UPLOAD_PATH": "/api/upload",
"STICKER_SEND_PATH": "/api/send"
}
}
}
}工具语义:
list_stickers(query?):列出共享库,可按名字过滤send_sticker(query):按 id、全名或唯一关键词匹配并发送add_sticker(path, name?):把模型所在机器上的本地图片登记进共享库,但不发送
关键词命中多张时工具会请模型收窄,不会擅自挑一张。
把抽屉装进现有 PWA
引入模块和样式:
<link rel="stylesheet" href="/sticker-drawer.css">
<div id="stickerDrawer"></div>
<button
id="stickerButton"
type="button"
aria-controls="stickerDrawer"
aria-expanded="false"
aria-pressed="false"
>
表情包
</button>
<script type="module">
import { StickerDrawer } from '/sticker-drawer.js'
new StickerDrawer({
root: document.querySelector('#stickerDrawer'),
trigger: document.querySelector('#stickerButton'),
apiBase: 'https://chat.example.com',
headers: () => ({ Authorization: `Bearer ${getRelayToken()}` }),
async onSend(attachment) {
await sendMessage({ text: '', attachments: [attachment] })
},
onNotice(message, kind) {
showToast(message, kind)
}
})
</script>省略 onSend 时,组件会把相同 payload POST 到 send endpoint。端点可改名:
new StickerDrawer({
root,
trigger,
endpoints: {
stickers: '/app/stickers',
upload: '/app/upload',
send: '/app/send'
}
})组件使用中性的 CSS 变量,不要求接入者采用 demo 的颜色:
:root {
--psm-surface: #171717;
--psm-surface-muted: #242424;
--psm-ink: #fafafa;
--psm-muted: #b8b8b8;
--psm-accent: #f1b657;
--psm-danger: #e26363;
--psm-line: #343434;
}Relay API 合同
现有后端不必使用 demo server,只要实现下面五个请求:
GET /api/stickers
POST /api/upload?name=<filename> raw image body
POST /api/stickers register uploaded metadata
POST /api/stickers/<id>/use update recent-use order
DELETE /api/stickers/<id>
POST /api/send send an image attachmentGET /api/stickers 返回:
{
"stickers": [
{
"id": "abc123",
"name": "wave hello",
"url": "/uploads/wave.gif",
"thumb_url": "/uploads/sticker-thumb-wave.webp",
"mime": "image/gif",
"width": 320,
"height": 240,
"last_used": 1787800000
}
]
}POST /api/send 的核心 payload:
{
"text": "",
"attachments": [
{
"url": "/uploads/wave.gif",
"name": "wave hello",
"mime": "image/gif",
"kind": "image",
"width": 320,
"height": 240
}
]
}如果你的聊天 API 字段不同,在 PWA 的 onSend 里转换一次,并让 MCP 的
STICKER_SEND_PATH 指向一个接受上述 payload 的轻量适配端点即可。
本地 Relay 配置
HOST=127.0.0.1 \
PORT=8787 \
STICKER_DATA_DIR=/path/to/data \
STICKER_TOKEN=choose-a-token \
npm run demo默认只监听
127.0.0.1设置
STICKER_TOKEN后,所有/api/*请求要求同一个 token:MCP 使用 Bearer;打开 demo 首页时, 本地服务器会写入同值的 HttpOnly/SameSite cookie,所以浏览器 demo 仍能直接使用STICKER_FFMPEG=off可关闭缩略图生成;未安装ffmpeg时也会自动退回原图预览删除库条目不会删除已经上传的原图,因为旧消息仍可能引用它
测试
npm test
npm run check聚焦测试覆盖共享库排序/删除/重复登记,以及“本地图片 → 上传 → 入库 → MCP 同构发送 payload”的完整路径。
来历与署名
它诞生于一个家庭 AI 伴侣项目:人可以在手机 PWA 里攒表情包,AI 也能在语气到了时自然发同一套图。
公开版由 词词 发起并授权;Sunnymilk(Sunny,家里的 Codex) 从现役实现中抽取、泛化、补齐 MCP 壳与独立 demo。
Open-source edition initiated by Cici and extracted/generalized by Sunnymilk (Sunny, the household Codex).
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Persistent personal memory for AI assistants — save, search, and recall across every MCP client.
Cross-tool persistent memory and context for AI assistants over MCP.
- JustOnceOAuthai.justonce
Persistent memory for AI assistants — one shared, OAuth-secured vault for every MCP client.
Your memory, everywhere AI goes. Build knowledge once, access it via MCP anywhere.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI to send expressive stickers based on conversation context, with a built-in UI for managing stickers.58MIT
- FlicenseNot gradedqualityCmaintenanceEnables each user to have a private, per-user memory store that persists across AI tools, allowing them to store, recall, search, list, and delete memories via MCP.-
- AlicenseNot gradedqualityBmaintenanceLocal-first custom sticker library for MCP agents, enabling image import, auto-tagging, search, and context-aware retrieval via standard MCP tools.27MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI chat clients to search, manage, and send custom meme/sticker images through MCP, with images stored in SQLite and served via public URLs; supports MCP Apps displaying images inline in chat.2MIT