Skip to main content
Glama
README.md
# 다같이 가능한 시간 (When We Can)

단톡방에서 모두 가능한 약속 시간을 빠르게 잡아주는 일정 조율 MCP.

- **MCP 이름**: 다같이 가능한 시간
- **식별자**: `whenwecan`
- **사용**: 카카오 [PlayMCP](https://playmcp.kakao.com) 카탈로그에서 활성화
- **인증**: 없음 (poll_id 8자 base62 토큰으로 접근 제어)
- **사양**: Streamable HTTP · Stateless · Remote MCP (PlayMCP 가이드 준수)

## 90초 사용 시나리오

1. 카카오톡 AI 채팅창: "다음 주 평일 저녁 7-10시 중에 60분 약속 잡아줘"
2. AI가 `createPoll` 호출 → 폴 URL + 단톡방 공유용 카드 반환
3. 단톡방에 링크 공유 → 멤버들이 클릭, 닉네임 입력, 가능한 시간 ✓
4. "결과 확인해줘" → `getPollResults`로 가장 많이 가능한 시간 TOP 3
5. "화요일 8시로 확정" → `closePoll` → ISO 8601 시간 반환 → 톡캘린더 MCP에 그대로 전달

## 툴 (4개)

| 툴 | 역할 |
|----|------|
| `createPoll` | 새 폴 생성 (명시 슬롯 또는 날짜범위+시간창 자동 생성) |
| `getPollResults` | 응답 집계, 베스트 슬롯 TOP 3 |
| `addCandidateSlots` | 폴에 후보 슬롯 추가 |
| `closePoll` | 폴 마감, 확정 슬롯의 ISO 8601 출력 |

## 로컬 개발

### 1. 의존성

```bash
npm install
```

### 2. 환경변수

`.env.local`:

```bash
UPSTASH_REDIS_REST_URL=...      # Upstash Redis (Vercel Marketplace에서 자동 주입)
UPSTASH_REDIS_REST_TOKEN=...
WHENWECAN_PUBLIC_URL=http://localhost:3000
```

### 3. 실행

```bash
npm run dev
```

### 4. MCP Inspector로 검증

```bash
npm run inspector
# 또는 직접
npx @modelcontextprotocol/inspector http://localhost:3000/api/mcp
```

- 모든 툴이 보이는지
- 각 툴이 `name + description + inputSchema + annotations(5필드)` 모두 갖추는지
- `createPoll → getPollResults → closePoll` 한 사이클 동작하는지

### 5. 단위 테스트

```bash
npm test
```

순수 함수(`lib/slots.ts`)에 대한 vitest 단위 테스트만 포함. Redis 의존 모듈은 통합 환경에서 검증.

## Vercel 배포

1. Vercel에 프로젝트 import
2. Vercel Marketplace에서 **Upstash Redis** 통합 추가 → `UPSTASH_REDIS_REST_URL/TOKEN` 자동 주입
3. 환경변수 `WHENWECAN_PUBLIC_URL` 추가 (예: `https://whenwecan.vercel.app`)
4. 첫 배포 후 `https://<domain>/api/mcp`에 MCP Inspector를 붙여 동작 확인

## PlayMCP 등록 절차

[`docs/superpowers/specs/2026-06-24-whenwecan-design.md`](./docs/superpowers/specs/2026-06-24-whenwecan-design.md) §9 등록 정보 참조.

PlayMCP 개발자 콘솔 → "새로운 MCP 서버 등록":

| 항목 | 값 |
|------|----|
| MCP 이름 | 다같이 가능한 시간 |
| MCP 식별자 | `whenwecan` |
| 대표 이미지 | `public/icon.png` |
| 인증 방식 | 인증 사용하지 않음 |
| MCP Endpoint | `https://<domain>/api/mcp` |
| 대화 예시 | README 본문 90초 시나리오에 기재된 3가지 |

## 디렉터리 구조

```
app/
  api/mcp/route.ts           # MCP Streamable HTTP 엔드포인트
  p/[pollId]/                # 폴 페이지 (Server Component + 클라이언트 폼)
    page.tsx
    PollForm.tsx
    respond/route.ts         # 응답 제출 액션
    not-found.tsx
  layout.tsx, page.tsx, globals.css
lib/
  slots.ts                   # 슬롯 생성/교집합/추천 (순수 함수)
  slots.test.ts
  poll.ts                    # Redis 어댑터
  format.ts                  # 한국어 시간 포맷, 마크다운 카드
  mcp.ts                     # MCP 서버 + 툴 4개 정의
public/icon.png              # 대표 이미지 (1024x1024 PNG)
docs/superpowers/specs/      # 설계 스펙
```

## PlayMCP 가이드 준수 체크리스트

- [x] Streamable HTTP only / Remote / Stateless
- [x] MCP 스펙 2025-03-26 ~ 2025-11-25 (공식 SDK v1.x)
- [x] "kakao" 단어 미사용
- [x] 툴 4개 (권장 3~10 범위)
- [x] 모든 툴: name + description(영문 + 서비스명 영국문) + inputSchema + annotations 5필드
- [x] description 1024자 이내
- [x] Tool name에 서비스명 미포함 (prefix 자동 부착)
- [x] result는 정제된 마크다운
- [x] 응답속도 — 모든 핸들러가 단일 Redis read/write + 순수 계산
- [x] 광고 0

Maintenance

ActivityStale
ResponsivenessNo issues