Skip to main content
Glama
NFULL07

식자재회수점검

by NFULL07
README.md
# 식자재 회수점검 (foodRecall)

**급식·유통 현장에서 취급 중인 식자재가 식약처 회수·판매중지 대상인지, 로트 단위로 즉시 검수하는 MCP 서버.**

- 라이브 Endpoint: `https://foodrecallcheck.playmcp-endpoint.kakaocloud.io/mcp`
- 전송: Streamable HTTP, Stateless (`POST /mcp`)
- 실데이터: 식품안전나라 회수·판매중지(I0490) 전량 메모리 적재 (기동 시 확인 355건)
- 도구 7개, 생성형 0개 (환각 없는 사실 대조 전용)

---

## 문제

식약처는 매일 식품 회수·판매중지를 공고한다. 그런데 회수는 보통 **제품명 전체가 아니라 특정 제조일자·유통기한 로트에만** 적용된다. 급식소·어린이집·편의점·유통사의 검수 담당자는 입고 때마다 "이 물건이 회수 대상인지"를 확인해야 하지만, 공개 사이트는 목록만 보여줄 뿐 "지금 내 물건이 해당되는가"를 판정해 주지 않는다. LLM은 최신 회수 목록을 모른다.

## 대상 사용자

학교·기관 급식소, 어린이집, 편의점, 식자재 유통사의 입고 검수 담당자.

## 왜 사이트로는 안 되고 이 MCP가 필요한가

식품안전나라 웹사이트로는 못 하고, 이 서버만 하는 세 가지:

1. **바코드 역조회** — 바코드 숫자로 회수 건을 거꾸로 찾는다. 웹 검색·사이트로는 불가능하다.
2. **재고 30건 일괄 검수** — 납품 목록·식단표를 한 번에 대조한다. 사이트라면 30번 검색해야 한다.
3. **제조업체별 회수 이력 집계** — 특정 업체의 누적 회수 건수를 낸다. 원본 API가 제공하지 않는 값으로, 발주 전 공급사 스크리닝에 쓴다.

## 판정 모델 (오탐 방지가 핵심)

모든 대조는 **해당 / 추가 정보 필요 / 미해당** 세 가지로만 답한다. 퍼지 매칭을 하지 않는다.

- 제품명이 회수 목록에 있으면 먼저 **경고**하고, 회수 대상 로트인지 확정하기 위해 제조일자·업체를 요청한다.
- 같은 제품명이라도 제조업체가 다르면 "해당"으로 단정하지 않는다(동명이인 제품 오탐 차단).
- 회수 레코드에 로트 제한이 없으면(규제당국이 제품 전체 회수) 업체·바코드 일치 시 "해당"으로 판정한다.

검수는 잘못 통과시키는 것도, 멀쩡한 물건을 잘못 폐기시키는 것도 사고다. 그래서 근거 필드를 항상 함께 반환해 사람이 검증할 수 있게 했다.

## 도구 7개

| 도구 | 기능 |
|------|------|
| check_inventory_recall_batch | 재고·식단 목록(최대 30건) 일괄 대조 |
| check_product_recall_match | 단일 제품 로트 대조 (제품명·제조일자·유통기한·바코드·업체) |
| check_recall_by_barcode | 바코드 역조회 |
| check_manufacturer_recall_history | 제조업체별 회수 이력 집계 |
| list_recent_food_recalls | 기간·분류별 최근 회수 목록 |
| get_recall_detail | 회수 레코드 상세(사유·등급·로트·회수방법·사진) |
| get_recall_grade_rule | 회수 등급(1~3등급)의 법적 의미와 조치 |

## 아키텍처 / 100ms 대응

PlayMCP 요구: 툴 응답 평균 100ms, p99 3,000ms. 기동 시 회수 데이터를 전량 메모리에 적재하고 주기 갱신한다. **도구 호출 경로에는 외부 API 호출이 전혀 없다.** 모든 조회는 메모리 인덱스(제품명·바코드·업체)에서 처리된다.

## 데이터 출처

- 식품안전나라 회수·판매중지 (서비스 I0490) — 국내·수입 회수를 모두 포함. 현재 이 소스로 운영.
- (확장 예정) 공공데이터포털 15074318 국내 회수, 15095378 수입식품 회수 — 승인된 엔드포인트 URL 확보 시 폴백 소스로 추가.

## 로컬 실행

    cp .env.example .env      # FOODSAFETYKOREA_API_KEY 입력
    npm i
    npm run test:match        # 판정 로직 검증 (네트워크 불필요)
    npm run test:schema       # 실스키마·날짜 파싱 검증
    npm run build && npm start
    curl localhost:8080/health   # {"ready":true,"records":355,...}

## 상태

- 타입 검사 0 에러, 판정 테스트 11/11, 스키마 테스트 14/14 통과
- 카카오 클라우드 배포 완료(Active), 실서버에서 도구 7개·355건 응답 확인