Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Zyte 유료 호출은 중지되어 있으며 키를 설정해도 활성화되지 않습니다.
# ZYTE_API_KEY=legacy_key_unused
GOOGLE_MAPS_API_KEY=your_google_maps_api_key_here
# 카카오맵 무료 쿼터 대상 앱에서 Maps API를 활성화한 뒤 설정합니다.
KAKAO_REST_API_KEY=your_kakao_rest_api_key_here
# GOOGLE_MAPS_API_KEY는 위치 검색에서 사용하지 않습니다.
NAVER_CLIENT_ID=your_naver_client_id_here
NAVER_CLIENT_SECRET=your_naver_client_secret_here
OPINET_API_KEY=your_opinet_api_key_here
Expand Down
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

# Daiso MCP 및 Skill

다이소(제품/매장/재고), 상품 가격 비교, 주변 음식점/카페, 주유소/유가, 개발자 요청 제출, 롯데마트(매장/상품), GS25(매장/상품/재고), 세븐일레븐(상품/매장/재고/인기검색어/카탈로그), CU(매장/재고), 이마트24(매장/상품/재고), 올리브영(매장/재고), 메가박스(지점/영화/시간표/좌석), 롯데시네마(지점/영화/좌석), CGV(극장/영화/시간표), 디트릭스(독립·예술영화관/상영작/잔여 좌석) 조회 기능을 MCP, CLI, Codex Skill로 AI에 연결합니다.
다이소(제품/매장/재고), 상품 가격 비교, 주변 음식점/카페, 주유소/유가, 개발자 요청 제출, GS25(매장/상품/재고), 세븐일레븐(상품/매장/재고/인기검색어/카탈로그), CU(매장/재고), 이마트24(매장/상품/재고), 올리브영(매장/재고), 메가박스(지점/영화/시간표/좌석), 롯데시네마(지점/영화/좌석), CGV(극장/영화/시간표), 디트릭스(독립·예술영화관/상영작/잔여 좌석) 조회 기능을 MCP, CLI, Codex Skill로 AI에 연결합니다.

디트릭스의 지원 범위와 CLI 예시는 [독립·예술영화관 조회 가이드](docs/dtryx.md)를 참고하세요.

Expand Down Expand Up @@ -57,7 +57,7 @@
</tr>
<tr>
<td>리테일</td>
<td>다이소, 올리브영, 롯데마트</td>
<td>다이소, 올리브영</td>
<td>상품, 매장, 재고</td>
</tr>
<tr>
Expand Down Expand Up @@ -95,7 +95,7 @@
</div>

> [!IMPORTANT]
> 최근 공개 서버 사용량이 크게 증가하여 2026년 7월 18일부터 올리브영·CGV·CU·GS25·롯데마트의 검색을 포함한 공개 GET API에 IP당 하루 합산 3,000회(KST 기준)의 호출 제한을 적용합니다. 한도를 초과하는 사용이 필요하다면 Daiso MCP는 오픈 소스이므로 이 저장소를 직접 배포해 이용해 주세요.
> 최근 공개 서버 사용량이 크게 증가하여 2026년 7월 18일부터 올리브영·CGV·CU·GS25의 검색을 포함한 공개 GET API에 IP당 하루 합산 3,000회(KST 기준)의 호출 제한을 적용합니다. 한도를 초과하는 사용이 필요하다면 Daiso MCP는 오픈 소스이므로 이 저장소를 직접 배포해 이용해 주세요.

<div align="center">

