8000 fix: GPT Actions 지원 서비스와 갱신 지침 정리 by hmmhmmhm · Pull Request #296 · hmmhmmhm/daiso-mcp · GitHub
[go: up one dir, main page]

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
11 changes: 7 additions & 4 deletions docs/client-guide.md
< 8000 col width="40">
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,18 @@ GS25 mcp로 강남 근처 매장과 오감자 재고 알려줘
CGV mcp로 강남 상영 영화와 시간표 알려줘
```

GPT Actions는 `queryAction` 하나로 REST를 호출합니다. 원격 MCP의 통합 도구10개와 인수 형식이 다릅니다. [GPT 갱신 지침](gpts-maintenance.md)에서 최신 스키마와 유지보수 방법을 확인하세요.

에이전트가 고르면 좋은 대표 흐름:

- 가격 비교: `콜라 어디가 싸?` → `compare_products`
- 주변 장소: `강남역 근처 카페 찾아줘` → `places_search_nearby`
- 주유소/유가: `강남역 근처 제일 싼 주유소 찾아줘` → `opinet_search_stations_around`
- 가격 비교: `콜라 어디가 싸?` → `queryAction(action=compareProducts)`
- 주변 장소: `강남역 근처 카페 찾아줘` → `queryAction(action=placesSearchNearby)`
- 주유소/유가: `강남역 근처 제일 싼 주유소 찾아줘` → `queryAction(action=opinetSearchStationsAround)`
- 브랜드 명시 재고: `다이소 핫식스 재고 찾아줘` → 먼저 다이소에서 검색 후 결과 없을 때만 대안 제안
- 편의점 재고: `GS25 강남 오감자 재고` → 상품 후보 확인 후 재고 조회
- 일본 다이소: `일본 다이소 ボウル 검색해줘` → `queryAction(action=daisoJpSearchProducts,q=ボウル)`. 매장별 재고는 지원하지 않습니다.
- 영화 시간표: `오늘 강남 CGV 시간표` → KST 오늘 날짜로 극장 검색 후 시간표 조회
- 개발자 요청: `올리브영 재고 도구가 계속 실패한다고 개발자에게 알려줘` → `submit_developer_request`
- 개발자 요청: `올리브영 재고 도구가 계속 실패한다고 개발자에게 알려줘` → `queryAction(action=submitDeveloperRequest)`

<br>

Expand Down
45 changes: 45 additions & 0 deletions docs/gpts-maintenance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# DAISO MCP GPT 갱신

기존 GPT: https://chatgpt.com/g/g-69a5266c32108191b71a24642dc63f9e-daiso-mcp

## 연동 계약

이 GPT는 원격 MCP 연결이 아니라 GPT Actions의 REST 연동입니다. 등록 스키마는 https://mcp.aka.page/openapi.json, 인증은 없음, 개인정보처리방침은 https://mcp.aka.page/privacy 입니다. 스키마를 다시 불러온 뒤 operationId `queryAction` 하나를 유지하고 action enum으로 기능을 선택합니다. MCP의 service/operation 인수나 deprecated 도구 이름을 Actions 호출에 그대로 넣지 않습니다. 공개 MCP의 도구10개 고정 규칙은 별도로 유지합니다.

Actions는 JSON 응답을 직접 소비합니다. 웹 검색/웹 읽기로 REST URL을 열 때에만 모든 후속 요청까지 `format=html`을 반드시 넣습니다. 웹으로 페이지를 읽은 것만으로 MCP나 Actions 연결이 생기지는 않습니다.

## 갱신용 설명

다이소·편의점·올리브영 재고, 영화 시간표와 생활 정보를 조회합니다. 일본 다이소의 상품·매장 검색도 지원합니다.

## 갱신용 지침

```text
당신은 DAISO MCP의 실제 조회 결과로 상품·매장·재고·영화·생활 정보를 안내합니다. 사용자의 언어로 간결하게 답하고 em dash를 사용하지 않습니다.

실행 수단은 GPT Actions의 queryAction입니다. action 선택값과 해당 인수를 사용합니다. 원격 MCP 도구의 service/operation 인수를 queryAction에 넣지 않습니다. 설치나 API 키 준비를 사용자에게 요구하지 않습니다.

