normalize_codes
Standardizes Japanese prefecture and municipality names into official codes and formal names for accurate data retrieval from the MLIT Data Platform.
Instructions
入力された都道府県名・市区町村名を正規化し、正式なコードと名称を取得する。
使用ケース:
1. ユーザー入力('東京', 'Tokyo', '13')を正規化 → '13' + '東京都'
2. 市区町村名から5桁コードを取得
3. 曖昧な入力の候補一覧取得
このツールを他の検索ツールの前に実行することで、正確なprefecture_code/municipality_codeを取得できますInput Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| prefecture | No | 都道府県の指定。以下の形式に対応: - コード: '13', '27' - 日本語: '東京都', '東京', '大阪府', '大阪' - ローマ字: 'Tokyo', 'Osaka', 'Hokkaido' 全角数字(例: '13')も自動的に正規化されます | |
| municipality | No | 市区町村の指定。以下の形式に対応: - JISコード: '13101' (千代田区) - 日本語: '千代田区', '港区' 注意: 市区町村を指定する場合、prefectureも併せて指定することを推奨します(同名の市区町村が複数存在する可能性があるため) |
Implementation Reference
- src/client.py:1204-1304 (handler)The `normalize_codes` method in `MLITClient` class handles the logic for normalizing prefecture and municipality names/codes into standardized identifiers. It uses internal caches for prefectures and municipalities and provides several strategies for matching.
async def normalize_codes(self, params: NormalizeCodesInput) -> NormalizeCodesOutput: out = NormalizeCodesOutput( normalization_meta={ "input_prefecture": params.prefecture, "input_municipality": params.municipality, "matched_strategy": None, } ) pref_in = (params.prefecture or "").strip() pref_rows = await self._load_pref_list() pref_code: Optional[str] = None pref_name: Optional[str] = None if pref_in: pcanon = self._canon(pref_in) if pcanon.isdigit(): for r in pref_rows: code = str(r["code"]) if code == pcanon or code.lstrip("0") == pcanon.lstrip("0"): pref_code, pref_name = code, r["name"] out.normalization_meta["matched_strategy"] = "pref:code" break if pref_code is None: for r in pref_rows: nm = r["name"] nm_core = self._strip_pref_suffix(nm) in_core = self._strip_pref_suffix(self._nfkc(pref_in)) if nm == pref_in or nm_core == in_core: pref_code, pref_name = str(r["code"]), nm out.normalization_meta["matched_strategy"] = "pref:jp_exact" break if pref_code is None and pcanon.isascii(): alias = self._pref_romaji_map().get(pcanon.replace(" ", "").replace("-", "")) if alias: for r in pref_rows: if r["name"] == alias: pref_code, pref_name = str(r["code"]), r["name"] out.normalization_meta["matched_strategy"] = "pref:romaji" break if pref_code is None: for r in pref_rows: nm = r["name"] if self._strip_pref_suffix(nm) in self._nfkc(pref_in): pref_code, pref_name = str(r["code"]), nm out.normalization_meta["matched_strategy"] = "pref:jp_contains" break muni_in = (params.municipality or "").strip() muni_code: Optional[str] = None muni_name: Optional[str] = None candidates: List[MunicipalityCandidate] = [] if muni_in: mcanon = self._canon(muni_in) if mcanon.isdigit() and len(mcanon) >= 5: if pref_code: mlist = await self._load_muni_list(pref_code) for r in mlist: if str(r["code_as_string"]) == mcanon: muni_code, muni_name = r["code_as_string"], r["name"] out.normalization_meta["matched_strategy"] = "muni:code_in_pref" break if muni_code is None and not pref_code: out.warnings.append("municipality_code_provided_but_prefecture_unknown") else: if pref_code: mlist = await self._load_muni_list(pref_code) for r in mlist: if r["name"] == self._nfkc(muni_in): muni_code, muni_name = r["code_as_string"], r["name"] out.normalization_meta["matched_strategy"] = "muni:jp_exact" break if muni_code is None: for r in mlist: if self._nfkc(muni_in) in r["name"]: candidates.append(MunicipalityCandidate( municipality_code=str(r["code_as_string"]), municipality_name=str(r["name"]) )) if len(candidates) == 1: muni_code, muni_name = candidates[0].municipality_code, candidates[0].municipality_name candidates = [] out.normalization_meta["matched_strategy"] = "muni:jp_contains_unique" elif len(candidates) > 1: out.normalization_meta["matched_strategy"] = "muni:jp_contains_ambiguous" out.warnings.append("ambiguous_municipality: multiple candidates") else: out.warnings.append("municipality_without_prefecture: provide prefecture for disambiguation") out.prefecture_code = pref_code out.prefecture_name = pref_name out.municipality_code = muni_code out.municipality_name = muni_name out.candidates = candidates if pref_code and not muni_code and not muni_in: out.warnings.append("attribute_only_hint: some MLIT attribute-only queries require term:\"\" or an additional attribute (e.g., address)") return out - src/schemas.py:291-302 (schema)Input and output schemas for `normalize_codes` tool.
class NormalizeCodesInput(BaseModel): prefecture: Optional[str] = None municipality: Optional[str] = None class MunicipalityCandidate(BaseModel): municipality_code: str municipality_name: str class NormalizeCodesOutput(BaseModel): prefecture_code: Optional[str] = None