前言
--
不知道你有沒有過這種經歷——跟 AI 說「幫我查一下武漢在哪個省」,結果它一本正經地胡說八道,給你編出一個根本不存在的行政區劃代碼。
又或者,做一個地址自動填入的功能,發現手裡的區劃資料要嘛是三五年前的老黃曆,要嘛缺斤少兩,東城區給你標到河北省去了。
這些問題折磨了我很久,直到我發現了國家地名資訊庫(dmfw.mca.gov.cn)——民政部出品的官方資料來源。從 2026 年起,這玩意兒就要正式取代統計局那套統計用區劃代碼了,可以說是「根正苗藍」的官方資料。
我就琢磨,能不能讓 AI 直接調這個 API 來查地名?於是根據官方提供的 API 文件,實作了對應的 MCP 和 Skill,已經開源在 GitHub,地址在文章結尾,需要自取。
先給不了解的同學做個簡介:
這個平台的資料是按年度更新的,所以查詢的時候注意帶上年份參數,不然可能查到的不是你想的那個版本。
行政區劃這玩意兒,全國不統一,有的地方只有兩級,有的地方四級全齊:
層級示例說明第一级北京市、湖北省省級行政區第二级武漢市、北京市市轄區第三級武昌區、東城區區縣級第四級街道/鄉鎮街道辦、鄉鎮幾個容易踩坑的地方:
所以如果你要做全國通用的地址選擇器,這幾種情況一定要特殊處理。
國家地名資訊庫提供了 7 個核心 API,我用了一段時間之後,覺得大部分場景前兩個就夠用了:
序號介面名稱URL方法用途1行政區劃搜尋/xzqh/getListGET查詢行政區劃層級結構2地名搜尋/stname/listPubGET按名稱搜尋地名3地名詳情取得/stname/detailsPubPOST取得地名詳細資訊4同名區劃統計/datastatis/GroupCountNameByCodeGET統計同名地名按區劃分布5同名類別統計/datastatis/GroupCountNameByTypeGET統計同名地名按類別分布6同音區劃統計/datastatis/GroupCountPinyinByCodeGET統計同音地名按區劃分布7同音類別統計/datastatis/GroupCountPinyinByTypeGET統計同音地名按類別分布說實話,同名/同音統計這幾個介面我目前還沒用上,但留著備用總沒錯——萬一哪天產品說「我們要做一個全國有多少個『張村』的統計」,直接調它就完了。
MCP(Model Context Protocol)這玩意兒,你可以理解為 AI 工具的「USB 介面」。以前 AI 想調個外部 API,你得寫一堆 Prompt 來描述怎麼調、調什麼參數。現在有了 MCP,直接定義好工具,AI 就能像呼叫本地函式一樣調遠端 API,爽得很。
bash 体验AI代码助手 代码解读复制代码mcp-china-geonames-server/
├── server.py # MCP 伺服器主檔案
├── requirements.txt # Python 依賴
└── README.md # 專案文件
就三個檔案,簡單明瞭。
我直接上程式碼,註解寫得比較詳細:
python 体验AI代码助手 代码解读复制代码from mcp.server.fastmcp import FastMCP
import requests
from typing import Optional
mcp = FastMCP("China GeoNames MCP Server")
BASE_URL = "https://dmfw.mca.gov.cn/9095"
@mcp.tool()
def search_administrative_division(
year: Optional[int] = None,
code: Optional[str] = None,
maxLevel: int = 1
) -> dict:
"""行政區劃搜尋——查某個地區的下級區劃"""
params = {"maxLevel": maxLevel}
if year:
params["year"] = year
if code:
params["code"] = code
response = requests.get(f"{BASE_URL}/xzqh/getList", params=params)
return response.json()
@mcp.tool()
def search_place_name(
stName: str,
placeTypeCode: Optional[str] = None,
year: Optional[int] = None,
searchType: str = "模糊",
code: Optional[str] = None,
page: int = 1,
size: int = 10
) -> dict:
"""地名搜尋——按名字查地點,支援模糊比對"""
params = {
"stName": stName,
"searchType": searchType,
"page": page,
"size": size
}
if placeTypeCode:
params["placeTypeCode"] = placeTypeCode
if year:
params["year"] = year
if code:
params["code"] = code
response = requests.get(f"{BASE_URL}/stname/listPub", params=params)
return response.json()
@mcp.tool()
def get_place_details(id: str) -> dict:
"""地名詳情——拿到 ID 之後查詳細資訊"""
response = requests.post(f"{BASE_URL}/stname/detailsPub", json={"id": id})
return response.json()
幾個小提示:
maxLevel=1 就是只查下一級,maxLevel=3 就是查三級。建議先試試 maxLevel=1,不然資料量會讓你懷疑人生(全國三級資料大概 300KB 左右)。code 參數傳空字串代表從根開始查,傳具體代碼查該節點下的子級。bash 体验AI代码助手 代码解读复制代码# 安裝依賴
pip install -r requirements.txt
# 執行伺服器
python server.py
就這些,沒有了。跑起來之後,設定到你的 AI 用戶端(Claude Desktop、Cline 之類的),就可以開聊了。
MCP 是讓 AI「會調」API,Skill 則是讓 AI「懂」API。
舉個例子,沒有 Skill 的時候,你讓 AI 幫你查「武漢屬於哪個省」,它可能得試好幾次才能蒙對。有了 Skill,AI 直接就知道:這個介面回傳的 data[].code 是行政區劃代碼,data[].name 是名稱,應該怎麼組合查詢。
我把官方 API 的合約用結構化的方式描述出來,AI 看了就知道怎麼用:
markdown 体验AI代码助手 代码解读复制代码## 1. 行政區劃搜尋
**URL:** `https://dmfw.mca.gov.cn/9095/xzqh/getList`
**請求方式:** GET
**請求參數:**
| 參數名 | 類型 | 必填 | 預設值 | 說明 |
|--------|------|------|--------|------|
| year | int | 否 | 最新年版 | 年份 |
| code | String | 否 | - | 行政區劃代碼 |
| maxLevel | int | 是 | - | 查詢深度 |
**回應參數:**
| 參數名 | 類型 | 說明 |
|--------|------|------|
| data | Object[] | 回傳結果集 |
| data[].code | String | 行政區劃代碼 |
| data[].name | String | 標準名稱 |
格式其實很直接,就是參數說明 + 回應說明。關鍵是寫清楚類型、是否必填、預設值這些,AI 才能準確地生成呼叫程式碼。
如果你只是想快速試試這個 API 能不能跑通,最方便的方法是直接打開瀏覽器主控台。
按 F12 → 切換到 Console 標籤 → 貼上下面的程式碼按 Enter:
javascript 体验AI代码助手 代码解读复制代码// 取得全國省市區三級資料(資料量較大,約300KB)
var response = await fetch("https://dmfw.mca.gov.cn/9095/xzqh/getList?code=&maxLevel=3");
var data = await response.json();
console.log(data);
// 只取得省級資料(建議初次使用)
var response = await fetch("https://dmfw.mca.gov.cn/9095/xzqh/getList?code=&maxLevel=1");
var data = await response.json();
console.log(data);
// 取得湖北省 省、市、區三級
var response = await fetch("https://dmfw.mca.gov.cn/9095/xzqh/getList?code=420000000000&maxLevel=3");
var data = await response.json();
console.log(data);
// 取得武漢市 市、區縣、鄉鎮街道三級
var response = await fetch("https://dmfw.mca.gov.cn/9095/xzqh/getList?code=420100000000&maxLevel=3");
var data = await response.json();
console.log(data);
這個方法的好處是所見即所得——回傳什麼資料你立刻就能看到,比 Postman 還快,而且不用裝任何軟體。除錯介面的時候超方便,誰用誰知道。
說實話,自己處理這套四級行政區劃資料還挺麻煩的。好在社群裡已經有大佬做了更易用的封裝:
xiangyuecn/area-javascript-sql(GitHub)
這個專案把國家地名資訊庫的四級資料整合到單個 CSV 檔案裡,還附帶了:
如果你不打算折騰 API,直接用這個也挺好。
我自己實作的 MCP 伺服器和 Skill 規範都開源了,有需要自取:
項目倉庫地址說明MCP 伺服器github.com/linyshdhhcb…基於 FastMCP 實作,開箱即用Skill 規範github.com/linyshdhhcb…完整的 API 規範文件覺得有用的話,給個 Star 呗!
花了點時間把國家地名資訊庫的 API 跑通了,說實話比我想像中順利——主要踩的坑都在行政區劃的特殊情況上(直轄市、省直轄縣這些),真正調介面的部分反而沒遇到什麼問題。
最後一個小建議:線上用一定要加快取。這個 API 回傳的資料量不小,頻繁呼叫既慢又浪費頻寬。把常用的省市區資料緩存在本地或 Redis 裡,體驗會好很多。
參考資料: