visitkorea-medicaltourism
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@visitkorea-medicaltourismfind KTO-certified hospitals in Seoul with English service"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
VisitKorea Medical Tourism MCP Server
An MCP (Model Context Protocol) server that wraps the Korea Tourism Organization (KTO) Medical Tourism Open API (MdclTursmService), exposing 8 structured tools that AI agents — including Claude and Manus AI — can call directly via Streamable HTTP.
The underlying data is curated by the Korea Tourism Organization (KTO) and published as an Open API on data.go.kr (Korea's Public Data Portal) under service ID 15143913. It covers KTO-certified medical tourism facilities across South Korea — hospitals, specialist clinics, and wellness centres — with multilingual support for 5 international languages.
Features
Area-based search — list facilities by province or city/county
Location-based search — find facilities within a GPS radius (up to 20 km), using WGS84 coordinates
Keyword search — full-text search across all regions
Sync list — full dataset synchronisation list for building and maintaining local databases
Detail records — common info, introductory info (hours, parking, capacity), and medical-specific info (specialties, languages, reservation status)
8 MCP tools — one per API operation, with full parameter documentation in docstrings
5 languages — English, Japanese, Simplified Chinese, Korean, Russian
TTL response cache — district codes cached 24 h; all other responses cached 5 min (≈6× speedup on cache hits)
Rate limiter — 10 upstream calls/min, burst of 5; fast-fail design returns an immediate error when the limit is hit rather than blocking
Input validation — all parameters validated before the upstream request; GPS bounds, date format, sort codes, and language codes checked with clear error messages
Health endpoint —
GET /healthzfor production liveness probes
Related MCP server: Nonpayment Health MCP Server
Prerequisites
Python 3.11+
A valid API key from data.go.kr (service ID
15143913)Replit account (for deployment)
Installation & Setup
1. Get an API key
Sign in or create a 공공데이터포털 account
Click 활용신청 (Request API access) for service
MdclTursmServiceAfter approval (~10 minutes), retrieve your key from My Page
Either key variant works — the server normalises both automatically at startup:
Key variant | Where to find it | Notes |
일반 인증키 (Encoding) | My Page → 발급받은 키 | URL-percent-encoded; the server decodes it once before use |
일반 인증키 (Decoding) | My Page → 발급받은 키 | Raw base64; used as-is |
2. Set the Replit Secret
Open the Secrets tab in Replit and add:
Secret name | Value |
| Your API key (Encoding or Decoding variant — either works) |
3. Install dependencies
Replit handles this automatically on first run. To install manually:
pip install -r mcp-server/requirements.txtrequirements.txt:
mcp[cli]
httpx
python-dotenv4. Run the server
python mcp-server/main.pyThe server starts on the PORT environment variable (default 8000).
Endpoint | Description |
| Streamable HTTP MCP endpoint (all tool calls) |
| Liveness probe — returns |
Connecting an AI Agent
Connector JSON
Paste this into your AI agent's custom connector settings:
{
"mcpServers": {
"visitkorea-medicaltourism": {
"url": "https://<your-replit-url>/mcp"
}
}
}Replace <your-replit-url> with your deployed Replit project domain.
Manus AI
Go to Settings → Connectors → Add Connectors → Custom MCP, click Import by JSON, and paste the JSON above. Do not add a "type" field — Manus AI infers Streamable HTTP from the URL automatically.
Claude Desktop
Add the JSON to your claude_desktop_config.json under the "mcpServers" key.
Tool Reference
All tools follow the same call pattern — they accept a lang_div_cd and return a list of dicts. Pagination defaults to 10 results per page starting at page 1.
Recommended workflows
Goal | Sequence |
Search by region |
|
Search near a location |
|
Search by keyword |
|
Build a local database |
|
Tool 1 — get_ldong_code
Retrieve legal administrative district (법정동) codes for province/city and district filtering.
Upstream endpoint: GET /ldongCode
Cache TTL: 24 hours (codes are static reference data)
Parameter | Type | Required | Description |
| string | Optional | Language code (default |
| string | Optional | Province code — e.g. |
| string | Optional |
|
| int | Optional | Results per page — clamped to 1–100 (default 10) |
| int | Optional | Page number (default 1) |
Example response item:
{ "rnum": 1, "code": "11", "name": "Seoul" }Tool 2 — get_area_based_list
List medical tourism facilities filtered by administrative region.
Upstream endpoint: GET /areaBasedList
Cache TTL: 5 minutes
Parameter | Type | Required | Description |
| string | Optional | Language code |
| string | Optional | Sort order: |
| string | Optional | Province code from |
| string | Optional | District code (requires |
| string | Optional | Modified-since date filter in YYYYMMDD format |
| int | Optional | Results per page (default 10) |
| int | Optional | Page number (default 1) |
Tool 3 — get_location_based_list
Find medical tourism facilities within a GPS radius. Coordinates must be within South Korea's WGS84 bounding box (longitude 124–132, latitude 33–39).
Upstream endpoint: GET /locationBasedList
Cache TTL: 5 minutes
Parameter | Type | Required | Description |
| string | Optional | Language code |
| float | Required | Longitude in WGS84 — e.g. |
| float | Required | Latitude in WGS84 — e.g. |
| int | Required | Search radius in metres — 1 to 20,000 |
| string | Optional | Sort: |
| string | Optional | Optional province filter |
| string | Optional | Optional district filter (requires |
| string | Optional | Modified-since date filter in YYYYMMDD format |
| int | Optional | Results per page (default 10) |
| int | Optional | Page number (default 1) |
Response items include a dist field (distance in metres from the provided coordinates).
Tool 4 — search_medical_by_keyword
Full-text keyword search across all medical tourism facilities.
Upstream endpoint: GET /searchKeyword
Cache TTL: 5 minutes
Parameter | Type | Required | Description |
| string | Optional | Language code |
| string | Required | Search term (automatically URL-encoded) |
| string | Optional | Sort order (A/C/D/O/Q/R) |
| string | Optional | Province filter |
| string | Optional | District filter (requires |
| int | Optional | Results per page (default 10) |
| int | Optional | Page number (default 1) |
Tool 5 — get_medical_sync_list
Retrieve the full medical tourism synchronisation list. Use for building or refreshing a local database of all facilities.
Upstream endpoint: GET /mdclTursmSyncList
Cache TTL: 5 minutes
Parameter | Type | Required | Description |
| string | Optional | Language code |
| string | Optional |
|
| string | Optional | Last known content ID — fetch only newer records |
| string | Optional | Modified-since date in YYYYMMDD format |
| int | Optional | Results per page (default 10) |
| int | Optional | Page number (default 1) |
Tool 6 — get_detail_common
Fetch full common detail for a specific facility: title, address, GPS, phone, homepage, and overview text.
Upstream endpoint: GET /detailCommon
Cache TTL: 5 minutes
Parameter | Type | Required | Description |
| string | Optional | Language code |
| string | Required | Content ID returned by any list or search tool |
| int | Optional | Results per page (default 1) |
| int | Optional | Page number (default 1) |
Key response fields: contentId, title, overview, homepage, tel, baseAddr, detailAddr, zipCd, mapX, mapY, orgImage, thumbImage, lDongRegnCd, lDongSignguCd, regDt, mdfcnDt
Note: The upstream API returns GPS fields as lowercase
mapx/mapy. This tool normalises them tomapX/mapYfor consistency with the list-endpoint field names.
Tool 7 — get_detail_intro
Fetch type-specific introductory details: opening hours, rest days, parking, capacity, and age suitability.
Upstream endpoint: GET /detailIntro
Cache TTL: 5 minutes
Parameter | Type | Required | Description |
| string | Optional | Language code |
| string | Required | Content ID |
| int | Optional | Results per page (default 1) |
| int | Optional | Page number (default 1) |
Tool 8 — get_detail_medical
Fetch medical-specific details: specialties, foreign languages served, reservation status, and SNS info.
Upstream endpoint: GET /detailMdclTursm
Cache TTL: 5 minutes
Parameter | Type | Required | Description |
| string | Optional | Language code |
| string | Required | Content ID |
| int | Optional | Results per page (default 1) |
| int | Optional | Page number (default 1) |
Key response fields: mainMdclSubjInfo (main specialties), svcLangInfo (supported languages), onlineRsvtPsblYn (online reservation available)
Language Code Reference
Code | Language |
| English |
| Japanese (日本語) |
| Simplified Chinese (简体中文) |
| Korean (한국어) |
| Russian (Русский) |
Error Handling
Upstream API errors
Tool functions surface data.go.kr errors as Python exceptions with descriptive messages. The raw API key is masked ([REDACTED]) in all error strings before they leave the process.
Upstream code | Exception type | Meaning |
| — | Success; returns results |
| — | No data; returns |
|
| Invalid request parameter |
|
| Missing required parameter |
|
| Upstream daily quota (1,000 requests/day) exceeded |
|
| Service key not registered |
|
| Service key expired |
other |
| Unexpected API error with code and message |
Local rate limiter
The server enforces a 10 calls/minute limit (burst of 5) on requests that reach the upstream API. Cache hits bypass the limiter entirely. When the limit is exceeded, the tool returns immediately with:
Rate limit: too many requests to upstream API. Please retry after Xs.
(Limit: 10 calls/min, burst 5)This is a fast-fail design — no blocking sleep — so the agent receives the retry-after guidance instantly and can back off gracefully.
Project Structure
visitkorea-medicaltourism-mcp/
├── mcp-server/
│ ├── main.py # FastMCP entrypoint — Streamable HTTP, /healthz endpoint
│ ├── requirements.txt # mcp[cli], httpx, python-dotenv
│ ├── README.md
│ ├── tools/
│ │ ├── ldong_code.py # get_ldong_code
│ │ ├── area_based_list.py # get_area_based_list
│ │ ├── location_based_list.py # get_location_based_list
│ │ ├── search_keyword.py # search_medical_by_keyword
│ │ ├── sync_list.py # get_medical_sync_list
│ │ ├── detail_common.py # get_detail_common
│ │ ├── detail_intro.py # get_detail_intro
│ │ └── detail_mdcl_tursm.py # get_detail_medical
│ └── utils/
│ ├── config.py # API key loading, FIXED_PARAMS, key masking
│ ├── cache.py # TTL dict cache (24h / 5min by endpoint)
│ ├── rate_limiter.py # Token bucket — 10/min, burst 5, fast-fail
│ ├── api_client.py # call_api() — wires cache, limiter, httpx, retry
│ └── validation.py # Input validation for all parameter types
└── artifacts/
├── landing/ # Developer landing page (React + Vite)
└── api-server/ # Express proxy (CORS, /api/healthz)utils/ module responsibilities
Each module has a single, clearly bounded responsibility:
Module | LOC | Responsibility |
| 41 | Loads |
| 49 | SHA-256-keyed TTL dict cache; |
| 60 |
|
| 141 |
|
| 93 |
|
Performance
Scenario | Typical latency |
Cache hit | < 5 ms |
Cache miss — first | ~600 ms (upstream API) |
Subsequent | < 5 ms |
Cache miss — other tools | ~600 ms |
Subsequent calls within 5 min TTL | < 5 ms |
The httpx client maintains a persistent TCP connection pool (max_connections=10, max_keepalive_connections=5) to avoid TLS handshake overhead on every request. Total request timeout is 15 s; connection timeout is 5 s.
Environment Variables
Variable | Required | Description |
| Yes | API key from data.go.kr (Encoding or Decoding variant) |
| No | Port for uvicorn to listen on (default |
Contributing
Contributions are welcome. Please open an issue before submitting a pull request. Ensure all changes are tested against the live API and that no API keys are committed to the repository.
License
MIT License
Tourism data provided by the Korea Tourism Organization (KTO) via the 공공데이터포털 open API platform (data.go.kr). Data usage is subject to KTO terms — attribution is required for Type1 content; Type3 content additionally prohibits modification.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/leejaew/visitkorea-medicaltourism-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server