Korea Data Suite logo

Korea Data Suite

Korean public holidays, business-day math, and MOLIT real-estate transactions as MCP tools.

Install Korea Data Suite

Pick your client, then add it in one click or paste the config.

No confirmed install command yet

We only publish a config when the install details come from the project itself β€” its README, its docs, or a verified owner. We haven’t found those for Korea Data Suite, and we’d rather show nothing than a guess you’d paste into your client.

Open setup steps on GitHub

Overview

Security & health

What it can reach and how reliably it runs β€” from our own checks, not the maintainer’s claims.

ActiveLast checked 2d ago

Recent health check succeeded.

4/4 checks healthy over the last 42d

Supply-chain signal

No high-severity advisories surfaced by our automated scan.

Critical 0High 0Medium 0Low 0

Scanned 17d ago via OSV.dev

Adoption & maintenance

Factual signals from GitHub, npm, and our automated checks β€” not a rating.

GitHub stars2Stargazers on the source repository.
Last commit2mo agoMost recent push to the default branch.

From the project README

Korea Data Suite

English | ν•œκ΅­μ–΄

Clean, developer-friendly REST APIs for Korean public data. Korean government open data is powerful but hard to consume β€” Korean-only docs, XML responses, legacy auth. This suite normalizes it into simple JSON APIs.

β–Ά Try it on RapidAPI β€” free tier, no setup. Hosted and auto-updated; same code as this repo. For AI agents, it's on the MCP Registry β€” uvx korea-data-mcp.

APIs

APIStatusDescription
Holidays & Business Daysβœ… v1Korean public holidays (incl. substitute & temporary holidays) and business-day calculations
Real Estate Transactionsβœ… v1Normalized MOLIT real transaction prices (apartment/officetel/land, sale & rent) β€” nationwide (261 sigungu)
Address Toolkit🚧 plannedRoad/lot address conversion, romanization
Business Registration🚧 plannedBRN validation & enrichment

Get started

Hosted (recommended) β€” a maintained instance with a free tier and no setup:

β†’ Subscribe on RapidAPI, grab your key, and call any endpoint. RapidAPI injects the key for you β€” copy a ready-made snippet from its Code Snippets panel.

RapidAPI (hosted)Self-host
SetupAPI key in secondsdata.go.kr key + server + cron
Data refreshautomatic (we run the sync)you manage the scheduler
Costfree tier, then paidfree (your own infra)

Both run the exact same code (this repo). Pick RapidAPI if you'd rather not operate data pipelines; self-host if you want full control.

Self-host

bash
uv sync
uv run uvicorn app.main:app --port 8642
curl "http://127.0.0.1:8642/v1/health"

Holidays & Business Days API

bash
# All holidays in a year (or a month)
curl "http://127.0.0.1:8642/v1/holidays?year=2026" -H "X-API-Key: <key>"

# Is a given date a holiday / business day?
curl "http://127.0.0.1:8642/v1/holidays/check?date=2026-03-02" -H "X-API-Key: <key>"

# Add N business days (skips weekends & holidays)
curl "http://127.0.0.1:8642/v1/business-days/add?date=2026-12-31&days=1" -H "X-API-Key: <key>"

# Count business days in a range (inclusive)
curl "http://127.0.0.1:8642/v1/business-days/count?start=2026-09-21&end=2026-09-27" -H "X-API-Key: <key>"

Covers official public holidays, substitute holidays (λŒ€μ²΄κ³΅νœ΄μΌ), temporary holidays (μž„μ‹œκ³΅νœ΄μΌ), and election days β€” the cases most global holiday APIs get wrong for Korea.

Real Estate Transactions API

Normalized MOLIT (Ministry of Land) real transaction prices β€” apartment, officetel, and land; sale, jeonse, and monthly-rent β€” as clean English JSON with cursor pagination.

bash
# Real transaction prices (apartment sales in Gangnam-gu)
curl "http://127.0.0.1:8642/v1/realestate/transactions?region=11680&property_type=apartment&trade_type=sale" -H "X-API-Key: <key>"

# Filter by date range + paginate with the returned cursor
curl "http://127.0.0.1:8642/v1/realestate/transactions?region=11680&date_from=2026-01-01&limit=50&cursor=<next_cursor>" -H "X-API-Key: <key>"

