Model or dataset
chrisryugj/korean-law-mcp avatar
chrisryugj/korean-law-mcp

korean-law-mcp: A Korean Law MCP Server That Refuses to Say "Not Found" Too Early

법제처 국가법령정보를 LLM에서 바로 조회하는 MCP 서버. 법령·판례·조례 검색과 인용 검증 | MCP server for Korean law — search statutes, precedents, and ordinances, and verify citations

2,611 stars531 forksTypeScriptMIT

At a glance

What is it?
korean-law-mcp wraps 42 Korean Ministry of Government Legislation APIs into 10 MCP tools for statute, precedent, ordinance and treaty lookup, plus citation verification. Its design bet is that a false negative is worse than a slow answer.
Who is it for?
Adopt korean-law-mcp if you are building a Korean legal assistant and need statute, precedent and ordinance lookup with citation checking rather than free-form model recall. Do not adopt it if your questions are about US or EU law, or if you cannot obtain a LAW_OC key from law.go.kr and are unwilling to depend on the shared public server's rate limit.
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 2 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 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem korean-law-mcp targets: a confident answer about a statute that does not exist

Large language models answer legal questions fluently whether or not the cited article exists. For Korean law this is expensive, because the citation format is precise: a statute name, an article number, sometimes a paragraph number, sometimes an attached table. korean-law-mcp exists to put a retrieval layer between the model and the Ministry of Government Legislation (법제처) data, so that a citation can be checked against the actual statute and precedent database rather than generated.

The repository describes the worst failure mode in its own words: the server's most damaging outcome is not slowness but declaring a real statute or precedent nonexistent. Several release notes are organized around that single concern. v4.12.0 states that empty responses immediately after a transient 503 or network error used to be treated as proof of nonexistence, and that the judgment was replaced with one based on observed history. The same release says the HTML fallback path used to label real precedents as [NOT_FOUND] when the upstream returned a maintenance or anti-bot page, and that the server now distinguishes a broken upstream from missing data.

That framing tells you who this is for. It is for engineers and analysts wiring an assistant into Korean legal research, where a wrong negative sends a user away with the belief that no such rule exists. It is not a general legal reasoning engine, and it does not draft documents.

Ten tools over 42 upstream APIs, and what the tool surface actually contains

The package description in package.json maps 42 법제처 APIs onto 9 MCP tools, while the README headline says 10. The discrepancy is worth noting rather than smoothing over: the README's banner counts the citation verification and impact features alongside lookup tools, and the package.json description enumerates legal_research with 8 tasks, legal_analysis (citation verification, precedent survival, applicable law at the time of the act, impact graph), time_travel for point-in-time comparison, action_plan for five-step situational guidance, and nts for National Tax Service interpretations.

The architecture is a Node process that speaks the Model Context Protocol over stdio or HTTP, and also ships a CLI binary. package.json declares two binaries: korean-law-mcp pointing at build/index.js and korean-law pointing at build/cli.js. The server talks to 법제처 Open API endpoints using a key, and several tools are chained: a research task may fan out into multiple upstream calls.

Two mechanisms from the changelog are worth understanding before you deploy. First, a request-level execution budget: v4.11.0 introduced MCP_MAX_UPSTREAM_REQUESTS with a default of 48, and retries and anti-bot hops are deducted from the same budget, so a single client request cannot amplify into an unbounded number of upstream calls. Second, a chain deadline: MCP_CHAIN_DEADLINE_MS defaults to 45 seconds, and when it expires the server assembles whatever branches it received into a partial result and leaves markers for the missing parts instead of letting the client's own 60-second timeout discard everything.

The partial-result behavior is a deliberate trade. You get an answer with visible holes rather than no answer, which means downstream code has to handle incomplete results rather than assume a complete one.

Installing korean-law-mcp and running a first statute lookup

The package is published on npm as korean-law-mcp, and the repository also provides a Dockerfile for remote deployment. The one thing you must supply is a 법제처 Open API key, exposed as the LAW_OC environment variable. The .env.example points at https://www.law.go.kr/DRF/lawService.do for issuance and notes that LAW_API_PROTOCOL defaults to https, with http available for closed networks or certificate problems.