브랜드와 국가를 유지합니다. 한국 다이소, 일본 다이소, GS25, CU, 세븐일레븐, 이마트24, 올리브영, 메가박스, 롯데시네마, CGV, 디트릭스, 네이버 장소 검색, 오피넷을 지원합니다. 롯데마트는 지원 중단이며 MINISO는 지원하지 않습니다. 일본 다이소는 상품·매장 검색과 온라인 구매 가능 여부를 제공하지만 매장별 재고 수량은 지원하지 않습니다. 한국 KRW와 일본 JPY를 섞어 가격을 비교하지 않습니다.

한국 다이소: daisoSearchProducts(q)로 실제 상품 ID를 얻고 daisoCheckInventory(productId,keyword 또는 lat/lng)로 조회합니다. 상품 검색 성공만으로 매장 재고가 있다고 말하지 않습니다. 상품 상세는 daisoGetProduct(productId), 진열 위치는 daisoGetDisplayLocation의 입력 스키마를 따릅니다.
일본 다이소: daisoJpSearchProducts(q), daisoJpGetProduct(productId), daisoJpFindStores(keyword)를 사용합니다. 상세 productId는 검색한 실제 13자리 코드입니다. onlineAvailable은 온라인 구매 가능 여부이며 매장 실재고가 아닙니다.
편의점·올리브영: 서비스별 SearchProducts/CheckInventory/FindStores 액션을 사용합니다. 상품명과 지역명을 분리하고 선택한 상품 코드와 매장 조건을 사용합니다. CU는 cuCheckInventory로 상품명을 조회할 수 있습니다. 결과가 없거나 불명확할 때 임의로 상품·브랜드·지역을 바꾸지 않습니다.
영화: 먼저 해당 브랜드의 극장 검색으로 실제 극장 코드를 얻고 영화/시간표/잔여석 액션을 호출합니다. 오늘 날짜는 한국 시간 기준 YYYYMMDD입니다. 디트릭스는 dtryxListCinemas → dtryxListNowShowing 또는 dtryxGetRemainingSeats이며 검색 결과의 cinemaCode와 brandCode를 함께 사용합니다.
생활 정보: 가격 후보 비교는 compareProducts(keyword), 주변 음식점/카페는 placesSearchNearby(location,keyword), 전국 유가는 opinetGetAveragePrices, 최저가는 opinetGetLowestPriceStations, 주변 주유소는 opinetSearchStationsAround(location 또는 lat/lng), 주유소 상세는 opinetGetStationDetail(stationId)입니다. stationId는 실제 검색 결과에서 얻습니다.

재고 0, 미확인 수량, 원본 차단, 자체 한도, 인증 오류를 구분합니다. 실패를 정상 품절이나 결과 없음으로 바꾸지 않습니다. 실제 호출 결과에 없는 수량·영업시간·가격·좌표·상품 코드를 만들지 않습니다. 실패 시 한 번만 조건을 좁혀 재시도하고 계속 실패하면 원인과 확인하지 못한 범위를 알립니다. 캐시 응답은 실시간 원본을 검증한 것처럼 설명하지 않습니다.

결과는 사용자에게 필요한 상품명·가격·매장명·주소·재고·상영 시각·남은 좌석 중심으로 정리합니다. 이미지 URL과 출처/상품 링크가 있으면 함께 제공합니다. 데이터가 없으면 없음과 미확인을 구분합니다.

사용자가 개발자 전달을 명시적으로 요청한 경우에만 submitDeveloperRequest를 사용합니다. 제목과 설명을 확인하고 비밀번호·인증 코드·토큰·쿠키·개인정보를 포함하지 않습니다. 테스트나 일반 조회 과정에서 요청을 임의로 제출하지 않습니다.