# Region codes (LAWD 5-digit)
curl "http://127.0.0.1:8642/v1/realestate/regions" -H "X-API-Key: <key>"

Daily sync ingests the current + previous month; use the backfill CLI for history:

bash
uv run python scripts/backfill.py --from 2025-01 --to 2025-12 --regions 11680,11650

Configuration

Environment variables (prefix KDS_, .env supported):

VariableDefaultDescription
KDS_DEV_MODEfalseSkip API-key auth (local dev)
KDS_API_KEYSβ€”Comma-separated accepted API keys
KDS_PROXY_SECRETSβ€”Comma-separated marketplace proxy secrets
KDS_DB_PATHdata/kds.dbSQLite path
KDS_DATA_GO_KR_KEYβ€”data.go.kr service key (optional; enables holiday + real-estate sync)
KDS_ENABLE_SCHEDULERtrueHoliday (weekly) + real-estate (daily) sync scheduler
KDS_RE_REGIONSall 261 nationwide sigunguComma LAWD codes to sync (subset override)
KDS_RE_DATASETSallComma dataset keys (apt_trade, apt_rent, offi_trade, offi_rent, land_trade)

Data sources & attribution

  • Holiday data: KASI Special Day Information (ν•œκ΅­μ²œλ¬Έμ—°κ΅¬μ› νŠΉμΌμ •λ³΄), via Korea Public Data Portal (data.go.kr) β€” KOGL Type 1. Ships with bundled seed data (2025–2027); refreshed weekly when a service key is configured.
  • Real transaction data: MOLIT μ‹€κ±°λž˜κ°€ κ³΅κ°œμ‹œμŠ€ν…œ (ꡭ토ꡐ톡뢀), via Korea Public Data Portal (data.go.kr) β€” KOGL Type 1.

Run as a daemon (macOS)

bash
# Install & start (auto-restart on crash, start at login)
./scripts/install-daemon.sh

# With Cloudflare Tunnel (after one-time `cloudflared tunnel login/create`)
./scripts/install-daemon.sh --with-tunnel

# Logs
tail -f ~/Library/Logs/kds/api.out.log

# Uninstall
launchctl bootout "gui/$(id -u)" ~/Library/LaunchAgents/com.choiyounggi.kds-api.plist
rm ~/Library/LaunchAgents/com.choiyounggi.kds-api.plist

To keep the machine awake for serving, disable system sleep (sudo pmset -a sleep 0) or use a dedicated always-on machine. See deploy/cloudflared.example.yml for exposing the API via Cloudflare Tunnel without opening ports.

Handling concurrent traffic

The read path and the write path are separated so traffic scales independently:

  • SQLite in WAL mode (set once at init) + busy_timeout β€” readers never block the daily writer and vice-versa, and multiple read workers can run concurrently.
  • API process is read-only, multi-worker. scripts/run.sh runs uvicorn with --workers ${KDS_WORKERS:-2} and KDS_ENABLE_SCHEDULER=false. Each worker is a separate process (separate GIL); WAL lets them all read at once. Raise KDS_WORKERS to scale reads with cores.
  • The daily ingest runs as its own process (com.choiyounggi.kds-sync, 04:00) via scripts/sync.py β€” never inside the API server, so a multi-thousand-row batch never competes with request handling for the GIL.
  • Edge caching (optional): responses carry Cache-Control: no-store for security. The real-estate data is public and changes at most daily β€” if origin load grows, serve it with a short Cache-Control: public, max-age=... and let the CDN absorb reads.

Security checklist before exposing externally

The app is hardened at the code layer (API-key auth fail-closed, parameterized SQL, strict input validation, security headers on every response including 5xx, docs/schema off by default, sanitized errors). The following are edge/deploy responsibilities that must be in place before opening the tunnel:

  • Never set KDS_DEV_MODE=true in production β€” it disables all auth. The app logs a warning at startup if it is on.
  • Cloudflare rate limiting + WAF on the tunnel hostname β€” the app has no app-layer rate limit by design (edge responsibility).
  • HSTS + TLS are terminated at the Cloudflare edge; confirm HSTS is enabled there (the origin serves plain HTTP on 127.0.0.1 only).
  • Keep KDS_ENABLE_DOCS unset (or false) in production; set true only to serve /docs /openapi.json at the origin.

SEO marketing site (programmatic)

