search_all
Simultaneously search Korean laws, administrative rules, and local regulations. Use when the specific legal domain is unknown.
Instructions
[통합검색] 법령+행정규칙+자치법규 동시검색. 도메인 불명확 시 사용.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | 검색할 키워드 | |
| display | Yes | 각 유형별 최대 결과 개수 (기본값: 10) | |
| apiKey | No | 법제처 Open API 인증키(OC). 사용자가 제공한 경우 전달 |
Implementation Reference
- src/tools/search-all.ts:62-128 (handler)The main handler function for the search_all tool. Runs parallel searches across three legal domains (law, admin rule, ordinance) using Promise.all, consolidates results into a unified output with summarization via summarizeSearchResult, and returns formatted content. Falls back to error messages per category on failure.
export async function searchAll( apiClient: LawApiClient, input: SearchAllInput ): Promise<{ content: Array<{ type: string, text: string }>, isError?: boolean }> { try { const display = input.display || 10 // Parallel searches for all three types const [lawResult, adminRuleResult, ordinanceResult] = await Promise.all([ searchLaw(apiClient, { query: input.query, display, apiKey: input.apiKey }).catch(e => ({ content: [{ type: "text", text: `법령 검색 실패: ${e.message}` }], isError: true })), searchAdminRule(apiClient, { query: input.query, display, apiKey: input.apiKey }).catch(e => ({ content: [{ type: "text", text: `행정규칙 검색 실패: ${e.message}` }], isError: true })), searchOrdinance(apiClient, { query: input.query, display, apiKey: input.apiKey }).catch(e => ({ content: [{ type: "text", text: `자치법규 검색 실패: ${e.message}` }], isError: true })) ]) // 각 결과에서 핵심 정보(법령명, ID, MST)를 보존하면서 요약 const maxLinesPerCategory = Math.max(3, Math.min(15, Math.floor(30 / 3))) let output = `=== 통합 검색 결과: "${input.query}" ===\n\n` // Law results output += `[법령]\n` if (!lawResult.isError) { output += summarizeSearchResult(lawResult.content[0]?.text || "", maxLinesPerCategory) } else { output += `${lawResult.content[0]?.text || "검색 실패"}\n` } output += `\n` // Admin rule results output += `[행정규칙]\n` if (!adminRuleResult.isError) { output += summarizeSearchResult(adminRuleResult.content[0]?.text || "", maxLinesPerCategory) } else { output += `${adminRuleResult.content[0]?.text || "검색 실패"}\n` } output += `\n` // Ordinance results output += `[자치법규]\n` if (!ordinanceResult.isError) { output += summarizeSearchResult(ordinanceResult.content[0]?.text || "", maxLinesPerCategory) } else { output += `${ordinanceResult.content[0]?.text || "검색 실패"}\n` } output += `\n` output += `각 영역의 상세 검색: search_law / search_admin_rule / search_ordinance` return { content: [{ type: "text", text: truncateResponse(output) }] } } catch (error) { return formatToolError(error, "search_all") } } - src/tools/search-all.ts:14-18 (schema)Zod schema (SearchAllSchema) defining input validation for search_all: query (string, required), display (number 1-50, default 10), and optional apiKey.
export const SearchAllSchema = z.object({ query: z.string().describe("검색할 키워드"), display: z.number().min(1).max(50).default(10).describe("각 유형별 최대 결과 개수 (기본값: 10)"), apiKey: z.string().optional().describe("법제처 Open API 인증키(OC). 사용자가 제공한 경우 전달") }) - src/tool-registry.ts:117-121 (registration)Registration of the 'search_all' tool in the MCP tool registry with its name, description, schema (SearchAllSchema), and handler (searchAll function).
name: "search_all", description: "[통합검색] 법령+행정규칙+자치법규 동시검색. 도메인 불명확 시 사용.", schema: SearchAllSchema, handler: searchAll }, - src/tool-registry.ts:26-26 (registration)Import of searchAll and SearchAllSchema from the search-all.ts module into the tool registry.
import { searchAll, SearchAllSchema } from "./tools/search-all.js" - src/tools/search-all.ts:26-60 (helper)Helper function summarizeSearchResult that preserves key metadata (law name, ID, MST) from search results while truncating to a reasonable number of items for display.
function summarizeSearchResult(text: string, maxItems: number): string { const lines = text.split('\n') // "N. 법령명" 패턴으로 항목 시작점 식별 const itemStarts: number[] = [] for (let i = 0; i < lines.length; i++) { if (/^\d+\.\s/.test(lines[i])) { itemStarts.push(i) } } if (itemStarts.length === 0) { // 항목 패턴이 없으면 첫 줄(총건수 등) + 제한된 줄 반환 return lines.slice(0, maxItems * 3).join('\n') + '\n' } // 헤더(첫 항목 전 텍스트) const header = itemStarts[0] > 0 ? lines.slice(0, itemStarts[0]).join('\n').trim() + '\n' : '' // 각 항목을 통째로 유지 (법령명 + ID + MST 등 메타데이터 보존) const items: string[] = [] const limit = Math.min(itemStarts.length, maxItems) for (let i = 0; i < limit; i++) { const start = itemStarts[i] const end = i + 1 < itemStarts.length ? itemStarts[i + 1] : lines.length items.push(lines.slice(start, end).join('\n').trimEnd()) } let result = header + items.join('\n') + '\n' if (itemStarts.length > limit) { result += `... 외 ${itemStarts.length - limit}건\n` } return result }