Content
# Cadastral MCP Server
VWorld (Ministry of Land, Infrastructure and Transport) Open API-based **Land Use Plan Inquiry + Cadastral Map DXF Export** MCP Server.
## Features
| Tool | Description |
|---|---|
| `get_land_use_plan` | Inquiry land use plan + land register (land category, area, ownership) + land use district/zone/area + individual land price |
| `get_land_use_plan_by_pnu` | Same as above, but by PNU (19 digits) |
| `export_cadastral_dxf` | Export cadastral map (with neighboring parcels) to DXF file by address |
| `export_cadastral_dxf_by_pnu` | Same as above, but by PNU (19 digits) |
| `export_land_report_dxf` | Export land report (including land use plan, cadastral map, and individual land price) to DXF file by address |
| `export_land_report_dxf_by_pnu` | Same as above, but by PNU (19 digits) |
| `search_national_law` | Search national laws by name |
| `get_national_law_text` | Get national law text by MST (law serial number) |
All features are for reference only and do not replace the legally effective "Land Use Plan Confirmation Certificate" or cadastral survey results. For accurate confirmation, please contact [eum.go.kr](https://www.eum.go.kr) or the relevant administrative office.
## Installation
```bash
npm install
npm run build
```
To use `export_land_report_dxf` (one-page report with XCLIP cropping), Python 3 and ezdxf are also required:
```bash
pip install ezdxf
```
If multiple Python installations are present and auto-detection fails, specify the correct path in `.env` as `CADASTRAL_PYTHON`.
## VWorld API Key Issuance
1. Register and log in to [vworld.kr](https://www.vworld.kr)
2. Apply for an open API authentication key on the service URL page:
- **Service URL**: The domain/IP where this server will be executed (e.g., `http://localhost`, actual domain when deploying the server)
- **Utilization API**: Check the following items:
- `Search API` — Address to PNU conversion
- `2D Data API` — Cadastral parcel boundary coordinates, individual land price (polygon attributes)
- `National Focus API` — Land register, land use district/zone (under `ned/data/*` endpoints)
- `WMS/WFS API` — Not required but can be checked together
3. Approval may take immediate to several hours.
**Important**: `Search API` works without a domain value, but `2D Data` and `National Focus` APIs require the `domain` parameter to match the registered service URL, or an `INCORRECT_KEY` error will occur. Ensure `VWORLD_DOMAIN` matches the service URL.
## Environment Variables
Copy `.env.example` to `.env` and fill in the variables.
| Variable | Required | Description |
|---|---|---|
| `VWORLD_KEY` | Required | VWorld open API authentication key |
| `VWORLD_DOMAIN` | Highly recommended | Service URL registered with the key; omit if not required for 2D Data and National Focus APIs |
| `DXF_OUTPUT_DIR` | Optional | DXF file storage path (default: `./output`) |
| `CADASTRAL_PYTHON` | Optional | Python executable path for `export_land_report_dxf`'s XCLIP cropping; auto-detection if not specified |
| `LAW_OC` | Optional | Law Ministry Open API authentication key; used for automatic inquiry of land use regulations |
## MCP Client Connection (e.g., Claude Desktop)
`claude_desktop_config.json`:
```json
{
"mcpServers": {
"cadastral-mcp": {
"command": "node",
"args": ["absolute_path/cadastral-mcp/build/index.js"],
"env": {
"VWORLD_KEY": "issued_key",
"VWORLD_DOMAIN": "registered_service_url"
}
}
}
}
```
## Tool Details
### `get_land_use_plan` / `get_land_use_plan_by_pnu`
- Input: `address` (or `pnu`), `stdrYear` (optional, land price reference year, default: current year)
- Output example:
```json
{
"PNU": "5211312000100770003",
"landRegister": { "landCategory": "paddy field", "area": "4470", "ownership": "private" },
"landUseDistrict": ["natural disaster risk improvement district", "livestock breeding restriction area", "production green zone"],
"individualLandPrice": [{ "referenceYear": "2026", "landPricePerSquareMeter": "191300" }]
}
```
### `export_cadastral_dxf` / `export_cadastral_dxf_by_pnu`
- Input: `address` (or `pnu`), `crs` (optional, default: `EPSG:5186`), `includeNeighbors` (optional, default: `true`), `bufferMeters` (optional, default: `50`)
- The target parcel and neighboring parcels within the `bufferMeters` range are queried and drawn.
- **If the user does not specify the range, ask for confirmation before proceeding.** (The tool description includes this guideline, and the MCP client can automatically recognize it.)
- DXF layer configuration:
- `TARGET_PARCEL` / `TARGET_LABEL` — Target parcel boundary (thick red line) + parcel number label
- `NEIGHBOR_PARCELS` / `NEIGHBOR_LABEL` — Neighboring parcel boundaries (thin blue line) + parcel number label
- `SOURCE_NOTE` — Source/disclaimer text (green)
### `export_land_report_dxf` / `export_land_report_dxf_by_pnu`
- Input: `address` (or `pnu`), `crs`/`includeNeighbors`/`bufferMeters` (default values are the same as `export_cadastral_dxf`), `stdrYear` (optional)
- One-page layout (dot font, white diamond icon + green title + yellow double underline title), left and right top tables:
- **Left**: Request information table — location, land area, land category, district/zone — VWorld data. **Maximum building coverage ratio, maximum floor area ratio, landscaping plan, and parking plan are displayed in separate rows with national law limits and local ordinance values** (see "Automatic Inquiry of Local Ordinances" below). Front road and road connection length are not available due to missing data sources — displayed as `-`
- **Top right**: Land use plan — 7-row table with administrative district, parcel number, land category, area, ownership, district/zone, and individual land price
- **Bottom right**: Cadastral map — drawn using `CADASTRAL_MAP` block, with panel border as boundary for **actual AutoCAD XCLIP (SPATIAL_FILTER)** to crop out parcels outside the box (like roads)
## Automatic Inquiry of Local Ordinances (Building Coverage Ratio/Floor Area Ratio/Landscaping/Parking)
- Extract the city name from the administrative district and search for "{city} urban planning ordinance"/"{city} building ordinance"/"{city} parking lot ordinance" using the Law Ministry Open API.
- In the entire text of the ordinance, find the relevant clauses using keywords like "building coverage ratio" + 21 land use district names.
- If the ordinance is not found or parsing fails, **national law limits** are displayed in a separate row. The table shows both (law)/(ordinance) rows, and if the ordinance inquiry fails, the ordinance row displays the failure reason.
## Real-time Inquiry of National Laws (Building Coverage Ratio/Floor Area Ratio) — `lib/national-law.ts`
- Like local ordinances, **directly call the Law Ministry API for each request** to read the text of the National Land Planning Act Enforcement Ordinance, Article 84 (building coverage ratio) and Article 85 (floor area ratio).
- If the inquiry fails (network error, etc.), always fall back to **verified fixed values (`lib/zoning-standards.ts`)**.
## Data Sources
- Cadastral boundary, parcel number, land price: VWorld 2D Data API (`req/data`, layer `LP_PA_CBND_BUBUN` — continuous cadastral map). The original data is managed by the Ministry of Land, Infrastructure and Transport/Korea Land Information Corporation (LX) and serviced by VWorld through a REST API. Do not directly read the shp file.
- Land register, land use district/zone: VWorld National Focus (NED) API (`ned/data/ladfrlList`, `ned/data/getLandUseAttr`)
- Individual land price: VWorld National Focus (NED) API (`ned/data/getIndvdLandPriceAttr`)
## Known Limitations
- Donut-shaped parcels with holes are supported but not verified in actual use cases.
- DXF is for reference only and does not have legal effect as a cadastral survey result.
- VWorld data update cycles (usually monthly) may not reflect real-time status.
- XCLIP in `export_land_report_dxf` is verified with actual AutoCAD for normal operation (cropping parcels outside the box).
- If multiple Python installations are present and ezdxf is not found, specify the path with `CADASTRAL_PYTHON`.
- Automatic inquiry of local ordinances may fail for some regions due to differences in ordinance names and table formats. In such cases, only national law limits are displayed.
- Parsing of HWP (kordoc) may not guarantee 100% success due to various document formats. If parsing fails, display "[Attached Table] — failure to automatically extract detailed standards".
- Real-time inquiry of national law building coverage ratio and floor area ratio (`lib/national-law.ts`) assumes stable Article numbers (Article 84/85). If the law is revised and the article is deleted or moved, the inquiry fails but falls back to fixed values.
## Development
```bash
npm run watch # TypeScript watch build
npm run typecheck # Type check only
npm test # vitest
```
Tests verify only pure logic without network calls — local ordinance parsing (`local-ordinance.test.ts`), national law limits (`zoning-standards.test.ts`), and national law real-time inquiry parsing (`national-law.test.ts`). API integration (VWorld/Law Ministry/XCLIP) is verified manually with actual keys.