A static, SEO-optimized marketing site is generated from the live DB by scripts/gen_site.py. For every region that has real transaction data it emits a Korean landing page (the query users actually type β€” "강남ꡬ μ•„νŒŒνŠΈ μ‹€κ±°λž˜κ°€ API" β€” backed by real MOLIT stats, a working curl example, and a signup CTA), plus a holidays pillar page, a home page, sitemap.xml, and robots.txt.

Quality gate (important): a region is only published if it has at least MIN_SALE_ROWS (30) apartment-sale rows. Regions without enough data are skipped β€” this deliberately avoids thin/doorway pages, which search engines penalize.

bash
# generate into site/dist (reads data/kds.db)
uv run python scripts/gen_site.py --out site/dist

Config is env-driven so the same generator works for any domain (put these in deploy/site.env, gitignored β€” copy deploy/site.env.example):

EnvMeaning
KDS_SITE_URLcanonical/sitemap base, e.g. https://korea-data.cloud
KDS_API_ORIGINorigin shown in the on-page curl examples, e.g. https://api.korea-data.cloud
KDS_CTA_URLsignup call-to-action (RapidAPI / Zyla / Postman listing)
KDS_SITE_DIRoutput dir the app serves (default site/dist)

Serving β€” the API app serves it

The FastAPI app serves site/dist at all non-API paths (app.mount("/")), while /v1/* stays the JSON API. The two get different response headers: the API keeps its locked-down default-src 'none' CSP + no-store; the site gets an HTML-renderable CSP (script-src 'none', inline styles allowed) + public cache. Files are read from disk per request, so regenerating the site goes live with no app restart β€” only a code change needs a restart.

The site is served on the same host as the API (api.korea-data.cloud) β€” the API lives under /v1, the site everywhere else β€” so no new tunnel hostname or DNS is needed. One-time on the serving host:

bash
cp deploy/site.env.example deploy/site.env    # KDS_SITE_URL == KDS_API_ORIGIN == https://api.korea-data.cloud
uv run python scripts/gen_site.py --out site/dist   # generate once
# restart the API app so this integration (new code) takes effect β€” the site is
# then live at https://api.korea-data.cloud/ , /holidays/ , /realestate/... .

Submit https://api.korea-data.cloud/sitemap.xml once in Google Search Console.

Want the site on a bare korea-data.cloud / www later? Add an ingress rule pointing that hostname at the same http://127.0.0.1:8642, route its DNS, and switch KDS_SITE_URL to it. Not required β€” the api host works for SEO today.

Reviews

No reviews yet β€” be the first to share how it worked for you.

Frequently Asked Questions about Korea Data Suite

Korea Data Suite is an MCP server that provides tools for Korean public holidays, business-day calculations, and MOLIT real-estate transaction data. It normalizes Korean government data into JSON, covering substitute, temporary, and election-day holidays plus apartment, officetel, and land transactions for sale, jeonse, and monthly rent across 261 sigungu.

Run `uvx korea-data-mcp` to use Korea Data Suite as an MCP server. The project is also listed in the MCP Registry, and its hosted implementation is available through RapidAPI with a free tier.

Yes, Korea Data Suite can check whether a date is a holiday or business day, add business days to a date, and count business days in an inclusive date range. Calculations skip weekends and Korean public holidays, including substitute and temporary holidays and election days.

Use the real-estate transaction tools with a five-digit LAWD region code and optional filters such as property type, trade type, and date range. Supported data covers apartments, officetels, and land, including sale, jeonse, and monthly-rent transactions, with cursor pagination.

Use the regions endpoint to retrieve five-digit LAWD region codes for real-estate queries. These codes can then be supplied to the transactions endpoint, which supports nationwide coverage across 261 sigungu.

Related MCP servers

Add a badge to your READMEShow it’s listed β€” live SVG, Markdown or HTML.

AllMCPs Directory Badge

Full Badge Customizer

Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.

Badge Style:
Live Dynamic SVG PreviewKorea Data Suite AllMCPs Directory Badge
Markdown (GitHub README)
[![AllMCPs](https://allmcps.com/api/badge/korea-data-suite?style=directory)](https://allmcps.com/mcp/korea-data-suite)
HTML Embed
<a href="https://allmcps.com/mcp/korea-data-suite"><img src="https://allmcps.com/api/badge/korea-data-suite?style=directory" alt="Korea Data Suite on AllMCPs" /></a>