법제처 국가법령정보를 LLM에서 바로 조회하는 MCP 서버. 법령·판례·조례 검색과 인용 검증 | MCP server for Korean law — search statutes, precedents, and ordinances, and verify citations
This report summarizes scanner evidence for chrisryugj/korean-law-mcp, a TypeScript project with 2,662 GitHub stars. SynthScan examined 57,338 lines of code across 349 source files, recording 164 pattern matches distributed across 7 syntactic categories. The legacy adjusted pattern signal is 6.3 (Moderate pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 90 finding(s).
Are imports declared and package/API names verified? 6 finding(s).
Are wrappers, guards, and repeated structures necessary? 111 finding(s).
Which changes need focused human review? 164 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 164 distinct pattern matches across 7 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | src/cli.ts | 36 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/cli.ts | 38 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/cli.ts | 186 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/cli.ts | 188 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/cli.ts | 387 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/cli.ts | 389 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/tools/verify-citations.budget.test.ts | 109 | // ── 예산 소진은 그 인용만의 실패다 (2026-10-01 감사 재현) ────────────────────── | COMMENT |
| MEDIUM | src/tools/history-review.test.ts | 133 | // ── 행정규칙 ──────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | src/tools/document-analysis.ts | 19 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | src/tools/document-analysis.ts | 21 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | src/tools/document-analysis.ts | 30 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | src/tools/document-analysis.ts | 32 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/tools/annex-select.test.ts | 65 | // ─── 별표번호 6자리 코드 체계 (실측 확정) ────────────────── | COMMENT |
| MEDIUM | src/tools/search.test.ts | 31 | // ── display 하한 (#89) ──────────────────────────────── | COMMENT |
| MEDIUM | src/tools/search.test.ts | 31 | // ── display 하한 (#89) ──────────────────────────────── | COMMENT |
| MEDIUM | src/tools/search.test.ts | 86 | // ── 옛 법령명 안내 (v4.15.0) ──────────────────────────── | COMMENT |
| MEDIUM | src/tools/annex-select.ts | 313 | // ─── query 필터 (#94) ───────────────────────────────── | COMMENT |
| MEDIUM | src/tools/annex-select.ts | 313 | // ─── query 필터 (#94) ───────────────────────────────── | COMMENT |
| MEDIUM | src/tools/annex-select.ts | 334 | // ─── 조문 맥락 (#133) ───────────────────────────────── | COMMENT |
| MEDIUM | src/tools/annex-select.ts | 334 | // ─── 조문 맥락 (#133) ───────────────────────────────── | COMMENT |
| MEDIUM | src/tools/annex.ts | 237 | // ─── 별표 텍스트 추출 ───────────────────────────────── | COMMENT |
| MEDIUM | src/tools/annex.ts | 398 | // ─── 목록 포맷 (기존 동작) ──────────────────────────── | COMMENT |
| MEDIUM | src/tools/applicable-law.staggered.test.ts | 7 | // ── 라이브 캡처 픽스처 (2026-07-19, OC만 test로 마스킹) ────────────────────── | COMMENT |
| MEDIUM | src/tools/applicable-law.staggered.test.ts | 19 | // ── 포맷 일치 스텁 헬퍼 ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/tools/scenarios/time-travel-diff.ts | 132 | // ─── 신구대조 발췌 (#97) ────────────────────────────── | COMMENT |
| MEDIUM | src/tools/scenarios/time-travel-diff.ts | 132 | // ─── 신구대조 발췌 (#97) ────────────────────────────── | COMMENT |
| MEDIUM | src/tools/scenarios/time-travel-diff.test.ts | 177 | // ─── 통합 배치 이음새 회귀 (지적 3·4) ──────────────────── | COMMENT |
| MEDIUM | src/server/http-server.ts | 95 | // ── Origin 검증 (DNS rebinding 방어) ────────────────────────────────────── | COMMENT |
| MEDIUM | src/server/http-server.ts | 140 | // ── 접근 인증 (MCP_AUTH_TOKEN 설정 시에만 활성) ──────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-executor.ts | 16 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-executor.ts | 18 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-executor.ts | 30 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-executor.ts | 32 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-executor.ts | 65 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-executor.ts | 67 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-executor.ts | 223 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-executor.ts | 225 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 7 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 9 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 109 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 111 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 136 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 138 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 320 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 322 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 351 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 353 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 428 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 430 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 514 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/risk-rules.ts | 516 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/tool-discovery.ts | 153 | // ── 무매칭일 때 ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-format.ts | 11 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-format.ts | 13 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-format.ts | 36 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-format.ts | 38 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-format.ts | 69 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-format.ts | 71 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-format.ts | 118 | // ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/lib/cli-format.ts | 120 | // ──────────────────────────────────────── | COMMENT |
| 8 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/tools/constitutional-decisions.ts | 27 | export async function searchConstitutionalDecisions( | CODE |
| LOW | src/tools/constitutional-decisions.ts | 92 | export async function getConstitutionalDecisionText( | CODE |
| LOW | src/tools/external-links.ts | 195 | function generateInterpretationLinks(interpretationId: string): string { | CODE |
| LOW | src/tools/impact-map.ts | 54 | async function searchPrecedentsWithoutFallback( | CODE |
| LOW | src/tools/unified-decisions.ts | 162 | async function searchPrecedentDecisionsWithText( | CODE |
| LOW | src/tools/tax-tribunal-decisions.ts | 24 | export async function searchTaxTribunalDecisions( | CODE |
| LOW | src/tools/tax-tribunal-decisions.ts | 94 | export async function getTaxTribunalDecisionText( | CODE |
| LOW | src/tools/applicable-law.ts | 102 | function extractTransitionExcerpts( | CODE |
| LOW | src/tools/precedents.ts | 68 | export function renderPrecedentSearchResult(result: StructuredPrecedentSearchResult): string { | CODE |
| LOW | src/tools/precedents.ts | 265 | function normalizeTaxlawBodyCandidate(value: unknown): string { | CODE |
| LOW | src/tools/precedents.ts | 440 | async function fetchHtmlFallbackPrecedent( | CODE |
| LOW | src/tools/annex-merge-marker.test.ts | 21 | function clientWithFailingCanonical(): LawApiClient { | CODE |
| LOW | src/tools/verify-citations.ts | 108 | export function lawNameFromCitationContext(lookbackRaw: string): string | undefined { | CODE |
| LOW | src/tools/verify-citations.ts | 396 | async function identifiedByFirstCandidate(apiClient: LawApiClient, lawName: string, apiKey?: string): Promise<boolean> { | CODE |
| LOW | src/tools/search-detail-chain.ts | 149 | export async function fetchCombinedSearchDetailChain( | CODE |
| LOW | src/tools/institutional-rules.ts | 181 | export async function searchPublicInstitutionRules(apiClient: LawApiClient, args: SearchPublicInstitutionRulesInput) { | CODE |
| LOW | src/tools/institutional-rules.ts | 187 | export async function getPublicInstitutionRuleText(apiClient: LawApiClient, args: GetPublicInstitutionRuleTextInput) { | CODE |
| LOW | src/tools/precedent-evidence.ts | 143 | export async function validatePrecedentSearchResult( | CODE |
| LOW | src/tools/precedent-search-core.ts | 285 | export async function searchPrecedentsStructured( | CODE |
| LOW | src/tools/compact-query-planner.ts | 167 | function normalizeOriginalPrecedentQuery(query: string): string { | CODE |
| LOW | src/tools/compact-query-planner.ts | 219 | function extractedOriginalKeywords(originalQuery: string): string[] { | CODE |
| LOW | src/tools/compact-query-planner.ts | 375 | function scoreAiLawArticleCandidate( | CODE |
| LOW | src/tools/compact-query-planner.ts | 535 | function addOriginalQueryCandidate( | CODE |
| LOW | src/tools/compact-query-planner.ts | 563 | function addOriginalKeywordCandidates( | CODE |
| LOW | src/tools/compact-query-planner.ts | 668 | function addDocumentHintCandidates( | CODE |
| LOW | src/tools/compact-query-planner.ts | 691 | function addStructuredAiLawArticleCandidates( | CODE |
| LOW | src/tools/special-admin-appeals.ts | 134 | export async function searchAppealReviewDecisions(apiClient: LawApiClient, args: SearchAppealReviewDecisionsInput) { | CODE |
| LOW | src/tools/special-admin-appeals.ts | 141 | export async function getAppealReviewDecisionText(apiClient: LawApiClient, args: GetAppealReviewDecisionTextInput) { | CODE |
| LOW | src/tools/chains.ts | 72 | function emptyStructuredPrecedentResult(args: SearchPrecedentsInput): StructuredPrecedentSearchResult { | CODE |
| LOW | src/tools/chains.ts | 91 | async function safeSearchPrecedentsStructured( | CODE |
| LOW | src/tools/chains.ts | 154 | export function shouldFetchAnnexSeparately( | CODE |
| LOW | src/tools/chains.ts | 257 | async function fetchPrecedentDetailForChain( | CODE |
| LOW | src/tools/chains.ts | 273 | function combineStructuredPrecedentResults( | CODE |
| LOW | src/tools/chains.ts | 349 | async function precedentSearchThenDetail( | CODE |
| LOW | src/tools/customs-interpretations.ts | 31 | export async function searchCustomsInterpretations( | CODE |
| LOW | src/tools/customs-interpretations.ts | 127 | export async function getCustomsInterpretationText( | CODE |
| LOW | src/server/http-config.ts | 28 | function parseRemoteUnauthenticatedOverride(raw: string | undefined): boolean { | CODE |
| LOW | src/lib/citation-content-matcher.ts | 105 | function longestCommonSubstringLen(a: string, b: string): number { | CODE |
| LOW | src/lib/external-https-proxy.ts | 29 | export function getExternalHttpsProxyConfig(): ExternalHttpsProxyConfig | null { | CODE |
| LOW | src/lib/historical-utils.ts | 82 | export async function fetchHistoricalVersionsFull( | CODE |
| LOW | src/lib/historical-utils.ts | 222 | export async function fetchHistoricalVersionsRaw( | CODE |
| LOW | src/lib/three-tier-parser.ts | 39 | function stripLeadingJoHeaderFromContent(content: string): string { | CODE |
| LOW | src/lib/abolished-laws.ts | 211 | async function buildAbolishedAdminRuleNote( | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | docs/DEVELOPMENT.md | 98 | ### Step 1: 도구 파일 생성 | COMMENT |
| LOW | docs/DEVELOPMENT.md | 129 | ### Step 2: tool-registry.ts에 등록 | COMMENT |
| LOW | docs/DEVELOPMENT.md | 145 | ### Step 3: 빌드 & 테스트 | COMMENT |
| LOW | src/setup.ts | 272 | // Step 1: API 키 | COMMENT |
| LOW | src/setup.ts | 285 | // Step 2: 클라이언트 선택 | COMMENT |
| LOW | src/setup.ts | 314 | // Step 3: 설정 파일 업데이트 | COMMENT |
| LOW⚡ | src/tools/chains.ts | 710 | // Step 1: 신구대조표 | COMMENT |
| LOW⚡ | src/tools/chains.ts | 713 | // Step 2: 조문별 개정 이력 | COMMENT |
| LOW⚡ | src/tools/chains.ts | 991 | // Step 2: 3단 비교 (절차 체계 파악) | COMMENT |
| LOW⚡ | src/tools/chains.ts | 993 | // Step 3: 별표(수수료/과태료) + 서식(신청서) 병렬 | COMMENT |
| LOW | src/tools/chains.ts | 749 | // Step 1: 상위 법령 확인 (조례/지역명은 법령 검색에서 제거) | COMMENT |
| LOW | src/tools/chains.ts | 763 | // Step 2: 조례 검색 — "조례"/"규칙" 제거 (이미 조례 DB에서 검색하므로) | COMMENT |
| LOW | src/tools/chains.ts | 784 | // Step 3: 상위 1건 전문 자동 조회 | COMMENT |
| LOW | src/tools/chains.ts | 844 | // Step 1: AI 검색 + 법령 검색 + 해석례를 병렬 실행하고, 판례는 AI 구조화 신호를 받은 뒤 공통 core로 검색한다. | COMMENT |
| LOW | src/tools/chains.ts | 978 | // Step 1: 법령 검색 | COMMENT |
| LOW | src/tools/chains.ts | 1016 | // Step 4: AI 검색으로 보완 (절차 상세) | COMMENT |
| LOW | src/tools/chains.ts | 1054 | // Step 1: analyze_document 로 리스크 분석 | COMMENT |
| LOW | src/tools/chains.ts | 1066 | // Step 2: 분석 결과에서 searchHints 추출 → 병렬로 법령+판례 검색 | COMMENT |
| LOW | src/tools/scenarios/time-travel.ts | 90 | // Step 1: 연혁 목록 → 두 시점 MST 결정 (페이징으로 전체 회수) | COMMENT |
| LOW | src/tools/scenarios/time-travel.ts | 149 | // Step 2: 두 시점 본문 raw 조회 | COMMENT |
| LOW⚡ | src/tools/scenarios/time-travel.ts | 177 | // Step 3: diff | COMMENT |
| LOW⚡ | src/tools/scenarios/time-travel.ts | 180 | // Step 4: 출력 | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/setup.ts | 272 | // Step 1: API 키 | COMMENT |
| LOW | src/setup.ts | 285 | // Step 2: 클라이언트 선택 | COMMENT |
| LOW | src/setup.ts | 314 | // Step 3: 설정 파일 업데이트 | COMMENT |
| LOW⚡ | src/tools/chains.ts | 710 | // Step 1: 신구대조표 | COMMENT |
| LOW⚡ | src/tools/chains.ts | 713 | // Step 2: 조문별 개정 이력 | COMMENT |
| LOW⚡ | src/tools/chains.ts | 991 | // Step 2: 3단 비교 (절차 체계 파악) | COMMENT |
| LOW⚡ | src/tools/chains.ts | 993 | // Step 3: 별표(수수료/과태료) + 서식(신청서) 병렬 | COMMENT |
| LOW | src/tools/chains.ts | 749 | // Step 1: 상위 법령 확인 (조례/지역명은 법령 검색에서 제거) | COMMENT |
| LOW | src/tools/chains.ts | 763 | // Step 2: 조례 검색 — "조례"/"규칙" 제거 (이미 조례 DB에서 검색하므로) | COMMENT |
| LOW | src/tools/chains.ts | 784 | // Step 3: 상위 1건 전문 자동 조회 | COMMENT |
| LOW | src/tools/chains.ts | 844 | // Step 1: AI 검색 + 법령 검색 + 해석례를 병렬 실행하고, 판례는 AI 구조화 신호를 받은 뒤 공통 core로 검색한다. | COMMENT |
| LOW | src/tools/chains.ts | 978 | // Step 1: 법령 검색 | COMMENT |
| LOW | src/tools/chains.ts | 1016 | // Step 4: AI 검색으로 보완 (절차 상세) | COMMENT |
| LOW | src/tools/chains.ts | 1054 | // Step 1: analyze_document 로 리스크 분석 | COMMENT |
| LOW | src/tools/chains.ts | 1066 | // Step 2: 분석 결과에서 searchHints 추출 → 병렬로 법령+판례 검색 | COMMENT |
| LOW | src/tools/scenarios/time-travel.ts | 90 | // Step 1: 연혁 목록 → 두 시점 MST 결정 (페이징으로 전체 회수) | COMMENT |
| LOW | src/tools/scenarios/time-travel.ts | 149 | // Step 2: 두 시점 본문 raw 조회 | COMMENT |
| LOW⚡ | src/tools/scenarios/time-travel.ts | 177 | // Step 3: diff | COMMENT |
| LOW⚡ | src/tools/scenarios/time-travel.ts | 180 | // Step 4: 출력 | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | README-EN.md | 421 | "LAW_OC": "your-api-key" | CODE |
| HIGH | README-EN.md | 450 | "https://mcp.gomdori.app/law?oc=your-api-key" | CODE |
| HIGH | README-EN.md | 463 | "url": "https://mcp.gomdori.app/law?oc=your-api-key" | CODE |
| HIGH | README-EN.md | 487 | export LAW_OC=your-api-key | CODE |
| HIGH | README-EN.md | 501 | docker run -e LAW_OC=your-api-key -e MCP_HTTP_HOST=0.0.0.0 \ | CODE |
| HIGH | docs/DEVELOPMENT.md | 22 | LAW_OC=your-api-key node build/index.js | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | docs/FTC-RAG-INTEGRATION.md | 1 | # 공정위 결정문 — 로컬 LLM RAG 결합 가이드 | COMMENT |
| MEDIUM | docs/FTC-RAG-INTEGRATION.md | 9 | ### 경로 A: 구조화 텍스트 (`get_decision_text`) ← RAG 메인 | COMMENT |
| MEDIUM | docs/FTC-RAG-INTEGRATION.md | 81 | ## 3. RAG 인덱싱 — 청킹 전략 | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/tools/verify-citations.ts | 61 | ) | COMMENT |
| LOW | src/tools/knowledge-base.ts | 1 | import { z } from "zod" | COMMENT |
| LOW | src/lib/route-patterns.ts | 181 | // "XX법 별표", "XX령 서식" 등 법령명이 함께 있는 경우만 매칭. | COMMENT |