pwa-sticker-mcp
PWA Sticker MCP · Stickers compartidos
Permite que las personas y la IA compartan la misma biblioteca de stickers PWA: la persona hace clic en el cajón para enviar, y el modelo envía la misma imagen a través de MCP.
El cajón PWA orientado a las personas y el servidor MCP orientado a la IA comparten una única biblioteca de stickers y un único contrato de adjuntos.
Esta edición pública se ha extraído de forma independiente de las funciones en uso de una PWA familiar real, conservando las partes más útiles:
Cajón de stickers PWA: subida, carga diferida, orden por uso reciente, acceso a la gestión mediante pulsación larga o teclado, y eliminación.
Cuadrícula cuadrada compatible con iOS: no depinde de
aspect-ratio, que tiende a colapsar en las cuadrículas con desplazamiento.Vista previa estática en WebP en el cajón: cuando hay
ffmpeg, genera automáticamente el primer fotograma de 192px; el envío real sigue siendo la imagen original o el GIF original.Tres herramientas MCP:
list_stickers,send_sticker,add_sticker.Mensajes de solo imagen: envía
{ text: "", attachments: [...] }, sin necesidad de inventar un texto de relleno.Un Relay/demo local que se puede ejecutar directamente, ideal para ver el ciclo completo antes de conectar tu propio backend de chat.
El repositorio no contiene las imágenes de stickers, los registros de chat, los dominios, las cuentas ni las credenciales de nuestra familia.
Para empear
Requiere Node.js 20+; ffmpeg es opcional.
npm install
npm run demoAbre http://127.0.0.1:8787, añade una imagen y ha clic en ella; la página mostrara el menaje de solo imagen que acabas de enviar.
Los datos se guardan por defecto en .data/ dento del proyecto, que ya está excluido por .gitignore.
Esta ejecución también proporciona un Relay utilizable para MCP. Abre otra terminal:
STICKER_RELAY_URL=http://127.0.0.1:8787 npm run mcpRelated MCP server: Firmament Open Brain
Conexión con clientes MCP
Claude Desktop, Clude Code u otros clientes que soporten MCP por stdio pueden usar:
{
"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"
}
}
}
}Semántica de las herramientas:
list_stickers(query?): lista la biblioteca compartida; se puede filtrar por nombre.send_sticker(query): coincide por id, nombre completo o palabra clave única y envía.add_sticker(path, name?): registra en la biblioteca compartida una imagen local de la máquina donde se ejecuta el modelo, pero no la envía.
Si la palabra clave coincide con varias imágenes, la herramienta pide al modelo que acote; no elige una por su cuenta.
Integrar el cajón en una PWA existente
Importa el módulo y los estilos:
<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>Si se omite onSend, el componente envía el mismo payload mediante POST al endpoint send. El endpoint se puede renombrar:
new StickerDrawer({
root,
trigger,
endpoints: {
stickers: '/app/stickers',
upload: '/app/upload',
send: '/app/send'
}
})El componente usa variables CSS neutras; no obliga a quien lo integre a adoptar los colores del demo:
:root {
--psm-surface: #171717;
--psm-surface-muted: #242424;
--psm-ink: #fafafa;
--psm-muted: #b8b8b8;
--psm-accent: #f1b657;
--psm-danger: #e26363;
--psm-line: #343434;
}Contrato de la API Relay
El backend existente no necesita usar el servidor demo; basta con implementar las siguientes cinco solicitudes:
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 devuelve:
{
"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
}
]
}El payload principal de POST /api/send:
{
"text": "",
"attachments": [
{
"url": "/uploads/wave.gif",
"name": "wave hello",
"mime": "image/gif",
"kind": "image",
"width": 320,
"height": 240
}
]
}Si los campos de tu API de chat son diferentes, haz una conversión en onSend de la PWA y haz que STICKER_SEND_PATH de MCP apunte a un endpoint adaptador ligero que acepte el payload anterior.
Configuración del Relay local
HOST=127.0.0.1 \
PORT=8787 \
STICKER_DATA_DIR=/path/to/data \
STICKER_TOKEN=choose-a-token \
npm run demoPor defecto solo escucha en
127.0.0.1Una vez establedido
STICKER_TOKEN, todas las solicitudes/api/*requieren el mismo token: MCP usa Bearer; al abrir la página principal del demo, el servidor local escibe una cookie HttpOnly/SameSite con el mismo valor, por lo que el demo del navegador puede seguir usándose directamente.STICKER_FFMPEG=offdesactiva la generación de miniaturas; siffmpegno está instalado, también se vuelve automáticamente a la vista previa de la imagen original.Eliminar una entada de la biblioteca no borra la imagen original ya subida, porque los menajes antíguos aún pueden referenciarla.
Pruebas
npm test
npm run checkLas pruebas enfoadas cubren la ordenación, la eliminación y el registro de duplicados en la biblioteca compartida, así como el recorrido completo de «imagen local → subida → inserción en la biblioteca → payload de envío isomórfico mediante MCP».
Origen y créditos
Nació en un proyecto familiar de compañero de IA: las personas pueden acumular stickers en la PWA del móvil, y la IA también puede enviar de forma natural el mismo conjunto de imágenes cuando el tono lo requiere.
La edición pública fue iniciada y autorizada por Cici; Sunnymilk (Sunny, el Codex de la casa) la extrajo de la implementación en uso, la generalizó y completó con la envoltura de MCP y un demo independiente.
Edición de código abierto iniciada por Cici y extraída/generalizada por Sunnymilk (Sunny, el Codex del hogar).
Licencia
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