Skip to main content
Glama
Sejin-Koo

public-data-portal-mcp

by Sejin-Koo

public-data-portal-mcp

나라장터·방위사업청·수자원공사·한국마사회·한국지역정보개발원·한국남부발전·한국지역난방공사· NIA 등 공공데이터포털/D2B 계열 입찰·조달 정보를 감싸는 MCP 서버입니다.

it-bid-daily-scan 예정작업이 매일 curl로 직접 처리하던 14개 소스의 인증 헤더 quirk, JSON/XML 혼재, resultCode 불일치, 나라장터 4종 교차 중복제거 로직을 서버 쪽으로 옮겨서 제공합니다. 오탐 필터링과 "검토가치 있음" 판단처럼 주관적 판단이 필요한 부분은 서버가 하지 않고 원문 매칭 결과만 반환합니다 — 그 판단과 체크포인트/seen 파일 관리(상태 저장)는 호출하는 쪽(에이전트)의 몫입니다. 이 서버 자체는 상태를 갖지 않는 순수 조회 서버입니다.

배포

Endpoint: https://public-data-portal-mcp.vercel.app/api/mcp
연결 방식: Settings > Connectors > "+" > Add custom connector, URL 위와 동일, 인증 불필요
          (클라이언트는 별도 키를 넘길 필요 없음 — 서버가 환경변수로 자체 보유)

Vercel에 이 저장소를 Import한 뒤, 프로젝트 환경변수에 아래를 반드시 설정해야 합니다:

DATA_PORTAL_KEY = <공공데이터포털 일반 인증키>
DART_API_KEY    = <OpenDART 인증키>
NIMBLE_API_KEY  = <Nimble Web API 키>   # resolve_bizno 3단계(SWIT) 전용 — 없으면 그 단계만 실패

DATA_PORTAL_KEY는 공공데이터포털 일반 인증키입니다. 2026-08-26 재발급본부터는 64자리 16진수라 Encoding 값과 Decoding 값이 같아 구분할 필요가 없습니다. 그 이전 base64 형식 키를 쓰는 경우에는 디코딩 값을 넣으세요 — URL 인코딩은 서버 코드(qs())가 자동 처리합니다.

환경변수명이 PUBLIC_DATA_PORTAL_KEY에서 DATA_PORTAL_KEY로 바뀌었습니다(2026-08-26). 종전 이름의 "PUBLIC"은 "공공데이터포털(Public Data Portal)"의 약자였지만, Vercel은 PUBLIC_ 접두어를 "브라우저에 노출할 공개 변수"로 해석해 Secret 타입 저장을 거부합니다. 전환이 끝났으므로 옛 이름은 더 이상 인식하지 않습니다. 옛 이름으로 되돌리지 마세요.

키가 설정됐는지는 list_agencies 도구의 keyConfigured·keySource로 확인할 수 있습니다 (키 값 자체는 반환하지 않습니다). 조회가 전부 실패하는데 원인을 모르겠으면 여기부터 보세요.

DART_API_KEY는 회사명을 사업자등록번호 10자리로 해석하는 공통 해석기 (lib/bizno_resolver.js)가 씁니다 — resolve_bizno 도구와, 회사명을 받는 여러 도구가 내부에서 같은 해석기를 부릅니다. 없어도 서버는 동작하지만 DART 경로(상장·외감법인)가 막혀 키스콘 색인 경로만 남으므로, 그 경우 회사명 대신 bizNo를 직접 넘기는 편이 정확합니다.

★ 실제 키 값은 이 저장소에 적지 마세요. 저장소가 공개이므로 커밋된 값은 즉시 노출되고, 파일을 고쳐도 git 히스토리에는 그대로 남습니다. 값은 Vercel 프로젝트 환경변수에만 둡니다.

Related MCP server: narajangteo-pro

사업자등록번호 해석 (resolve_bizno)

회사명 ↔ 사업자등록번호를 양방향으로 풀어 식별자(사업자등록번호·법인등록번호·DART 고유번호· 종목코드·상호 이력·대표자·소재지·업종)를 한 묶음으로 돌려주고, 국세청 등록 상태까지 덧붙입니다. 해석 경로는 3단계입니다.

단계

근거

덮는 범위

갱신

1

data/corp_name_index.json.gz → OpenDART 기업개황

상장·외감법인

주 1회 통째로 교체

2

data/kiscon_bizno_index.json.gz

건설업 등록업체(DART 미등록 비상장사 포함)

월 1회 누적 병합

3

SWIT 소프트웨어사업자 신고 검색

SW사업자 신고업체(DART 미등록 IT·SI 비상장사 포함)

실시간 조회(색인 없음)

1·2번 두 파일을 하나로 합치지 마세요. 1번은 매주 갈아끼우는 스냅샷이라, 누적이 필요한 키스콘 색인을 거기에 넣으면 다음 주에 사라집니다.

키스콘 색인은 scripts/refresh-kiscon-index.mjs가 만듭니다. 사업자등록번호를 키로 두고 상호를 배열로 쌓아, 사명이 바뀌어도 옛 이름으로 찾힙니다. 워크플로 .github/workflows/refresh-kiscon-index.yml가 월 1회 증분 병합하며, 전량 재수집은 workflow_dispatch에서 mode=backfill로 수동 실행합니다(수십 분 소요). 이 워크플로에는 저장소 시크릿 DATA_PORTAL_KEY가 필요합니다.

3단계 SWIT는 Nimble 경유입니다 — NIMBLE_API_KEY 필요