Expand Down Expand Up @@ -136,8 +136,6 @@ ChatGPT, Claude, Home Assistant, Grok 같은 AI 앱에서 바로 연결해 사
콜라 어디가 싼지 비교해줘
올리브영 mcp로 명동 근처 매장 찾아줘
이마트24 mcp로 강남 근처 매장과 두바이 재고 알려줘
롯데마트 mcp로 잠실 근처 매장 찾아줘
롯데마트 mcp로 강변점에서 콜라 재고 알려줘
GS25 mcp로 강남 근처 매장과 오감자 재고 알려줘
세븐일레븐 mcp로 삼각김밥 검색해줘
세븐일레븐 mcp로 안산 중앙역 근처 매장 찾아줘
Expand Down Expand Up @@ -183,8 +181,6 @@ CGV mcp로 강남 상영 영화와 시간표 알려줘
올리브영 mcp를 사용해서 명동 근처 매장 찾아줘
올리브영 mcp를 사용해서 선크림 재고 확인해줘
이마트24 mcp를 사용해서 강남 매장 찾고 두바이 재고 확인해줘
롯데마트 mcp를 사용해서 잠실 근처 매장 찾아줘
롯데마트 mcp를 사용해서 강변점에서 콜라 검색해줘
GS25 mcp를 사용해서 강남 매장 찾고 오감자 재고 확인해줘
세븐일레븐 mcp를 사용해서 안산 중앙역 근처 매장 찾고 핫식스 재고 확인해줘
메가박스 mcp를 사용해서 강남역 근처 지점 찾아줘
Expand Down Expand Up @@ -318,8 +314,6 @@ npx daiso cu-inventory 과자 --storeKeyword 강남
npx daiso cgv-theaters 강남 --limit 10
npx daiso cgv-movies --playDate 20260307 --theaterCode 0056
npx daiso cgv-timetable --playDate 20260307 --theaterCode 0056
npx daiso lottemart-stores 잠실 --area 서울 --limit 10
npx daiso lottemart-products 콜라 --storeName 강변점 --area 서울
npx daiso emart24-stores 강남 --service24h true
npx daiso emart24-products 두바이 --pageSize 20
npx daiso emart24-inventory 8800244010504 --bizNoArr 28339,05015
Expand Down Expand Up @@ -404,7 +398,7 @@ GET /api/opinet/stations/around?x=314681.8&y=544837&radiusMeters=3000&fuelCode=B
GET /api/opinet/station?id=A0010207
```

오피넷 API 키는 `OPINET_API_KEY` 환경 변수 또는 Cloudflare Worker Secret으로 설정합니다. 키 발급은 오피넷 웹사이트의 `유가관련정보 > 유가정보 API > 인증키 발급`에서 진행합니다. 반경 검색은 `lat/lng`, `location`, KATEC `x/y`를 모두 지원하며, `location` 검색에는 `GOOGLE_MAPS_API_KEY`가 필요합니다.
오피넷 API 키는 `OPINET_API_KEY` 환경 변수 또는 Cloudflare Worker Secret으로 설정합니다. 키 발급은 오피넷 웹사이트의 `유가관련정보 > 유가정보 API > 인증키 발급`에서 진행합니다. 반경 검색은 `lat/lng`, `location`, KATEC `x/y`를 모두 지원하며, `location` 검색에는 `KAKAO_REST_API_KEY`를 설정합니다. 역명·상호명은 네이버 지역 검색으로 보완합니다. 자세한 설정은 [무료 위치 검색 가이드](./docs/free-location-search.md)를 확인하세요.

운영 제약 및 캐싱 정책:

Expand All @@ -415,7 +409,7 @@ GET /api/opinet/station?id=A0010207
- `GET /api/opinet/lowest`: 30분 캐시, 10분 stale-while-revalidate
- `GET /api/opinet/stations/around`: 20분 캐시, 5분 stale-while-revalidate
- `GET /api/opinet/station`: 60분 캐시, 10분 stale-while-revalidate
- `location` 키워드의 Google Geocoding 결과는 Worker 인스턴스 메모리에서 24시간 캐시합니다.
- 주소·장소명 변환은 카카오 주소/키워드 검색을 사용합니다. 직접 좌표를 입력하면 위치 변환 API를 호출하지 않습니다.
- 호출 한도에 자주 도달하면 운영자가 담당 기관인 한국석유공사/오피넷에 문의해 추가 할당량 또는 별도 이용 조건을 협의할 예정입니다.

### 개발자 요청 제출
Expand All @@ -437,6 +431,10 @@ GET /api/feedback/requests?type=bug&title=제목&description=설명

로컬 실행이나 배포 환경에는 `SUPABASE_URL`, `SUPABASE_SERVICE_ROLE_KEY`를 설정하세요. 테이블 스키마는 [supabase-agent-requests.sql](./docs/supabase-agent-requests.sql)에 있습니다.

### 무료 위치 검색

주소·역명·상호명을 좌표로 바꾸는 기능은 카카오맵 무료 API를 사용합니다. Google Geocoding과 Zyte는 호출하지 않습니다. 카카오 무료 쿼터 대상 확인, 환경 변수와 실패 시 동작은 [무료 위치 검색 가이드](./docs/free-location-search.md)에 있습니다.

### 운영 헬스 체크

공개 상태 페이지: **[Daiso MCP Status](https://aka-page.betteruptime.com/)**
Expand All @@ -453,7 +451,7 @@ curl -H "Authorization: Bearer $HEALTH_CHECK_SECRET" \
주요 쿼리:

- `service=gs25`: 특정 서비스만 확인
- `check=lottemart.products`: 특정 체크만 확인
- `check=daiso.products`: 특정 체크만 확인
- `mode=quick|deep|full`: 체크 모드 선택
- `fresh=true`: 60초 캐시 우회
- `includeSamples=true`: 첫 결과 이름 샘플 포함
Expand Down Expand Up @@ -484,7 +482,7 @@ curl -H "x-health-check-key: $HEALTH_CHECK_SECRET" \
"https://mcp.aka.page/api/rate-limit/stats?service=cgv"
```

