vietnam-address-mcp
Click on "Deploy 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., "@vietnam-address-mcp Chuẩn hóa địa chỉ: 12 Lê Lợi, Phường Bến Nghé, Quận 1, TP.HCM"
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.
vietnam-address-mcp
Convert old Vietnamese addresses to the new 34-province structure — straight from your AI assistant. Đổi địa chỉ cũ sang đơn vị hành chính mới (sau sáp nhập tỉnh, bỏ cấp huyện) ngay trong Claude, Cursor, VS Code…
The animation is drawn from the real server's output (demo/capture.mjs), not typed by hand.
Why
Since 1 July 2025 Vietnam has 34 provinces and 3,321 wards/communes, and the district level is gone. Addresses in your CRM, order forms and shipping data still use the old 63-province, 3-level format.
Mapping them is not something a language model can do reliably from memory: there are 10,040 old units, 471 of them were split between several new wards, and names such as "Phường 1" exist in many districts. This server answers from data instead, and says so when the answer is uncertain.
Related MCP server: dia-chi-moi
Install
Requires Node.js 20+. No network access or API key is needed at runtime.
Claude Code
claude mcp add vietnam-address -- npx -y vietnam-address-mcpClaude Desktop, Cursor, VS Code, any MCP client — add to the client's MCP config:
{
"mcpServers": {
"vietnam-address": {
"command": "npx",
"args": ["-y", "vietnam-address-mcp"]
}
}
}From source
git clone https://github.com/amItuff/vietnam-address-mcp.git
cd vietnam-address-mcp
npm ci && npm run build
# then point your client at: node /absolute/path/to/vietnam-address-mcp/dist/index.jsTools
Tool | Use it to |
| Turn a free-text address, old or new format, into the current structure. Keeps the street. |
| Batch version for up to 200 addresses (a spreadsheet column) with a summary of ok / ambiguous / not found. |
| Convert an old address that is already split into |
| Look up provinces and wards by name. |
Every result carries dataVersion (currentThrough and effectiveDate), so you can see which legal
basis the data reflects. It is currently Resolution 388/NQ-UBTVQH16, effective 2026-09-20.
Spreadsheets (CSV)
No MCP client needed for a file of addresses:
npx -y vietnam-address-mcp csv customers.csv --column address --output customers.new.csvThe original columns are kept and new_address, address_status, address_confidence and address_note
are appended. Filter on address_status (ok, ambiguous, not_found) and on
address_confidence = split_default to review the rows that need a human. Commas, semicolons and tabs
are detected automatically (override with --delimiter).
Try asking your assistant: "Chuẩn hóa địa chỉ: 12 Lê Lợi, Phường Bến Nghé, Quận 1, TP.HCM".
{
"status": "ok",
"inputFormat": "legacy",
"confidence": "exact",
"street": "12 Lê Lợi",
"address": {
"ward": { "code": "26740", "fullName": "Phường Sài Gòn" },
"province": { "code": "79", "fullName": "Thành phố Hồ Chí Minh" },
"formatted": "Phường Sài Gòn, Thành phố Hồ Chí Minh",
"formattedWithStreet": "12 Lê Lợi, Phường Sài Gòn, Thành phố Hồ Chí Minh"
},
"from": {
"province": { "code": "79", "fullName": "Thành phố Hồ Chí Minh" },
"district": { "code": "760", "fullName": "Quận 1" },
"ward": { "code": "26740", "fullName": "Phường Bến Nghé" },
"formatted": "Phường Bến Nghé, Quận 1, Thành phố Hồ Chí Minh"
},
"notes": []
}How uncertainty is reported
Every response carries a status and, when it succeeded, a confidence. Assistants are instructed to
surface these instead of hiding them.
Result | Meaning |
| Every level matched uniquely. |
| The old ward was divided between several new wards. A default is returned together with all |
| The district was missing, but the ward name is unique in the province. |
| The input matches several units (e.g. "Phường 1" with no district). |
| No match. |
Also handled: missing diacritics, abbreviations (P., Q., TP.HCM), a street glued to the ward,
units whose type changed (Xã Bố Hạ → Phường Bố Hạ), and names that differ only by diacritics
(Văn Lang / Văn Lăng).
Limitations
Read these before relying on the output.
Old → new only. The reverse direction is genuinely one-to-many and is not implemented.
Divided wards are heuristic. 471 of 10,040 old units (~4.7%) were split. The default target was chosen upstream by comparing the old ward's geocoded centre point with the new boundaries. It is a sensible guess, not a legal determination — confirm with the street or the official resolution.
Names only. There is no street-level data and no geocoding.
Comma-separated input. Components must be separated by commas (a street glued to the ward is the one exception).
Old-ward coverage. The old list is the General Statistics Office catalogue of mid-2025. Wards that were merged or renamed before that and are missing from it may return
not_foundwith suggestions.Data freshness. New-unit names and codes are current through Resolution 388/NQ-UBTVQH16 (effective 2026-09-20). Later changes need a data update (see CONTRIBUTING).
Not legal advice. For contracts and official filings, check the resolutions.
Data and licensing
The server is offline and ships its dataset (data/, about 2.2 MB), generated by
scripts/build-data.mjs from two MIT-licensed projects pinned to exact commits:
Source | Provides |
Current provinces and wards (codes, names) | |
Old ward list and the old → new mapping |
The build validates hard invariants (34 provinces, 3,321 wards, every mapping target exists, every divided ward has exactly one default, every new ward is reachable) and CI rebuilds the data from the pinned commits and fails if the committed files differ. Details and attribution: NOTICE.md.
If you only need a library rather than an MCP server, see the Python package vietnamadminunits, whose data this project builds on.
Development
npm ci
npm run typecheck && npm test # Node >= 22 for the tests
npm run build && node scripts/smoke.mjsThe test suite includes round trips over every unit in the dataset (each old ward written out in full must convert to one of its own targets; each new ward must resolve to itself), plus golden cases cross-checked against Resolution 1685/NQ-UBTVQH15. See CONTRIBUTING.md.
License
Available Tools
4 toolsconvert_legacy_addressConvert an old (pre-2025) ward/district/province to the new unitARead-onlyIdempotent
Converts a pre-July-2025 administrative address given as separate fields to the new 2-level structure. Prefer this over normalize_address when the parts are already split (e.g. database columns). Đổi xã/phường/huyện/tỉnh cũ sang đơn vị hành chính mới. If the old ward was divided between several new wards, the result has confidence "split_default" and lists every alternative. Omitting the district works when the ward name is unique in the province; otherwise the result is "ambiguous".
Inputs: province (required), ward, street, district.
normalize_addressNormalize a Vietnamese address to the new administrative unitsARead-onlyIdempotent
Takes a free-text, comma-separated Vietnamese address in either the OLD format (ward, district, province - before 1 July 2025) or the NEW format (ward, province) and returns it in the current 2-level structure (34 provinces, no districts), keeping the street part. Handles missing diacritics, abbreviations (P., Q., TP.HCM) and a street glued to the ward. Chuẩn hóa địa chỉ / đổi địa chỉ cũ sang địa chỉ mới sau sáp nhập tỉnh, bỏ cấp huyện. Returns status ok | ambiguous | not_found, a confidence level, alternatives for divided wards, and suggestions for typos.
Inputs: address (required).
normalize_addressesNormalize many Vietnamese addresses at onceARead-onlyIdempotent
Batch version of normalize_address for up to 200 addresses (for example a column of a customer or order spreadsheet). Returns one result per input in the same order plus a summary of how many are ok, ambiguous, not_found or divided-ward defaults. Review ambiguous and not_found items with the user instead of guessing. Chuẩn hóa hàng loạt địa chỉ cũ sang địa chỉ mới.
Inputs: addresses (required).
search_unitsLook up provinces and wards by nameARead-onlyIdempotent
Searches administrative units by name, ignoring diacritics and tolerating small typos. scope "current" (default) searches the 34 provinces and 3,321 wards in force today and returns official codes. scope "legacy" searches pre-2025 provinces, districts and wards and returns where each one maps to now. Tra cứu tỉnh/thành, phường/xã theo tên, kèm mã đơn vị hành chính.
Inputs: query (required), level, limit, scope, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 4 tools
Each tool has a stated input shape: batch array (normalize_addresses), free-text string (normalize_address), pre-split fields (convert_legacy_address), and name lookup (search_units). The only overlap is between normalize_address and convert_legacy_address, which both produce the same normalized output, but descriptions explicitly say to prefer the latter when fields are already split.
All four names are snake_case with a clear verb_noun structure (normalize_address, convert_legacy_address, search_units), and the batch variant follows a predictable plural convention (normalize_addresses). No mixed styles or vague verbs.
Four tools is lean but each covers a distinct entry mode (single free-text, batch, structured fields, lookup) with no filler. Nothing suggests a missing variant at this scope.
The surface covers old-format normalization, new-format passthrough, batch processing, structured conversion, and search in both current and legacy scopes, plus ambiguity/suggestion handling. Minor gaps remain: no batch variant for convert_legacy_address and no reverse (new-to-old) mapping, though most agents can work around these.
Maintenance
Related MCP Connectors
Convert old Vietnamese addresses to the 2025 format and check new ones, per official resolutions.
Address validation & geocoding for AI agents: 240+ countries, UK PAF, free US/CA enrichment
日本の住所⇄郵便番号を変換。表記ゆれも吸収。Japan address ⇄ postal code, handles messy input. Free tier, no API key.
Normalize and verify Japanese postal addresses into structured fields for agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables Hong Kong address lookup and correction using government data, with fuzzy matching and LLM-powered correction for both Chinese and English addresses.4ISC
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to convert old Vietnamese addresses (63 provinces with district level) into post-2025 addresses (34 provinces, ward/province only), returning new ward codes, postal codes, confidence and all candidates when a unit was split or ambiguous. Also exposes tools to parse free-form addresses, search old/new administrative units, list provinces and wards, and trace which old units formed a new ward.MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to build and parse VietQR payments, convert old 63-province addresses to the 34-province structure, validate tax IDs and e-invoices, turn money amounts into Vietnamese words, and convert between solar and lunar calendar dates. All tools run offline with bundled data, returning structured ok/error results.MIT
- AlicenseAqualityCmaintenanceEnables offline, fully local lookups and validations tuned for Chinese development work: statutory holiday and adjusted-workday checks, workday arithmetic, ID card/USCC/mobile format validation, Chinese-to-pinyin conversion, lunar-solar date conversion, and administrative region queries. It also provides searchable summaries of common uni-app, mini program, Element Plus, and Vant APIs, so assistants can answer these questions without any network calls or third-party services.131MIT