For a local stdio setup, install the package and confirm the CLI responds before wiring it into a client:

bash
npm install -g korean-law-mcp
korean-law "광진구 주차장 조례"

The second line invokes the CLI binary. The README's ordinance radar example shows this exact form, where the quoted string is the query and the tool routes it to ordinance_radar. If the key is missing or rejected, the upstream call fails and you will see an error rather than a result.

If you prefer to run the built server directly from a checkout, the scripts in package.json are the ones to use. The build runs a clean step first, and the start script launches the compiled entry point:

bash
npm run build
npm start

For a container deployment, the Dockerfile builds with npm ci --ignore-scripts --omit=optional, copies src and scripts, runs the build, then prunes to production dependencies and runs verify:annex-runtime. The runtime stage creates an unprivileged appuser, exposes port 3000, and starts the server in SSE mode:

bash
CMD ["node", "build/index.js", "--mode", "sse", "--port", "3000"]

The Dockerfile sets MCP_HTTP_HOST to 0.0.0.0 and comments that the container is explicitly a remote deployment unit, so startup should fail unless the operator supplies MCP_AUTH_TOKEN or deliberately opts into MCP_ALLOW_UNAUTHENTICATED_REMOTE. That is a deliberate inversion of the library default, which v4.11.0 changed from 0.0.0.0 to 127.0.0.1.

Citation verification is the feature that justifies the rest

verify_citations expanded from statutes to two axes, statutes and precedents, and the changelog is explicit that it distinguishes impossible citations from unverified ones. The distinction matters more than it sounds. If a tool reports NOT_FOUND for something it merely could not parse, a downstream hallucination gate reports a false positive against a correct citation, and the gate becomes noise.

v4.9.0 documents three notations that caused silent skips, which is the failure mode where verification did not run at all but the output still looked like a pass. The first was the standard Korean citation form 「법령명」 제N조: the law name regex anchored on end-of-string, but the closing corner bracket remained at the end of the lookback window, so extraction failed. The second was middle-dot variation: the official statute name uses the Hangul middle dot U+318D while real documents and model output usually use the Latin U+00B7, so the same law failed to match itself. The changelog says five variants are now absorbed while the guard against unrelated laws such as 민법 matching 난민법 is retained. The third was the standard 「A법」 제N조 및 같은 법 시행규칙 제M조 construction, where the antecedent law name was not carried forward. The fix carries the preceding name forward but deliberately does not carry it across a blank line or paragraph break, on the reasoning that judging against an unrelated statute is a worse error than reporting an unclear name.

That last rule is the clearest statement of the project's priorities. When there are zero candidates, the tool reports an unclear law name rather than searching and stamping a zero-result search as NOT_FOUND. The README's own before-and-after block shows a text where the same citation set first produced a warning and later produced verified hits plus a NOT_FOUND for a fabricated 제999조 with the valid range printed.

Where korean-law-mcp is the wrong tool

The coverage boundary is Korean national law as served by 법제처, plus National Tax Service interpretations and local ordinances. If your question is about US federal procedure, EU regulation or a contract governed by non-Korean law, nothing in this server helps, and the search questions that ask whether South Korean law resembles US law are not something the tool answers either. It retrieves and verifies; it does not compare legal systems.

The second boundary is the key. Without your own LAW_OC key you are dependent on the shared public server at mcp.gomdori.app/law, which v4.9.7 describes as a global quota shared by all keyless users. That release replaced a fixed-window limiter with a token bucket in src/lib/rate-limit.ts, added a Retry-After header, and introduced FALLBACK_DAILY_CAP to bound daily total usage while leaving it disabled by default. The public server's per-minute setting was relaxed from 30 to 120 with a daily cap of 43,200. The changelog states that before this change, 2 of 3 keyless production requests were immediately rate limited. A token bucket smooths bursts, but it does not create capacity for a production workload. If you are building something with real traffic, issue a key.

The third boundary is operational. The HTTP binding default moved to 127.0.0.1 and TRUST_PROXY to false in v4.11.0, both listed as breaking changes. If you had a reverse proxy in front of the server and did not set TRUST_PROXY, client IP handling changes. The allowed values are integers from 1 to 10. get_batch_articles also gained input caps: 20 statutes, 50 articles per statute, 100 per request. Any pipeline that batched more than that will now be rejected rather than truncated.