쿼리 필터는 `from`, `to`, `service`입니다. `from`과 `to`는 함께 지정하거나 둘 다 생략해야 하며 날짜 형식은 `YYYY-MM-DD`입니다. `service`에는 `oliveyoung`, `cgv`, `cu`, `gs25`, `lottemart`만 사용할 수 있습니다. 날짜를 생략하면 현재 KST 일자를 포함한 최근 7일을 조회합니다. 조회 가능한 보관 범위는 현재 KST 일자와 그 이전 29일이며, 한 번에 KST 달력 날짜 기준 최대 30일을 요청할 수 있습니다.
쿼리 필터는 `from`, `to`, `service`입니다. `from`과 `to`는 함께 지정하거나 둘 다 생략해야 하며 날짜 형식은 `YYYY-MM-DD`입니다. `service`에는 `oliveyoung`, `cgv`, `cu`, `gs25`, `lottemart`만 사용할 수 있습니다. `lottemart` 필터는 지원 중단 전 호출 제한 통계를 조회하기 위해 유지합니다. 날짜를 생략하면 현재 KST 일자를 포함한 최근 7일을 조회합니다. 조회 가능한 보관 범위는 현재 KST 일자와 그 이전 29일이며, 한 번에 KST 달력 날짜 기준 최대 30일을 요청할 수 있습니다.

성공 응답은 전체 합계와 일별·서비스별 차단 요청 수와 고유 차단 주체 수를 제공합니다.

Expand Down Expand Up @@ -640,7 +638,9 @@ daiso 인터랙티브 모드
- [이마트24 앱 스크래핑 준비 가이드](./docs/emart24-app-scraping-preparation-guide.md)
- [이마트24 앱 스크래핑 리플레이 가이드](./docs/emart24-app-scraping-replay-guide.md)

### 롯데마트
### 롯데마트 과거 분석

롯데마트 지원은 중단했습니다. 기존 REST 경로는 `410 SERVICE_RETIRED`, 기존 CLI 명령은 지원 중단 오류를 반환합니다.

- [롯데마트 모바일 도와센터 스크래핑 리플레이 계획](./docs/lottemart-mobile-scraping-replay-plan.md)

Expand Down
16 changes: 5 additions & 11 deletions docs/ai-instruction.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
당신은 다이소/통합 가격 후보 비교/주변 음식점·카페/롯데마트/GS25/세븐일레븐/CU/이마트24/올리브영/메가박스/롯데시네마/CGV 생활·쇼핑·영화 도우미입니다.
당신은 다이소/통합 가격 후보 비교/주변 음식점·카페/GS25/세븐일레븐/CU/이마트24/올리브영/메가박스/롯데시네마/CGV 생활·쇼핑·영화 도우미입니다.

다이소/통합 가격 후보 비교/주변 음식점·카페/롯데마트/GS25/세븐일레븐/CU/이마트24/올리브영/메가박스/롯데시네마/CGV 관련 정보는 모두 mcp.aka.page 작업 기능만
다이소/통합 가격 후보 비교/주변 음식점·카페/GS25/세븐일레븐/CU/이마트24/올리브영/메가박스/롯데시네마/CGV 관련 정보는 모두 mcp.aka.page 작업 기능만
사용하고, 웹검색은 하지 마세요.
mcp.aka.page 작업 기능 호출 중 에러가 나면 아래 문구로 안내하세요:
"ChatGPT 계정 로그인이 필요합니다. (다이소/통합 가격 후보 비교/주변 음식점·카페/롯데마트/GS25/세븐일레븐/CU/이마트24/올리브영/메가박스/롯데시네마/CGV 서비스
"ChatGPT 계정 로그인이 필요합니다. (다이소/통합 가격 후보 비교/주변 음식점·카페/GS25/세븐일레븐/CU/이마트24/올리브영/메가박스/롯데시네마/CGV 서비스
자체 로그인은 필요 없습니다.)"

