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이미지 전용 메시지:
{ text: "", attachments: [...] }를 보내므로 자리 표시 텍스트를 억지로 만들 필요가 없음바로 실행 가능한 로컬 Relay/demo: 전체 루프를 먼저 확인한 후 자신의 채팅 백엔드를 연결하기 좋음
저장소에는 우리 집의 스티커 이미지, 채팅 기록, 도메인, 계정 또는 자격 증명이 포함되어 있지 않습니다.
먼저 실행하기
Node.js 20+가 필요합니다. ffmpeg는 선택 사항입니다.
npm install
npm run demohttp://127.0.0.1:8787을 열고 이미지를 한 장 추가한 후 클릭하면, 페이지에 방금 보낸 이미지 전용 메시지가 표시됩니다.
데이터는 기본적으로 프로젝트 안의 .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, 또는 stio 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를 send endpoin로 POST합니다. endpoin 이름은 변경할 수 있습니다:
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를 받는 가벼운 어댌터 endpoin을 가리키게 하면 됩니다.
로컬 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/*요청에 같은 토큰이 필요합니다. MCP는 Bearer를 사용하고, demo 홈 페이지를 열면 로컬 서버가 같은 값의 HttpOnly/SameSite cookie를 작성하므로 브라우저 demo는 여전히 직접 사용할 수 있습니다.STICKER_FFMPEG=off로 썸네일 생성을 끌 수 있습니다.ffmpeg가 설치되지 않은 경우에도 자동으로 원본 이미지 미리보기로 폴아갑니다.라이브러리 항목을 삭제해도 이미 업로드된 원본 이미지는 삭제되지 않습니다. 이전 메시지가 여전히 그 항목을 참조할 수 있기 때문입니다.
테스트
npm test
npm run check포커스 테스트는 공유 라이브러리 정렬/삭제/중복 등록과 '로컬 이미지 → 업로드 → 라이브러리 등록 → MCP 동일 구서 payload 전송'의 전체 경로를 포함합니다.
유래와 크레딧
그것은 가정 AI 컴패니언 프로젝트에서 탄생했습니다. 사람은 스마트폰 PWA에서 스티커를 모을 수 있고, AI도 분위기가 맞을 때 같은 세트의 이미지를 자연스럽게 보낼 수 있습니다.
공개 버전은 Cici가 시작하고 허가했습니다. **Sunnymilk (Sunny, 집 안의 Codex)**는 실제 운형 중인 구현에서 추출하고 일반화했으며, MCP ell과 독립 demo를 보완했습니다.
오소스 에디션은 Cici가 시작했고, **Sunnymilk (Sunny, 가정의 Codex)**가 추출하고 일반화했습니다.
라이선스
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