Korea Data Suite

io.github.choiyounggi由 GitHub 账号 choiyounggi 发布v0.1.1更新于 Oct 24, 2026

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

已验证STDIO仅桌面金融数据与分析

概览

AI 生成的概览

本地 MCP 服务器,通过托管 JSON API 让助手查询韩国公休日、工作日计算以及国土交通部不动产实际交易数据

可以做什么
查询某年或某月的韩国公休日,包括替代公休日、临时公休日和选举日,并判断某日期是否为公休日或工作日。在指定日期上增加工作日,或统计区间内的工作日数量,自动跳过周末和公休日。查询公寓、写字楼和土地的正常化国土交通部实际交易价格,涵盖买卖、全租和月租,支持日期筛选和游标分页。列出用于筛选不动产查询的 LAWD 地区代码。
适用场景
当助手需要可靠的韩国日历逻辑来处理排期或截止日期,或需要按地区和房产类型查询韩国不动产实际成交价格时适用。适合原本需要阅读韩文政府文档和 XML 响应的工作流程。
运行要求
以本地进程运行,通常通过 PyPI 包用 uvx 启动。需要在 KDS_API_KEY 环境变量中提供 Korea Data Suite API 密钥,可在 RapidAPI 页面订阅获取。KDS_API_BASE 变量设置 API 源地址,默认指向托管服务,因此需要能访问该主机的网络。
安装前请注意
KDS_API_KEY 中的密钥是付费订阅凭证,托管服务有免费额度,超出后收费。查询内容(包括地区和日期筛选)会发送给第三方托管 API。README 警告切勿在生产环境启用 KDS_DEV_MODE,因为它会关闭所有身份验证。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Korea Data Suite,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

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 syncuv run uvicorn app.main:app --port 8642curl "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 cursorcurl "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
# Logstail -f ~/Library/Logs/kds/api.out.log
# Uninstalllaunchctl bootout "gui/$(id -u)" ~/Library/LaunchAgents/com.choiyounggi.kds-api.plistrm ~/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.clouduv 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.

First run needs history: the daily sync only ingests the current month. To give pages real depth, backfill once — uv run python scripts/backfill.py --from 2025-07 --to 2026-06 --regions <codes> --datasets apt_trade,apt_rent.

Automate (macOS daemon)

deploy/com.choiyounggi.kds-site.plist regenerates the site daily at 04:30 (right after the 04:00 sync) via scripts/publish_site.sh. Because the app serves from disk, the refreshed pages are live immediately — no restart, no external deploy:

bash
cp deploy/com.choiyounggi.kds-site.plist ~/Library/LaunchAgents/launchctl bootstrap "gui/$(id -u)" ~/Library/LaunchAgents/com.choiyounggi.kds-site.plisttail -f ~/Library/Logs/kds/site.out.log

Uptime note: since the site is served by the local app (not a CDN), its SEO availability tracks the machine — keep it awake for serving (pmset, as the API already requires). If always-on hosting is wanted later, the same site/dist can be pushed to Cloudflare Pages instead.

MCP server (AI-agent access)

The API is also packaged as a standalone Model Context Protocol server — packages/korea-data-mcp/ — so AI agents (Claude Desktop/Code, Cursor, …) can discover and call the endpoints directly. It is its own minimal package (deps: mcp, httpx) and is what gets published to PyPI / listed in the MCP Registry.

Quick add (before PyPI, straight from this repo — users bring their own key):

bash
claude mcp add korea-data-suite --env KDS_API_KEY=<key> \  -- uvx --from "git+https://github.com/choiyounggi/korea-data-suite#subdirectory=packages/korea-data-mcp" korea-data-mcp

See packages/korea-data-mcp/README.md for tools, client config, and uvx korea-data-mcp (once on PyPI).

License

MIT © choiyounggi

来源:README.md,提交 1d6e375

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

1
  1. v0.1.1最新Sep 16, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分