search_ordinance
Search Korean local ordinances and regulations by keyword. Specify region or subject to find relevant rules.
Instructions
[자치법규] 조례/규칙 검색. 지역명 포함 권장.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | 검색할 자치법규명 (예: '서울', '환경') | |
| display | Yes | 페이지당 결과 개수 (기본값: 20, 최대: 100) | |
| apiKey | No | 법제처 Open API 인증키(OC). 사용자가 제공한 경우 전달 |
Implementation Reference
- src/tools/ordinance-search.ts:19-119 (handler)The main handler function for the search_ordinance tool. Normalizes the query, calls the API, parses the XML response, and if no results, retries with expanded queries. Formats results as text output.
export async function searchOrdinance( apiClient: LawApiClient, input: SearchOrdinanceInput ): Promise<{ content: Array<{ type: string, text: string }>, isError?: boolean }> { try { // 검색어 정규화 (약칭 해결, 오타 보정) const normalizedQuery = normalizeLawSearchText(input.query) // 1차 검색 시도 let xmlText = await apiClient.searchOrdinance({ query: normalizedQuery, display: input.display || 20, apiKey: input.apiKey }) // parseSearchXML 사용 (rootTag: OrdinSearch, itemTag: law) let parsed = parseSearchXML( xmlText, "OrdinSearch", "law", (content) => ({ 자치법규일련번호: extractTag(content, "자치법규일련번호"), 자치법규명: extractTag(content, "자치법규명"), 지자체기관명: extractTag(content, "지자체기관명"), 공포일자: extractTag(content, "공포일자"), 시행일자: extractTag(content, "시행일자"), 자치법규상세링크: extractTag(content, "자치법규상세링크"), }) ) let totalCount = parsed.totalCnt let usedQuery = normalizedQuery // 검색 결과 없으면 확장 쿼리로 자동 재시도 if (totalCount === 0) { const { expanded } = expandOrdinanceQuery(input.query) for (const expandedQuery of expanded) { xmlText = await apiClient.searchOrdinance({ query: expandedQuery, display: input.display || 20, apiKey: input.apiKey }) parsed = parseSearchXML( xmlText, "OrdinSearch", "law", (content) => ({ 자치법규일련번호: extractTag(content, "자치법규일련번호"), 자치법규명: extractTag(content, "자치법규명"), 지자체기관명: extractTag(content, "지자체기관명"), 공포일자: extractTag(content, "공포일자"), 시행일자: extractTag(content, "시행일자"), 자치법규상세링크: extractTag(content, "자치법규상세링크"), }) ) totalCount = parsed.totalCnt if (totalCount > 0) { usedQuery = expandedQuery break } } } const currentPage = parsed.page const ordinances = parsed.items if (totalCount === 0) { // 확장 검색도 실패한 경우, 시도한 쿼리들 안내 const { expanded } = expandOrdinanceQuery(input.query) const triedQueries = [normalizedQuery, ...expanded].slice(0, 3).join("', '") return { content: [{ type: "text", text: `'${input.query}' 검색 결과가 없습니다.\n\n시도한 검색어: '${triedQueries}'\n\n💡 다른 키워드로 다시 검색해보세요.` }] } } let output = `자치법규 검색 결과 (총 ${totalCount}건, ${currentPage}페이지):\n\n` for (const ordin of ordinances) { output += `[${ordin.자치법규일련번호}] ${ordin.자치법규명}\n` output += ` 지자체: ${ordin.지자체기관명 || "N/A"}\n` output += ` 공포일: ${ordin.공포일자 || "N/A"}\n` output += ` 시행일: ${ordin.시행일자 || "N/A"}\n` if (ordin.자치법규상세링크) { output += ` 링크: ${ordin.자치법규상세링크}\n` } output += `\n` } output += `\n💡 전문을 조회하려면 get_ordinance Tool을 사용하세요.\n` return { content: [{ type: "text", text: output }] } } catch (error) { return formatToolError(error, "search_ordinance") } } - src/tools/ordinance-search.ts:11-15 (schema)Zod schema for search_ordinance inputs: query (string), display (number, 1-100, default 20), apiKey (optional string).
export const SearchOrdinanceSchema = z.object({ query: z.string().describe("검색할 자치법규명 (예: '서울', '환경')"), display: z.number().min(1).max(100).default(20).describe("페이지당 결과 개수 (기본값: 20, 최대: 100)"), apiKey: z.string().optional().describe("법제처 Open API 인증키(OC). 사용자가 제공한 경우 전달") }) - src/tool-registry.ts:155-161 (registration)Registration of the search_ordinance tool in the tool registry with name, description, schema, and handler.
// === 자치법규 === { name: "search_ordinance", description: "[자치법규] 조례/규칙 검색. 지역명 포함 권장.", schema: SearchOrdinanceSchema, handler: searchOrdinance }, - src/lib/api-client.ts:302-317 (helper)API client method that makes the actual HTTP request to the law search API with target=ordin for searching ordinances.
async searchOrdinance(params: { query: string display?: number apiKey?: string }): Promise<string> { const apiParams = new URLSearchParams({ target: "ordin", OC: this.getApiKey(params.apiKey), type: "XML", query: params.query, display: (params.display || 20).toString(), }) const url = `${LAW_API_BASE}/lawSearch.do?${apiParams.toString()}` return await this.fetchText(url, "searchOrdinance") } - src/lib/tool-chain-config.ts:76-80 (helper)Tool chain configuration linking search_ordinance to get_ordinance for detail lookups, using ordinSeq as the detail parameter.
search_ordinance: { detailTool: "get_ordinance", detailParam: "ordinSeq", idRegex: BRACKET_ID, },