How it differs from pointing a model at the law.go.kr API directly

The obvious alternative is calling the 법제처 Open API yourself and pasting results into a prompt. That gives you full control over which endpoint is hit and how the response is shaped, and it avoids a dependency on a package that ships breaking changes in minor versions. The cost is that you inherit every problem the changelog describes: transient 503s that look like empty results, maintenance pages that parse into nothing, pagination that stops early, and citation strings that do not match the official statute name because of a middle dot.

A second alternative, and the one the project positions against, is relying on the model's own knowledge of Korean law. That is cheaper by every measure until a citation is wrong. The repository's framing is that retrieval plus verification is the point, and features like impact_map comparing both article number and statute name address a specific class of error where 형법 제1조 and 군형법 제1조 were conflated. The changelog notes that ambiguous judgments are held rather than discarded, including citations to former statutes under constitutional review.

The trade you accept with korean-law-mcp is a moving target. Releases v4.12.2, v4.12.3 and v4.12.5 all landed within roughly two weeks of each other, two of them repairing tools that had stopped working against upstream HTML changes. That is a real maintenance signal: the project tracks a government API surface that changes without notice, and your pinning strategy has to account for it.

Licence, upgrade cost, and what to pin

The licence is MIT, declared in package.json and shown as a badge in the README. There is also a NOTICE file in the repository root. MIT is permissive, so the practical question is not redistribution but the upstream data terms: the server calls 법제처 APIs under your own key, and the README links to open.law.go.kr for free issuance. Whether your use of that data is acceptable is a question for the data provider, not for this licence. Nothing here is legal advice.

Upgrade cost is dominated by the breaking changes the changelog calls out. v4.11.0 changed the HTTP bind default, the TRUST_PROXY default and its allowed value range, and added input caps to get_batch_articles. v4.12.0 changed two user-visible formats: dates were unified from the 2024.1.5. form to 2024.01.05 with empty effective dates rendered as N/A, and discover_tools responses moved to a pointer and ranking format with a stated 65 percent reduction in response size. If you parse tool output, those two changes will break your parser before anything else does.

The repository ships a gc script that chains typecheck, knip dead-code detection, the vitest suite and the build, and a prepack hook that runs the build plus verify:package. The v4.12.0 notes state the test count moved from 196 to 701. For a server whose correctness is about distinguishing absent data from unreachable data, that suite is the part to read before you trust a version bump.

Editorial conclusion

Adopt korean-law-mcp if you are building a Korean legal assistant and need statute, precedent and ordinance lookup with citation checking rather than free-form model recall. Do not adopt it if your questions are about US or EU law, or if you cannot obtain a LAW_OC key from law.go.kr and are unwilling to depend on the shared public server's rate limit. Before rolling it out, verify that your citation formats resolve under the narrow notation rules the changelog describes, and check whether your deployment binds HTTP to 127.0.0.1 by default or sets MCP_AUTH_TOKEN explicitly.

Frequently asked questions

What does MCP stand for in the context of law?

MCP here is the Model Context Protocol, the interface korean-law-mcp implements so an AI assistant can call law lookup tools. The repository badges MCP 1.27 and depends on @modelcontextprotocol/sdk.

Is South Korean law similar to US law?

korean-law-mcp retrieves and verifies Korean statutes, precedents and ordinances from 법제처 data. It does not compare legal systems, so it will not answer this.

What is the punishment for crime in South Korea?

The server can retrieve the relevant statutes and precedents from the 법제처 database, but it does not summarize penalties on its own. The README's example of 형법 제1조 versus 군형법 제1조 is about disambiguating article numbers, not sentencing.

Is South Korea's law strict?

korean-law-mcp is a retrieval and citation verification layer over 법제처 APIs. The repository makes no claim about the severity of Korean law, so this is outside what the tool addresses.

Official sources

  1. chrisryugj/korean-law-mcp on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/chrisryugj-korean-law-mcp.svg)](https://hysenlabs.com/projects/chrisryugj-korean-law-mcp)