Skip to main content
Glama
Maroco0109

who-will-notify-mcp

by Maroco0109

who-will-notify-mcp

이제 누가 공지해주냐... 의 **"누가"**를 맡는 MCP 서버.

전국 장학금 공고(한국장학재단·공공데이터포털)를 모아 컨텍스트화하고, 사용자의 질문에 그 컨텍스트로 답하는 카카오 PlayMCP 직등록형 MCP 서버입니다. 모든 기능은 tool calling으로만 제공되며, 전송은 Streamable HTTP(stateless)입니다. 답변은 실데이터(공공누리 제1유형, 재배포 허용)에만 근거하며 지어내지 않습니다.

질문: "소득 3분위 이하 신청 가능한 장학금 있어?"
답변: "'대학생장학금'(지역연고, 모집중~2026-12-04)이 소득기준 중위 100% 이하 대상입니다.
       (출처: find_scholarships → 대학생장학금)"

데이터 출처

  • 공공데이터포털 data.go.kr한국장학재단_학자금지원정보(대학생) (dataset id 15028252).

  • 라이선스: 공공누리 제1유형("이용허락범위 제한 없음") — 출처표시 시 재배포 허용.

  • 접근: odcloud 오픈API(REST, JSON), serviceKey 인증. 월 단위 갱신, 약 1,850건.

  • 각 행 = 하나의 장학 공고: 상품명(제목)·지원내역/자격(본문)·모집시작일~모집종료일(기간)·구조화 facet(학자금유형·학년·소득·성적·대학구분·기관).

Related MCP server: University Course Catalog MCP Server

아키텍처 ("repo-as-DB")

data.go.kr 15028252 (한국장학재단 학자금지원정보, 공공누리 1유형)
   │  scripts/sync-notices.mjs  (= 매주 월 07:00 KST cron, .github/workflows/crawl.yml)
   │    odcloud API 페이징 fetch → 정규화 → 안전게이트 → 180일 보존 → data/notices.json 커밋
   │      · 안전게이트: 에러봉투/비JSON reject · 완전성(fetched===totalCount)
   │        · shape drop(>5% abort) · 최소건수 floor · 크기(NOTICES_MAX_BYTES) · 키 pre-write assert
   ▼
data/notices.json  (repo-as-DB 영속 저장소, 약 1,013건)
   │
   ▼
raw.githubusercontent.com/.../data/notices.json
   │  (런타임 best-effort fetch, 프로세스 캐시 TTL 15분)
   ▼
KakaoCloud 컨테이너 (Dockerfile, TZ=Asia/Seoul) — express  POST /mcp · GET /health
   이미지에 notices.json 베이크(floor) → fetch 실패해도 stale-serve
  • cron: GitHub Actions 0 22 * * 0 UTC(= 월 07:00 KST). 원천이 월 갱신이라 주 1회로 충분. Actions secret DATA_GO_KR_KEY 필요.

  • 영속: data/notices.json을 repo에 커밋(repo-as-DB). 서버는 런타임에 raw GitHub를 새로고침하고, 실패 시 이미지에 베이크된 floor를 서빙.

  • 키 격리: serviceKey크롤 쪽(GitHub Actions + 로컬 .env)에만 존재. 배포되는 MCP 서버는 키가 필요 없습니다(미리 만들어진 notices.json만 읽음).

  • 모집상태: 런타임이 KST 오늘 기준으로 각 공고 상태(모집중/마감임박/마감/상시)를 계산해 라벨링하고, 검색/목록을 모집중 우선으로 정렬합니다.

MCP 툴 (5개)

입력

반환

search_notices

query, status?, limit?

키워드 관련 공고 요약(id·제목·발췌·기관·모집기간·상태), 모집중 우선

list_notices

category?, status?, limit?

공고 요약 목록(모집중 우선, 상태 라벨)

get_notice

id

공고 전문(지원내역·자격·제출서류·모집기간·기관·홈페이지)

get_scholarship_dates

kind?(모집중/마감임박/상시/all), withinDays?