## 언어 감지 및 역할 설정
Expand Down Expand Up @@ -32,7 +32,6 @@ mcp.aka.page 작업 기능 호출 중 에러가 나면 아래 문구로 안내
- 세븐일레븐: `seveneleven_*` 도구만 사용
- CU: `cu_*` 도구만 사용
- 이마트24: `emart24_*` 도구만 사용
- 롯데마트: `lottemart_*` 도구만 사용
- 올리브영: `oliveyoung_*` 도구만 사용
- 통합 가격 후보 비교: `compare_products` 또는 `compareProducts` action 사용
- 개발자 요청 제출: `submit_developer_request` 또는 `submitDeveloperRequest` action 사용
Expand Down Expand Up @@ -78,8 +77,6 @@ mcp.aka.page 작업 기능 호출 중 에러가 나면 아래 문구로 안내
- 이마트24 매장 탐색: 키워드/지역 조건 기반 이마트24 매장 조회
- 이마트24 상품 검색: 키워드 기반 상품 목록 조회
- 이마트24 재고 확인: PLU 코드 + 매장 코드 목록 기반 재고 조회
- 롯데마트 주변 매장 탐색: 지역/키워드/좌표 기반 롯데마트 계열 매장 조회
- 롯데마트 상품 검색: 특정 매장을 기준으로 상품 가격/재고 조회
- 올리브영 주변 매장 탐색: 사용자 위치 기반 매장 조회
- 올리브영 재고 파악: 상품 키워드 기준 재고/품절 여부 및 주변 매장 정보 조회
- 메가박스 주변 지점 탐색: 사용자 위치 기준 가까운 영화관 조회
Expand All @@ -94,7 +91,7 @@ mcp.aka.page 작업 기능 호출 중 에러가 나면 아래 문구로 안내

## 워크플로우

1. 사용자가 브랜드(다이소/롯데마트/GS25/세븐일레븐/CU/이마트24/올리브영/메가박스/롯데시네마/CGV)를 명시하면 품목상 어울리지 않아 보여도 먼저 해당 서비스 도구로 실제 조회를 수행
1. 사용자가 브랜드(다이소/GS25/세븐일레븐/CU/이마트24/올리브영/메가박스/롯데시네마/CGV)를 명시하면 품목상 어울리지 않아 보여도 먼저 해당 서비스 도구로 실제 조회를 수행
- 금지 예시: "핫식스는 다이소가 아니라 편의점 상품이라서 다이소 조회를 생략하겠습니다."
- 올바른 예시: "먼저 다이소 기준으로 검색해보고, 없으면 그때 다른 브랜드를 제안하겠습니다."
- 예시 해석: "안산 중앙역 주변 다이소 찾아주시고 핫식스 재고 찾아주세요"는 뒤의 핫식스 재고 요청도 다이소 기준으로 처리
Expand All @@ -114,15 +111,14 @@ mcp.aka.page 작업 기능 호출 중 에러가 나면 아래 문구로 안내
- 세븐일레븐: `keyword`로 재고 조회, 필요 시 `storeKeyword`를 함께 사용
- CU: `keyword`로 재고 조회, 필요 시 `storeKeyword`/위치(`lat`,`lng`) 반영
- 이마트24: 먼저 상품 검색으로 `pluCd`를 확인하고 `storeKeyword` 또는 `bizNoArr`와 함께 재고 조회
- 롯데마트: 먼저 `lottemart_find_nearby_stores` 또는 매장명으로 점포를 특정한 뒤 `lottemart_search_products` 호출
- 올리브영: 상품 후보/종류 질문은 먼저 상품 검색, 재고 질문은 `keyword`로 재고 조회, 필요 시 `storeKeyword`/위치(`lat`,`lng`) 반영

- 메가박스: `keyword`나 좌표가 있으면 먼저 가까운 지점을 특정하고, 상영작/회차 조회 후 필요 시 `theaterId`/`movieId`로 잔여 좌석 조회
- 롯데시네마: 먼저 상영작/회차 조회 후 필요 시 `theaterId`/`movieId`로 잔여 좌석 조회
- CGV: `keyword`나 좌표가 있으면 먼저 가까운 극장을 특정하고, 상영작/회차 조회 후 필요 시 `theaterCode`/`movieCode`로 잔여 좌석 조회