SWIT(www.swit.or.kr)는 클라우드/데이터센터 IP를 차단합니다. Vercel에서 직접 호출하면 TCP 연결 후 곧바로 리셋됩니다(ECONNRESET — DNS 실패도 타임아웃도 아닙니다). 그래서 이 단계는 Nimble Web API를 국내 IP 경유 프록시로 거쳐 호출합니다(country: "KR").

  • 인증은 Authorization: Bearer <키>입니다. 공식 문서의 Basic(이메일:비밀번호 base64) 방식은 현행 API키에 401 No supported authentication method found를 냅니다.

  • NIMBLE_API_KEY가 없으면 직접 호출로 폴백하지만, 위 이유로 사실상 항상 실패합니다.

  • 호출 1건당 Nimble 사용량이 소모됩니다. 앞의 두 단계가 모두 실패했을 때만 타므로 빈도는 낮지만, 무료 구간(월 5,000 요청)을 넘기면 과금됩니다.

국세청 등록 상태 (국세청상태)

해석된 번호와 후보 번호의 계속사업자·휴업자·폐업자 여부를 폐업일·과세유형과 함께 돌려줍니다. api.odcloud.kr/api/nts-businessman/v1/status를 쓰고 인증은 기존 DATA_PORTAL_KEY로 충분합니다(별도 키 불필요). 여러 건을 한 번에 물으므로 후보가 여럿이어도 왕복은 1회입니다.

이 값은 색인에 저장하지 않습니다. 휴폐업은 수시로 바뀌는데 색인은 스냅샷이라, 굳혀 두면 갱신 주기 내내 낡은 값을 답하게 됩니다. 조회 시점에 실시간으로만 묻습니다.

조회 실패를 폐업으로 읽지 마세요. 실패는 국세청상태조회오류로 따로 오고, 국세청에 등록 이력이 없는 번호는 "국세청에 등록되지 않은 번호"로 표기됩니다 — 둘 다 폐업과 다릅니다.

★ 번호를 알아야 상태를 답하는 구조라 회사명으로 번호를 찾는 용도로는 쓸 수 없습니다. 이 해석기의 대체재가 아니라 그 뒤에 붙는 검증 단계입니다.

제공 도구

아래 목록은 서버 초기의 것으로, 이후 추가된 도구는 담고 있지 않습니다. 현행 목록은 lib/server.jsserver.tool( 등록부를 보세요.

  1. scan_narajangteo_procurement(since, until?, keywords?) — 나라장터 4종(조달요청→ 발주계획→사전규격→입찰공고) 조회 + 4종 교차 중복제거(가장 진전된 단계만 유지).

  2. scan_agency_bids(agency, since, until?, keywords?) — 나라장터 외 8개 기관 (kwater_bid, kwater_prespec, kra, dapa_overseas, dapa_bid, klid, kospo, kdhc) 중 하나를 조회.

  3. scan_dapa_plan(keywords?) — 방위사업청 D2B 조달계획(ID 기반, 날짜 필터 없음).

  4. scan_nia_board(pages?, keywords?) — NIA 알림마당 게시판 HTML 파싱(ID 기반).

  5. get_holiday_info(year, month) — 한국천문연구원 특일정보.

  6. list_agencies() — 사용 가능한 agency 코드/기본 키워드/현재 KST 시각 확인.

이 서버가 하지 않는 것 (호출하는 쪽의 책임)

  • 나라장터(1~4번) vs 다른 8개 기관 간 교차 중복제거: scan_narajangteo_procurementscan_agency_bids 결과의 title을 비교해서 같은 사업이면 나라장터 쪽만 남기는 판단은 호출하는 쪽에서 수행해야 합니다.

  • 오탐(false positive) 필터링: "AIRPORT"의 "AI"처럼 키워드가 단어 일부로 우연히 매칭된 경우를 걸러내는 판단.

  • 검토가치 판단: 예산 규모·사업 성격 기준으로 강조 여부를 정하는 판단.

  • 체크포인트/seen 파일 관리: scan_dapa_plan/scan_nia_board는 매번 전체 매칭분을 반환하므로, "신규" 여부 판정과 seen 목록 갱신은 호출하는 쪽이 파일(또는 다른 저장소)에 직접 저장해서 비교해야 합니다.

  • HTML 보고서 생성: 표 형식·정렬·강조 스타일 등 출력 형식은 호출하는 쪽에서 구성합니다.

참고

  • 원본 quirk 문서: it-bid-daily-scan 예정작업(SKILL.md)에 소스별 상세 이력이 남아있습니다.

  • 코드 패턴은 krx-regulation-mcp와 동일(Node.js ESM + @modelcontextprotocol/sdk + Vercel StreamableHTTPServerTransport).

  • NIA 게시판 HTML 파싱은 정규식 기반이라 사이트 마크업이 바뀌면 깨질 수 있습니다 — 매칭 건수가 갑자기 0으로 떨어지면 가장 먼저 의심할 부분입니다.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides access to South Korean government procurement (G2B) and Nara Market shopping mall data, enabling users to search bid announcements, procurement statistics, product catalogs, and contract information through 15 specialized tools.
    4
    Apache 2.0
  • A
    license
    A
    quality
    D
    maintenance
    Integrates 6 Korean public procurement APIs to search, analyze, and manage procurement data using natural language.
    8
    3
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables searching Korean procurement notices from the public data portal, with support for integrated search across categories, flexible date ranges, and attachment extraction.
    MIT