모집기간 기준 조회 — "지금 신청 가능한 / 마감 임박"

find_scholarships

category?(학자금유형), gradeCriteria?, incomeCriteria?, gpaCriteria?, universityType?, organization?, status?

조건(자격) facet 필터

  • 목록/검색은 요약만 반환하고 본문 전문은 get_notice로만 제공합니다(응답 크기 규율).

  • category학자금유형구분(지역연고·성적우수·특기자·소득구분·장애인·기타 등)입니다.

  • 마감된 공고도 검색에는 포함되며(대부분 연간 반복 장학금이라 정보 가치 있음) 상태 라벨로 구분됩니다. "지금 신청 가능한 것만"은 get_scholarship_dates({kind:"모집중"})를 사용하세요.

로컬 개발 · 검증

npm install
cp .env.example .env            # DATA_GO_KR_KEY= 에 data.go.kr 일반 인증키 입력
npm run sync                    # data.go.kr fetch → 안전게이트 → data/notices.json 생성(.env 로드)
npm run typecheck
npm test                        # node:test (정규화/id안정/안전게이트/상태라벨/캐시/stale-serve)

# 서버 실행 + 호스트 하니스
npm run dev                     # 터미널 A — :3000
node scripts/host-test.mjs                    # 터미널 B — 배선 점검(키 불필요)
OPENAI_API_KEY=sk-... node scripts/host-test.mjs "소득 3분위 이하 신청 가능한 장학금 있어?"

# 헬스/전송 확인
curl localhost:3000/health        # {"status":"ok",...,"source":"baked","count":1013}
curl -o /dev/null -w "%{http_code}" localhost:3000/mcp   # 405 (stateless)

serviceKey는 URL 쿼리 파라미터라 로그에 남으면 유출됩니다 — sync 스크립트는 URL/키를 어떤 로그·에러에도 출력하지 않고, data/notices.json 작성 직전 키 포함 여부를 assert합니다.

환경변수

변수

기본값

설명

PORT

3000

HTTP 포트

NOTICES_RAW_URL

raw GitHub data/notices.json

런타임 공고 소스

NOTICES_TTL_MS

900000 (15분)

캐시 새로고침 주기

NOTICES_FETCH_TIMEOUT_MS

8000

raw fetch 타임아웃

NOTICES_MAX_BYTES

16777216 (16MB)

ingest 상한(약 1,013건 여유 수용)

NOTICES_BAKED_PATH

./data/notices.json

베이크 floor 경로

RATE_LIMIT_MAX

120

IP당 분당 요청 한도

TZ

Asia/Seoul (Dockerfile)

모집상태 KST 계산용

DATA_GO_KR_KEY

크롤 전용(로컬 .env / Actions secret). 런타임 서버엔 불필요

DATA_GO_KR_UDDI

최신본 기본값

(선택) 월 갱신 시 최신 데이터셋 uddi 로 덮어쓰기

PlayMCP / 카카오 MCP Hub 등록 정보 (복붙용)

심사 규칙상 모든 툴 description에 서비스명 who-will-notify-mcp 포함 + 모든 툴 annotations(title/readOnlyHint/destructiveHint/idempotentHint/openWorldHint) 정의 — 현재 코드가 충족합니다.

항목

서버 이름 / 식별자

who-will-notify-mcp

한 줄 소개

한국장학재단(공공데이터포털) 장학금 공고를 컨텍스트화해 "지금 신청 가능한 장학금?", "소득 3분위 대상 있어?" 같은 질문에 출처와 함께 답하는 MCP 서버

카테고리

교육 / 장학 / 정보 검색

태그

장학금, 학자금, 공공데이터, 한국장학재단, 검색, read-only

전송 방식

Streamable HTTP (stateless) — POST /mcp

인증

불필요(공개 read-only)

개인정보 수집

없음(공공누리 제1유형 공개 장학 데이터만 read-only 조회)

상세 설명 (Description)

