get_law_abbreviations
Look up Korean law abbreviations and their full official names, including domain-specific aliases, with support for partial matching and date filtering. Retrieves bidirectional mappings from a comprehensive dictionary.
Instructions
법령 약칭 사전 (법제처 lawSearch · target=lsAbrv). 법제처가 등록한 전체 약칭 매핑(약 2,600건)에서 query로 부분 매칭. 도메인 약칭(정통망법·개보법 등 lsAbrv 미등록) → PRIVACY_ALIASES로 자동 변환 후 검색. 예: '정통망법' → 도메인 변환 → 「정보통신망 이용촉진 및 정보보호 등에 관한 법률」 매칭. '개인정보 보호법' → 정식명만 사용 (lsAbrv는 약칭 없는 법령 미수록). 약칭 → 정식명 / 정식명 → 약칭 양방향. 응답 1.2MB+ 가져와 모듈 캐시(24h) 사용 — bypassCache=true로 강제 갱신. stdDt/endDt 지정 시 서버측 필터 (캐시 무시). 다음: get_law_text(mst)로 본문, search_law(query)로 정식 검색.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | 약칭 또는 정식 법령명 키워드 (부분 매칭, 양방향). 예: '정통망법' → 정식명 조회, '개인정보 보호법' → 약칭 조회. 미지정 시 등록 순으로 N건 덤프. | |
| exact | No | 정확 매칭 여부 (기본 false: 부분 매칭) | |
| display | No | 결과 개수 (기본 20, 최대 100). 클라이언트 측 절단. | |
| stdDt | No | 등록일 시작 YYYYMMDD (서버측 필터, 캐시 무시) | |
| endDt | No | 등록일 종료 YYYYMMDD (서버측 필터, 캐시 무시) | |
| bypassCache | No | 모듈 캐시 무시 강제 갱신 |
Implementation Reference
- The main tool definition including the `handler` function that executes the get_law_abbreviations logic: fetches law abbreviations from the API, applies caching (24h TTL), filters by query (partial or exact match), resolves domain-specific aliases via resolveLawAlias, and formats the response text.
export const getLawAbbreviations: Tool<typeof inputSchema> = { name: "get_law_abbreviations", description: "법령 약칭 사전 (법제처 lawSearch · target=lsAbrv). " + "법제처가 등록한 전체 약칭 매핑(약 2,600건)에서 query로 부분 매칭. " + "도메인 약칭(`정통망법`·`개보법` 등 lsAbrv 미등록) → PRIVACY_ALIASES로 자동 변환 후 검색. " + "예: '정통망법' → 도메인 변환 → 「정보통신망 이용촉진 및 정보보호 등에 관한 법률」 매칭. " + "'개인정보 보호법' → 정식명만 사용 (lsAbrv는 약칭 없는 법령 미수록). " + "약칭 → 정식명 / 정식명 → 약칭 양방향. " + "응답 1.2MB+ 가져와 모듈 캐시(24h) 사용 — bypassCache=true로 강제 갱신. " + "stdDt/endDt 지정 시 서버측 필터 (캐시 무시). " + "다음: get_law_text(mst)로 본문, search_law(query)로 정식 검색.", inputSchema, async handler(args, client) { try { const useCache = !args.stdDt && !args.endDt && !args.bypassCache; let items: AbbrItem[]; let cacheUsed = false; if (useCache && CACHE && Date.now() - CACHE.loadedAt < CACHE_TTL_MS) { items = CACHE.items; cacheUsed = true; } else { const fetchOpts: { stdDt?: string; endDt?: string } = {}; if (args.stdDt) fetchOpts.stdDt = args.stdDt; if (args.endDt) fetchOpts.endDt = args.endDt; items = await fetchAll(client, fetchOpts); if (useCache) { CACHE = { items, loadedAt: Date.now() }; } } // 도메인 약칭 fallback — '정통망법' → '정보통신망 이용촉진 및 정보보호 등에 관한 법률' // PRIVACY_ALIASES에 등록된 입력만 변환 (lsAbrv 미등록 약칭 보완). const resolvedQuery = args.query ? resolveLawAlias(args.query) : undefined; const aliasResolved = resolvedQuery !== undefined && resolvedQuery !== args.query; const total = items.length; const filtered = resolvedQuery ? items.filter((it) => matches(it, resolvedQuery, args.exact)) : items; if (filtered.length === 0) { const queryNote = aliasResolved ? `"${args.query}" → "${resolvedQuery}" (도메인 약칭 변환)` : `"${args.query}"`; return notFoundResponse( args.query ? `법령 약칭 매칭 없음: ${queryNote} (전체 ${total}건 중 0건)` : `법령 약칭 사전 비어 있음 (등록일 ${args.stdDt ?? "?"}~${args.endDt ?? "?"})`, [ `search_law(query="${args.query ?? ""}") — 정식명·내용 검색 (PRIVACY_ALIASES fallback 포함)`, `intelligent_law_search(query="${args.query ?? ""}") — 의미 검색`, ] ); } const sliced = filtered.slice(0, args.display); let text = `법령 약칭 사전`; if (args.query) { text += ` — "${args.query}"`; if (aliasResolved) text += ` → "${resolvedQuery}" (도메인 약칭 변환)`; } text += "\n"; text += `전체 ${total}건`; if (args.query) text += ` 중 ${filtered.length}건 매칭`; text += ` · ${sliced.length}건 표시`; if (cacheUsed) text += ` (캐시 사용)`; text += "\n\n"; for (let i = 0; i < sliced.length; i++) { const it = sliced[i]; if (!it) continue; const abbr = it.법령약칭명 || "(약칭 미등록)"; text += `[${i + 1}] ${it.법령명한글}\n`; text += ` 약칭: ${abbr}\n`; const meta: string[] = []; if (it.법령구분명) meta.push(it.법령구분명); if (it.현행연혁코드) meta.push(it.현행연혁코드); if (it.소관부처명) meta.push(it.소관부처명); if (it.시행일자) meta.push(`시행 ${it.시행일자}`); if (meta.length > 0) text += ` ${meta.join(" · ")}\n`; text += ` [mst=${it.법령일련번호}, lawId=${it.법령ID}]\n\n`; } const firstItem = sliced[0]; if (firstItem) { text = appendSuggestions(text, [ { tool: "get_law_text", args: { mst: firstItem.법령일련번호 }, reason: `${firstItem.법령명한글} 본문`, }, { tool: "search_law", args: { query: firstItem.법령명한글 }, reason: "정식 검색 (약칭이 다른 법령과 충돌 시)", }, ]); } return { content: [{ type: "text", text }] }; } catch (err) { return formatToolError(err, "get_law_abbreviations"); } }, }; - Input schema defined using Zod, with fields: query (optional string), exact (boolean, default false), display (1-100, default 20), stdDt/endDt (optional YYYYMMDD date strings), and bypassCache (boolean, default false).
const inputSchema = z.object({ query: z .string() .optional() .describe( "약칭 또는 정식 법령명 키워드 (부분 매칭, 양방향). " + "예: '정통망법' → 정식명 조회, '개인정보 보호법' → 약칭 조회. " + "미지정 시 등록 순으로 N건 덤프." ), exact: z .boolean() .default(false) .describe("정확 매칭 여부 (기본 false: 부분 매칭)"), display: z .number() .int() .min(1) .max(100) .default(20) .describe("결과 개수 (기본 20, 최대 100). 클라이언트 측 절단."), stdDt: z .string() .regex(/^\d{8}$/) .optional() .describe("등록일 시작 YYYYMMDD (서버측 필터, 캐시 무시)"), endDt: z .string() .regex(/^\d{8}$/) .optional() .describe("등록일 종료 YYYYMMDD (서버측 필터, 캐시 무시)"), bypassCache: z .boolean() .default(false) .describe("모듈 캐시 무시 강제 갱신"), }); - src/tools/registry.ts:36-84 (registration)Import of getLawAbbreviations from the primitive file and its registration in the ALL_TOOLS array at line 84, which is then indexed by name in the TOOL_INDEX map for tool lookup.
import { getLawAbbreviations } from "./primitives/get-law-abbreviations.js"; import { getLawTree } from "./primitives/get-law-tree.js"; // W3 — Layer C corpus import { searchPrivacyCorpus } from "./corpus/search-privacy-corpus.js"; import { searchPrivacyCases } from "./corpus/search-privacy-cases.js"; import { searchPrivacyGuides } from "./corpus/search-privacy-guides.js"; // W3 — Layer B+ hints (PIPC 공식 출처 인덱스화) import { getSectoralRelatedLaws } from "./hints/get-sectoral-related-laws.js"; import { getPipcCuratedCorpus } from "./hints/get-pipc-curated-corpus.js"; // W4 — Validator (4계층 환각 검증) import { verifyPipaCitation } from "./validator/verify-pipa-citation.js"; export const ALL_TOOLS: Tool[] = [ // W1.5 searchLaw, getLawText, intelligentLawSearch, getRelatedLaws, getAnnexes, // W2 — search primitives (admin rule + decisions + interpretations + english) searchAdminRule, searchPipcDecisions, searchConstitutionalDecisions, searchAdminAppeals, searchInterpretations, searchEnglishLaw, // W2 — get text primitives getAdminRuleText, getPipcDecisionText, getConstitutionalDecisionText, getAdminAppealText, getInterpretationText, getEnglishLawText, // W2 — comparison primitives compareAdminRuleOldNew, compareArticles, // W2 — temporal primitives getLawHistory, getHistoricalLaw, compareOldNew, getThreeTier, getArticleChangeHistory, getDelegatedLaws, getLawSystemTree, getIntelligentRelatedLaws, // W2 — terminology primitives getLegalTerm, getTermArticles, getLawAbbreviations, - fetchAll helper: calls the lawSearch.do API with target=lsAbrv, parses the XML response into AbbrItem objects using parseSearchXML and extractTag utilities.
async function fetchAll( client: LawApiClient, options: { stdDt?: string; endDt?: string } ): Promise<AbbrItem[]> { const extraParams: Record<string, string> = {}; if (options.stdDt) extraParams.stdDt = options.stdDt; if (options.endDt) extraParams.endDt = options.endDt; const xml = await client.fetchApi({ endpoint: "lawSearch.do", target: "lsAbrv", type: "XML", extraParams, timeoutMs: 60_000, // 응답 1.2MB+ 여유 }); const result = parseSearchXML<AbbrItem>( xml, "LawSearch", "law", (itemXml) => ({ 법령일련번호: extractTag(itemXml, "법령일련번호"), 법령명한글: extractTag(itemXml, "법령명한글"), 법령약칭명: extractTag(itemXml, "법령약칭명"), 법령ID: extractTag(itemXml, "법령ID"), 시행일자: extractTag(itemXml, "시행일자"), 공포일자: extractTag(itemXml, "공포일자"), 소관부처명: extractTag(itemXml, "소관부처명"), 법령구분명: extractTag(itemXml, "법령구분명"), 현행연혁코드: extractTag(itemXml, "현행연혁코드"), 등록일: extractTag(itemXml, "등록일"), }) ); return result.items; } - matches helper: filters AbbrItem by checking if the query matches either the full law name or abbreviation (exact or partial match).
function matches(item: AbbrItem, query: string, exact: boolean): boolean { const q = query.trim(); if (q.length === 0) return true; const name = item.법령명한글; const abbr = item.법령약칭명; if (exact) { return name === q || abbr === q; } return name.includes(q) || abbr.includes(q); }