Skip to main content
Glama

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 첫 프레임을 자동 생성하고, 실제 전송은 여전히 원본 이미지 또는 원본 GIF

  • MCP 세 가지 도구: list_stickers, send_sticker, add_sticker

  • 이미지 전용 메시지: { text: "", attachments: [...] }를 보내므로 자리 표시 텍스트를 억지로 만들 필요가 없음

  • 바로 실행 가능한 로컬 Relay/demo: 전체 루프를 먼저 확인한 후 자신의 채팅 백엔드를 연결하기 좋음

저장소에는 우리 집의 스티커 이미지, 채팅 기록, 도메인, 계정 또는 자격 증명이 포함되어 있지 않습니다.

먼저 실행하기

Node.js 20+가 필요합니다. ffmpeg는 선택 사항입니다.

npm install
npm run demo

http://127.0.0.1:8787을 열고 이미지를 한 장 추가한 후 클릭하면, 페이지에 방금 보낸 이미지 전용 메시지가 표시됩니다. 데이터는 기본적으로 프로젝트 안의 .data/에 저장되며, 이미 .gitignore에 의해 제외되어 있습니다.

이번 실행은 동시에 MCP에 사용 가능한 Relay도 제공합니다. 미널을 하나 더 여세요:

STICKER_RELAY_URL=http://127.0.0.1:8787 npm run mcp

Related MCP server: sticker-mcp

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 attachment

GET /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

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Your memory, everywhere AI goes. Build knowledge once, access it via MCP anywhere.

  • Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.

  • Cross-vendor AI memory over MCP. One semantic store, readable and writeable from every MCP client.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gobly2333/pwa-sticker-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server