한국장학재단이 공공데이터포털에 개방한 전국 장학금 공고 약 1,000건(공공누리 제1유형)을 구조화해 담아두고, 사용자의 자연어 질문을 tool calling으로 받아 관련 장학 공고·모집기간·자격조건을 출처와 함께 반환하는 who-will-notify-mcp MCP 서버입니다. 검색/목록은 요약만, 본문 전문은 get_notice로만 제공하며, 각 공고의 **모집상태(모집중/마감임박/마감)**를 실시간으로 라벨링합니다. 모든 툴은 읽기 전용(read-only) 이라 데이터를 변경하지 않습니다.

대표 질문 (예시 프롬프트)

  • 지금 신청 가능한 장학금 있어?get_scholarship_dates({ kind: "모집중" })

  • 마감 임박한 장학금 알려줘get_scholarship_dates({ kind: "마감임박" })

  • 소득 3분위 이하 신청 가능한 장학금 있어?find_scholarships({ incomeCriteria: "..." })

  • 성적우수 장학금 찾아줘find_scholarships({ category: "성적우수" })

  • 장애인 대상 장학금 있어?search_notices({ query: "장애인" })

  • 그 장학금 제출서류가 뭐야?get_notice({ id: "sch-..." })

툴 요약 (annotations 포함)

5개 툴 모두 readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false.

description(서비스명 포함) 요약

입력

search_notices

who-will-notify-mcp에서 질문 키워드로 장학 공고 요약을 검색(모집중 우선·상태 라벨)

query, status?, limit?

list_notices

who-will-notify-mcp에서 장학 공고를 나열(유형/상태 필터)

category?, status?, limit?

get_notice

who-will-notify-mcp에서 id로 장학 공고 전문 반환

id

get_scholarship_dates

who-will-notify-mcp에서 모집기간 기준(모집중/마감임박/상시) 조회

kind?, withinDays?

find_scholarships

who-will-notify-mcp에서 자격조건(유형·학년·소득·성적·대학·기관) 필터

category?, gradeCriteria?, incomeCriteria?, gpaCriteria?, universityType?, organization?, status?

배포 · PlayMCP 등록 체크리스트 (사용자 수행)

코드/데이터는 준비 완료. 아래 콘솔 조작은 사용자가 직접 수행합니다(브라우저 로그인·OTP는 대행 불가).

  1. GitHub secret 등록: repo Settings → Secrets and variables → Actions → New repository secretDATA_GO_KR_KEY = data.go.kr 일반 인증키. (주 1회 자동 sync에 필요)

  2. push & Actions 활성화: main에 머지/푸시 → raw.githubusercontent가 새 data/notices.json을 서빙 → 런타임 파이프라인 활성. Actions 활성화 확인.

  3. 첫 동기화(선택): GitHub Actions → weekly-scholarship-sync → Run workflow(수동) 1회 실행 → data/notices.json 갱신 커밋 확인.

  4. MCP 서버 배포: KakaoCloud Git 소스 빌드 → 이 repo 연결 → Dockerfile 자동 감지(TZ=Asia/Seoul 포함) 빌드/배포 → MCP Endpoint URL 복사.

  5. 임시 등록: PlayMCP 콘솔 → 새 MCP 서버 등록 → Endpoint URL 붙여넣기 → 저장(카카오 로그인 + OTP).

  6. 테스트: PlayMCP AI 채팅에서 위 "대표 질문"으로 확인.

  7. 심사 요청: 콘솔에서 "심사 요청" 클릭.

  8. 월 갱신 메모: 원천 데이터셋 uddi는 월 갱신 시 새로 발급됩니다. 최신 uddi를 repo variable DATA_GO_KR_UDDI에 넣으면 코드 변경 없이 반영됩니다. (Actions 스케줄은 repo 60일 무활동 시 자동 비활성화 — 가끔 커밋 권장.)

라이선스

  • 데이터: 한국장학재단 / 공공데이터포털, 공공누리 제1유형(출처표시). 본 서버는 해당 공개 데이터를 read-only로 재배포합니다.

  • 코드: 개인 프로젝트.

Related MCP Connectors

Related MCP Servers