korean-law-mcp: A Korean Legal Retrieval Server Built Around Citation Verification
법제처 국가법령정보를 LLM에서 바로 조회하는 MCP 서버. 법령·판례·조례 검색과 인용 검증 | MCP server for Korean law — search statutes, precedents, and ordinances, and verify citations
At a glance
- What is it?
- An MIT-licensed TypeScript MCP server that wraps 42 Korean Ministry of Government Legislation APIs into 10 tools, with citation verification and article-level impact mapping as its defining features. Its own changelog is the most honest source of information about where it breaks.
- Who is it for?
- Adopt this if you are building a Korean legal assistant and your failure mode of record is a confidently cited article that does not exist, because verify_citations and impact_map are the parts of the codebase that received the most corrective work. Do not adopt it if you need English-language legal sources, or if you cannot read the Korean changelog, since the release notes are where the real behaviour is documented.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The failure this server is actually built to prevent
The README states the design premise directly: the worst failure mode for this server is not slowness but asserting that a statute or precedent does not exist when it does. That framing shapes the whole tool surface. Korean legal research involves three separate retrieval problems (statutes, precedents, and local ordinances) plus a fourth problem that is not retrieval at all: checking whether a citation an LLM produced is real. The project treats the fourth as a first-class feature rather than a byproduct of search. It is aimed at people building Korean legal assistants, and at anyone piping statutory text into a model that will later quote article numbers back at a user. If your use case is general web search over Korean text, this is the wrong layer.
Forty-two upstream APIs behind ten tools
The headline claim in the README is 42 Ministry of Government Legislation APIs compressed into 10 tools. The categories listed are statutes, precedents, administrative rules, local ordinances, treaties, and interpretive documents including National Tax Service interpretations. Compression matters here because MCP clients pay for tool definitions in context. The v4.12.0 notes describe a change to discover_tools that cut its response by 65 percent while keeping the correct answer in 10 out of 10 cases, which suggests the project treats tool-discovery output as a token budget problem, not just a routing problem. The server is published on npm as korean-law-mcp and the README lists Claude Desktop, Cursor, Windsurf, Zed, and Claude.ai as supported clients. There is also a CLI, so the same code paths can be driven from a terminal.
How citation verification separates absence from unavailability
The interesting mechanism is not search, it is the distinction between a citation that cannot exist and one that the server could not confirm. The v4.12.0 notes describe replacing a rule that treated a single empty response after a transient 503 or network error as proof of non-existence, and blocking an HTML fallback path that would label a real precedent as NOT_FOUND when the upstream returned a maintenance or anti-bot page. The v4.9.0 notes go further and name the failure they consider most dangerous: not a failed verification but a verification pass that never ran. If the law name cannot be extracted, article-level checking never starts, and the output shows only a warning symbol rather than a failure mark, which a reader interprets as a pass. Three notation cases were fixed for that reason, including the closing corner bracket in the standard Korean citation form, five variants of the middle dot character, and the same-law follow-on form where a trailing ordinance name inherits the preceding statute. The inheritance is deliberately dropped at a blank line, on the reasoning that attributing a citation to the wrong statute is worse than declining to attribute it.
Configuration keys and the breaking changes that matter
The README names several environment variables. MCP_CHAIN_DEADLINE_MS sets a 45-second deadline for chained consultation; when it expires the server assembles partial results from whatever branches returned and marks the missing positions rather than letting the whole call hit the MCP client timeout at 60 seconds. MCP_MAX_UPSTREAM_REQUESTS defaults to 48 and is described as a per-request execution budget that retries and anti-bot hops draw from, which bounds request amplification. FALLBACK_DAILY_CAP caps daily usage of the shared server key and defaults to 0, meaning disabled. TRUST_PROXY changed default from 1 to false in v4.11.0, and the HTTP bind default moved from 0.0.0.0 to 127.0.0.1. That last pair is a security-relevant default change, and the changelog points to a migration section. Users who supply their own Ministry key via an apikey header bypass the shared-key gate entirely; free issuance is at open.law.go.kr.
Rate limiting was rebuilt because the fixed window punished everyone
The v4.9.7 notes describe a concrete production problem: users of the public server without their own key were hitting 429 responses repeatedly, and the note states that in production measurement on 2026-08-12, two of three keyless requests were immediately rejected. The cause is structural rather than a tuning error. The fallback quota is a single global limit shared by all keyless users, and a fixed window means the first few callers in a window consume it, leaving everyone else blocked for the remainder. The replacement in src/lib/rate-limit.ts is a token bucket, which refills continuously and absorbs bursts while keeping the average rate. The response body now includes a retry-in-seconds message and a Retry-After header, and IP-limit responses were converted to JSON-RPC format because the previous plain error object could not be parsed by MCP clients. The public server's per-minute limit was relaxed from 30 to 120 with a daily cap of 43,200, which the notes describe as holding total volume constant while widening the burst.
Ordinance radar and the deliberate rejection of an upstream API
ordinance_radar addresses a recurring task for local government staff: checking whether a municipal ordinance still reflects its parent statutes after those statutes were amended. The implementation extracts the parent law, enforcement decree, and enforcement rule from the citations in article 1 (purpose) of the ordinance, then compares each parent's current effective date against the ordinance's effective date and flags the ones amended later. The README explains that it scans only the purpose article rather than the whole body, to avoid false alarms from unrelated citations buried in attached tables. It also states plainly that the Ministry's own linked-ordinance API (lnkOrd) was not used because its coverage is low, and that parsing the standard notation in the ordinance text was chosen instead. That is a useful disclosure: the project is willing to document a rejected upstream dependency rather than present the API as the obvious path.
Where it fails, and what it is not
Several limitations follow from the notes themselves. The v4.10.0 change added follow-on regulation guidance for repealed statutes, which implies that before that release a search for a repealed law returned zero results and stopped there, and that repealed citations were being misreported as hallucinations until v4.8.0 introduced a separate REPEALED status. The v4.7.4 notes describe a case where searching an informal short name returned 50 unrelated statutes because the upstream ignored the query, fixed with a short-name registry and a containment guard. The v4.12.2 and v4.12.3 releases are described as repairs to tools that had stopped working, one due to an HTML failure in a single-record lookup and one due to four knowledge-base tools referencing three targets that did not exist. A project whose recent releases are mostly restorations is a project whose surface area exceeds what a small maintainer set can continuously exercise. It is also strictly Korean-law scoped, and the documentation is primarily Korean, so teams without Korean-reading engineers will be working from the English README and the changelog alone.
The alternative: general retrieval plus a separate checker
The obvious alternative is to skip the MCP layer and call the Ministry's Open API directly from your application, then run your own verification step over model output. The difference is not coverage, since both reach the same upstream. It is where the verification logic lives. A direct integration gives you full control over retries, caching, and how you represent absence versus unavailability, and it lets you store results in whatever index you already operate. What you give up is the accumulated handling of the specific cases this project has documented: the middle-dot variants, the same-law follow-on form, repealed-versus-hallucinated separation, and the article-number plus law-name cross-check in impact_map that the notes say was added because a query about Criminal Act article 1 was pulling in Military Criminal Act article 1. Rebuilding that list from scratch means rediscovering each case from user reports, which is roughly how this project found them.
Maintenance cost and the MIT licence
The release cadence is high, with multiple versions in September 2026 alone, and the changelog documents both breaking changes and regressions, including a v4.11.0 regression fixed in v4.12.0 where a body over 2MiB caused a 300-second hang that became a 13ms explicit error. Pinning a version and reading the changelog before upgrading is the practical posture; the v4.11.0 notes list three breaking changes in one release. The licence is MIT, which permits commercial use and modification, but the server depends on Ministry APIs whose own terms and quotas are separate from the code licence, and the README points to open.law.go.kr for key issuance. Nothing here is legal advice, and the licence of the wrapper says nothing about the terms attached to the data it retrieves.
Editorial conclusion
Adopt this if you are building a Korean legal assistant and your failure mode of record is a confidently cited article that does not exist, because verify_citations and impact_map are the parts of the codebase that received the most corrective work. Do not adopt it if you need English-language legal sources, or if you cannot read the Korean changelog, since the release notes are where the real behaviour is documented. Before wiring it into a pipeline, run verify_citations against a document whose citations you have already checked by hand, and confirm that the output shows a per-citation line rather than a warning symbol, because a silently skipped verification pass is the one failure this project keeps returning to.
Community notes