4. 결과는 핵심 정보 중심으로 보기 쉽게 정리
- 다이소/롯데마트/GS25/세븐일레븐/CU/이마트24/올리브영: 상품명, 가격, 재고 여부, 매장명/거리
- 다이소/GS25/세븐일레븐/CU/이마트24/올리브영: 상품명, 가격, 재고 여부, 매장명/거리
- 메가박스/롯데시네마/CGV: 영화명, 극장명, 상영시간, 잔여좌석/총좌석, 거리
- 이미지 렌더링 강제 규칙:
- 규칙 1: MCP/REST 응답에 `imageUrl`이 있으면 반드시 마크다운 이미지로 렌더링
Expand Down Expand Up @@ -154,8 +150,6 @@ mcp.aka.page 작업 기능 호출 중 에러가 나면 아래 문구로 안내
- CU 재고 조회 시 `keyword`는 필수이며 필요 시 `storeKeyword`를 함께 사용
- 이마트24 재고 조회는 `pluCd` + `storeKeyword` 또는 `pluCd` + `bizNoArr` 조합을 사용
- 이마트24 매장 조회 후 `storeCode`를 모아 `bizNoArr`로 전달할 수 있고, 대화형 흐름에서는 기존 매장 키워드를 다시 넣어도 됨
- 롯데마트 상품 검색 시 `keyword`는 필수이며 `storeCode` 또는 `storeName` 중 하나가 필요
- 롯데마트 주변 매장 조회는 좌표가 없으면 `keyword` 또는 주소 지오코딩 결과에 따라 거리 계산이 보강될 수 있음
- 올리브영에서 "어떤 거 있나요", "종류 보여줘", "상품 목록" 요청은 먼저 `oliveyoung_search_products` 또는 `/api/oliveyoung/products` 사용
- `oliveyoung_search_products` 또는 `/api/oliveyoung/products` 응답의 `products[].imageUrl`이 있으면 각 상품 이미지를 반드시 마크다운으로 전부 렌더링
- 올리브영 이미지 URL의 query string(`?l=ko` 등)은 마크다운 렌더링 시 절대 삭제하지 않으며, 전체 URL을 그대로 사용
Expand Down
31 changes: 31 additions & 0 deletions docs/free-location-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 무료 위치 검색

주소·역명·상호명은 카카오맵 주소/키워드 검색으로 좌표를 구합니다. 역명·상호명 검색은 네이버 지역 검색으로 보완합니다. REST, MCP, CLI의 기존 위치 입력을 유지하며 Google Geocoding과 Zyte는 호출하지 않습니다.

## 설정

로컬 환경 변수 또는 Cloudflare Worker Secret에 다음 값을 설정하세요.

```text
KAKAO_REST_API_KEY
NAVER_CLIENT_ID
NAVER_CLIENT_SECRET
```

카카오 키는 주소와 장소명 변환에 사용합니다. 네이버 두 값은 장소명 검색 보완에 사용하며, 네이버 지역 검색을 주소 변환기로 사용하지 않습니다. 기존 음식점·카페 검색도 네이버 설정을 사용합니다.

2026년 10월 5일 기준 카카오맵 무료 쿼터는 계정에서 처음 활성화한 앱에만 제공됩니다. 카카오 콘솔에서 해당 앱이 무료 대상인지 확인하세요. 무료 대상 앱은 주소 검색과 키워드 검색에 각각 일간 100,000회 쿼터를 받습니다. 무료 대상이 아니라면 유료 API를 자동으로 활성화하지 마세요. 실제 대상 여부와 한도는 [카카오맵 안내](https://developers.kakao.com/docs/ko/kakaomap/common)와 [쿼터 문서](https://developers.kakao.com/docs/ko/getting-started/quota)를 확인하세요.

공개 서버의 다이소MCP 앱은 무료 대상임을 확인한 뒤 활성화했습니다. 별도로 배포하는 경우 자신의 앱 설정을 확인해야 합니다.

## 조회 동작

- 도로명·지번주소는 카카오 주소 검색을 사용합니다.
- 역명·상호명은 카카오 키워드 검색을 사용하고, 네이버 지역 검색으로 보완합니다.
- 사용자가 위도·경도 또는 오피넷 KATEC 좌표를 입력하면 사용자 위치 변환을 건너뜁니다.
- 검색 결과의 좌표·지역·이름을 검증합니다. 극장·주유소의 좌표가 필요한 주변 검색에서 위치 변환에 실패하면 다른 지역의 기본 좌표로 대체하지 않고 오류를 반환합니다. 편의점의 원본 키워드 검색은 해당 서비스가 제공하는 검색 방식으로 이어갈 수 있습니다.
- CGV 주변 검색은 공식 극장 목록과 가까운 장소 후보를 대조한 뒤 거리순으로 정렬합니다.

위치 변환을 복구해도 원본 서비스의 인증 오류나 재고 조회 차단까지 해결되는 것은 아닙니다. 서비스별 헬스 체크를 함께 확인하세요.

롯데마트 지원은 중단했습니다. MCP 도구와 기본 도움말에서는 제외하며, 기존 REST 경로는 외부 요청 없이 `410 SERVICE_RETIRED`, 기존 CLI 명령은 지원 중단 오류를 반환합니다. 과거 호출 제한 통계와 분석 문서는 보존합니다.
Loading
Loading