Actions 응답은 JSON으로 처리합니다. 웹 읽기를 보조 수단으로 사용할 때 모든 /api/* GET 링크에 format=html을 반드시 포함합니다. 웹 읽기 오류만으로 서버 장애나 로그인 필요를 단정하지 않습니다.
```

## 편집·검증

1. 기존 GPT의 지침·Actions·지식 파일·공개 범위를 읽고 필요한 내용을 보존합니다. 위 지침은 갱신 초안이며 기존 설정을 읽지 못한 상태에서 덮어쓰지 않습니다.
2. Actions의 URL 가져오기에서 최신 openapi.json을 불러와 queryAction과 신규 일본/오피넷 선택값을 확인합니다. 삭제된 롯데마트 액션은 노출하지 않습니다.
3. 상품 검색, 검색 결과의 실제 ID로 상세/재고, 일본 상품/매장, 유가, 미지원 롯데마트 질문을 평가합니다. 요청 제출 테스트는 운영 데이터를 만들지 않습니다.
4. GPT 편집기에서 오류가 없는지 확인한 뒤 기존 공개 범위를 유지하여 업데이트합니다. 저장/공개 완료 화면을 확인하고 실제 GPT 조회를 한 번 더 실행합니다.
5. 편집 권한 또는 사용자 인증이 필요한 경우 정확한 화면 상태를 안내합니다. 결제나 요금제 변경, 플러그인으로의 별도 마이그레이션을 임의로 진행하지 않습니다.
10 changes: 10 additions & 0 deletions docs/openapi-actions-facade.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,13 @@ ChatGPT Actions 등록이 더 이상 안정적으로 되지 않는 상태가 됐

이 구조는 "서비스 추가 시 OpenAPI path 수가 계속 증가하는 문제"를 해결하기 위한 설계입니다.
완전히 새로운 capability가 추가되더라도 기본 facade path는 그대로 유지하고 `action` 목록만 확장하면 됩니다.

## 2026-10-21 스키마 갱신

기본 스키마1.1.0은 operationId `queryAction` 하나를 유지하고 일본 다이소 3개, 오피넷 4개의 기존 GET 작업을 action enum에 연결합니다. 공개 MCP 도구10개 계약이나 기존 REST/CLI 이름은 바꾸지 않습니다.

- 일본: daisoJpSearchProducts(q), daisoJpGetProduct(productId), daisoJpFindStores(keyword). 상품 코드는 검색 결과의 실제13자리 값을 사용합니다. 온라인 구매 가능과 매장 재고를 구분합니다.
- 오피넷: opinetGetAveragePrices, opinetGetLowestPriceStations, opinetSearchStationsAround, opinetGetStationDetail. fuelCode/count/radiusMeters/x/y/stationId와 기존 location/lat/lng/areaCode를 사용합니다.
- GPT 편집기는 URL을 다시 불러와야 등록 스키마가 갱신됩니다. 서버 배포만으로 기존 GPT 저장 설정이 변경됐다고 보고하지 않습니다.

[GPT 설정·검증 지침](gpts-maintenance.md), [OpenAI 공식 Actions 시작 가이드](https://developers.openai.com/api/docs/actions/getting-started)를 참고하세요.
69 changes: 65 additions & 4 deletions openapi.jso 8000 n
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"openapi": "3.1.0",
"info": {
"title": "다이소 MCP API (OpenAI Actions용)",
"description": "OpenAI 챗봇의 OpenAPI import 개수 제한을 피하기 위해 모든 GET API를 단일 facade 엔드포인트로 집약한 스펙입니다.\n\n실제 런타임은 기존 /api/{service}/... 엔드포인트로 위임하며, 이 스펙은 OpenAI Actions 등록 전용으로 사용합니다.\n\n브랜드명이 요청 앞부분에 나오면 뒤의 상품/재고 요청까지 같은 브랜드로 해석해야 합니다. 예: \"안산 중앙역 주변 다이소 찾아주시고 핫식스 재고 찾아주세요\"는 다이소 기준 조회를 먼저 수행하고, 결과가 없을 때만 다른 브랜드를 제안합니다.\n\n전체 개별 엔드포인트 스펙이 필요하면 /openapi-full.json 또는 /openapi-full.yaml 을 사용하세요.",
"version": "1.0.0",
"title": "DAISO MCP API (OpenAI Actions용)",
"description": "OpenAI 챗봇의 OpenAPI import 개수 제한을 피하기 위해 모든 GET API를 단일 facade 엔드포인트로 집약한 스펙입니다.\n\n실제 런타임은 기존 /api/{service}/... 엔드포인트로 위임하며, 이 스펙은 OpenAI Actions 등록 전용으로 사용합니다.\n\n브랜드명이 요청 앞부분에 나오면 뒤의 상품/재고 요청까지 같은 브랜드로 해석해야 합니다. 예: \"안산 중앙역 주변 다이소 찾아주시고 핫식스 재고 찾아주세요\"는 다이소 기준 조회를 먼저 수행하고, 결과가 없을 때만 다른 브랜드를 제안합니다.\n\n일본 다이소는 상품·매장 검색과 온라인 구매 가능 여부만 제공하며 매장별 재고는 지원하지 않습니다. 오피넷 유가·주유소 조회도 action 선택값으로 제공합니다. 실패와 미확인 수량을 재고 0으로 해석하지 마세요.\n전체 개별 엔드포인트 스펙이 필요하면 /openapi-full.json 또는 /openapi-full.yaml 을 사용하세요.",
"version": "1.1.0",
"contact": {
"name": "GitHub Repository",
"url": "https://github.com/hmmhmmhm/daiso-mcp"
Expand All @@ -22,6 +22,60 @@
"summary": "공통 GET 액션 실행",
"description": "action 값에 따라 기존 GET API 엔드포인트로 프록시합니다. OpenAI Actions 등록 시 이 단일 엔드포인트를 사용하세요.",
"parameters": [
{
"name": "fuelCode",
"in": "query",
"required": false,
"description": "유종 코드. B027=휘발유, D047=경유, B034=고급휘발유, C004=실내등유, K015=자동차부탄",
"schema": {
"type": "string"
}
},
{
"name": "stationId",
"in": "query",
"required": false,
"description": "opinetGetStationDetail에 필요한 실제 주유소 ID. 검색 결과에서 얻습니다.",
"schema": {
"type": "string"
}
},
{
"name": "count",
"in": "query",
"required": false,
"description": "최저가 주유소 반환 개수",
"schema": {
"type": "integer"
}
},
{
"name": "radiusMeters",
"in": "query",
"required": false,
"description": "주변 주유소 검색 반경(m)",
"schema": {
"type": "integer"
}
},
{
"name": "x",
"in": "query",
"required": false,
"description": "오피넷 KATEC X좌표. 보통은 location 또는 lat/lng를 사용하세요.",
"schema": {
"type": "number"
}
},
{
"name": "y",
"in": "query",
"required": false,
"description": "오피넷 KATEC Y좌표. 보통은 location 또는 lat/lng를 사용하세요.",
"schema": {
"type": "number"
}
},
{
"name": "cinemaCode",
"in": "query",
Expand Down Expand Up @@ -81,6 +135,13 @@
"daisoSearchProducts",
"daisoGetProduct",
"daisoFindStores",
"daisoJpSearchProducts",
"daisoJpGetProduct",
"daisoJpFindStores",
"opinetGetAveragePrices",
"opinetGetLowestPriceStations",
"opinetSearchStationsAround",
"opinetGetStationDetail",
"daisoCheckInventory",
"daisoGetDisplayLocation",
"oliveyoungSearchProducts",
Expand Down Expand Up @@ -118,7 +179,7 @@
"name": "q",
"in": "query",
"required": false,
"description": "다이소 제품 검색어",
"description": "한국·일본 다이소 제품 검색어",
"schema": {
"type": "string"
}
Expand Down
50 changes: 47 additions & 3 deletions openapi.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@

openapi: 3.1.0
info:
title: 다이소 MCP API (OpenAI Actions용)
title: DAISO MCP API (OpenAI Actions용)
description: |
OpenAI 챗봇의 OpenAPI import 개수 제한을 피하기 위해 모든 GET API를 단일 facade 엔드포인트로 집약한 스펙입니다.

실제 런타임은 기존 /api/{service}/... 엔드포인트로 위임하며, 이 스펙은 OpenAI Actions 등록 전용으로 사용합니다.

브랜드명이 요청 앞부분에 나오면 뒤의 상품/재고 요청까지 같은 브랜드로 해석해야 합니다. 예: "안산 중앙역 주변 다이소 찾아주시고 핫식스 재고 찾아주세요"는 다이소 기준 조회를 먼저 수행하고, 결과가 없을 때만 다른 브랜드를 제안합니다.

일본 다이소는 상품·매장 검색과 온라인 구매 가능 여부만 제공하며 매장별 재고는 지원하지 않습니다. 오피넷 유가·주유소 조회도 action 선택값으로 제공합니다. 실패와 미확인 수량을 재고 0으로 해석하지 마세요.
전체 개별 엔드포인트 스펙이 필요하면 /openapi-full.json 또는 /openapi-full.yaml 을 사용하세요.
version: 1.0.0
version: 1.1.0
contact:
name: GitHub Repository
url: "https://github.com/hmmhmmhm/daiso-mcp"
Expand All @@ -24,6 +25,42 @@ paths:
summary: 공통 GET 액션 실행
description: action 값에 따라 기존 GET API 엔드포인트로 프록시합니다. OpenAI Actions 등록 시 이 단일 엔드포인트를 사용하세요.
parameters:
- name: fuelCode
in: query
required: false
description: 유종 코드. B027=휘발유, D047=경유, B034=고급휘발유, C004=실내등유, K015=자동차부탄
schema:
type: string
- name: stationId
in: query
required: false
description: opinetGetStationDetail에 필요한 실제 주유소 ID. 검색 결과에서 얻습니다.
schema:
type: string
- name: count
in: query
required: false
description: 최저가 주유소 반환 개수
schema:
type: integer
- name: radiusMeters
in: query
required: false
description: 주변 주유소 검색 반경(m)
schema:
type: integer
- name: x
in: query
required: false
description: 오피넷 KATEC X좌표. 보통은 location 또는 lat/lng를 사용하세요.
schema:
type: number
- name: y
in: query
required: false
description: 오피넷 KATEC Y좌표. 보통은 location 또는 lat/lng를 사용하세요.
schema:
type: number
- name: cinemaCode
in: query
required: false
Expand Down Expand Up @@ -67,6 +104,13 @@ paths:
- daisoSearchProducts
- daisoGetProduct
- daisoFindStores
- daisoJpSearchProducts
- daisoJpGetProduct
- daisoJpFindStores
- opinetGetAveragePrices
- opinetGetLowestPriceStations
- opinetSearchStationsAround
- opinetGetStationDetail
- daisoCheckInventory
- daisoGetDisplayLocation
- oliveyoungSearchProducts
Expand Down Expand Up @@ -100,7 +144,7 @@ paths:
- name: q
in: query
required: false
description: 다이소 제품 검색어
description: 한국·일본 다이소 제품 검색어
schema:
type: string
- name: query
Expand Down
7 changes: 7 additions & 0 deletions src/api/actionsProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ export const ACTION_QUERY_DEFINITIONS: ActionQueryDefinition[] = [
pathParam: 'productId',
},
{ action: 'daisoFindStores', summary: '다이소 매장 검색', targetPath: '/api/daiso/stores' },
{ action: 'daisoJpSearchProducts', summary: '일본 다이소 상품 검색', targetPath: '/api/daiso-jp/products' },
{ action: 'daisoJpGetProduct', summary: '일본 다이소 상품 상세', targetPath: '/api/daiso-jp/products/:productId', pathParam: 'productId' },
{ action: 'daisoJpFindStores', summary: '일본 다이소 매장 검색 (매장 재고 미지원)', targetPath: '/api/daiso-jp/stores' },
{ action: 'opinetGetAveragePrices', summary: '오피넷 전국 평균 유가', targetPath: '/api/opinet/average' },
{ action: 'opinetGetLowestPriceStations', summary: '오피넷 최저가 주유소', targetPath: '/api/opinet/lowest' },
{ action: 'opinetSearchStationsAround', summary: '오피넷 주변 주유소', targetPath: '/api/opinet/stations/around' },
{ action: 'opinetGetStationDetail', summary: '오피넷 주유소 상세', targetPath: '/api/opinet/station' },
{
action: 'daisoCheckInventory',
summary: '다이소 재고 조회',
Expand Down
4 changes: 3 additions & 1 deletion src/pages/openapiSpecActionParameters.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
/**
* OpenAI Actions용 축약 OpenAPI 스펙
*/
import { ACTION_FUEL_PARAMETERS } from './openapiSpecFuelParameters.js';
import { ACTION_QUERY_ACTIONS } from '../api/actionsProxy.js';

export const ACTION_QUERY_PARAMETERS = [
...ACTION_FUEL_PARAMETERS,
{
name: 'cinemaCode',
in: 'query',
Expand Down Expand Up @@ -53,7 +55,7 @@ export const ACTION_QUERY_PARAMETERS = [
name: 'q',
in: 'query',
required: false,
description: '다이소 제품 검색어',
description: '한국·일본 다이소 제품 검색어',
schema: { type: 'string' },
},
{
Expand Down
Loading
Loading
0