Skip to main content
Glama
vietnam-address-mcp

vietnam-address-mcp

by amItuff

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…

CI License: MIT MCP

Tiếng Việt · English

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-mcp

Claude 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.js

Tools

Tool

Use it to

normalize_address

Turn a free-text address, old or new format, into the current structure. Keeps the street.

normalize_addresses

Batch version for up to 200 addresses (a spreadsheet column) with a summary of ok / ambiguous / not found.

convert_legacy_address

Convert an old address that is already split into province / district / ward (e.g. database columns).

search_units

Look up provinces and wards by name. scope: "legacy" searches old units and shows where each maps today.

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.csv

The 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

status: "ok", confidence: "exact"

Every level matched uniquely.

confidence: "split_default"

The old ward was divided between several new wards. A default is returned together with all alternatives; the default is a heuristic.

confidence: "inferred"

The district was missing, but the ward name is unique in the province.

status: "ambiguous"

The input matches several units (e.g. "Phường 1" with no district). candidates lists them; nothing is guessed.

status: "not_found"

No match. didYouMean offers suggestions from the same province.

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_found with 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

thanglequoc/vietnamese-provinces-database

Current provinces and wards (codes, names)

tranngocminhhieu/vietnamadminunits

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.mjs

The 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

MIT. Third-party data notices are in NOTICE.md.

Available Tools

4 tools
convert_legacy_addressConvert an old (pre-2025) ward/district/province to the new unitA
Read-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 unitsA
Read-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 onceA
Read-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 nameA
Read-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

    A4.1/5.0

    Scored across 4 tools

    Disambiguation4/5

    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.

    Naming Consistency5/5

    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.

    Tool Count5/5

    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.

    Completeness4/5

    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

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables Hong Kong address lookup and correction using government data, with fuzzy matching and LLM-powered correction for both Chinese and English addresses.
      4
      ISC
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables 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
    • A
      license
      Not graded
      quality
      A
      maintenance
      Enables 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
    • A
      license
      A
      quality
      C
      maintenance
      Enables 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.
      13
      1
      MIT