Skip to main content
Glama

๐ŸŒ Read this in other languages: English | ํ•œ๊ตญ์–ด (Korean)

MCP Python

LexLink is an MCP (Model Context Protocol) server that exposes the Korean National Law Information API (open.law.go.kr) to AI agents and LLM applications. It enables AI systems to search, retrieve, and analyze Korean legal information through standardized MCP tools.

Features

  • 26 MCP Tools for comprehensive Korean law information access

    • Search and retrieve Korean laws (effective date & announcement date)

    • Search and retrieve English-translated laws

    • Search and retrieve administrative rules (ํ–‰์ •๊ทœ์น™)

    • Query specific articles, paragraphs, and sub-items

    • Law-ordinance linkage (๋ฒ•๋ น-์ž์น˜๋ฒ•๊ทœ ์—ฐ๊ณ„)

    • Delegated law information (์œ„์ž„๋ฒ•๋ น)

    • Phase 3 - Case Law & Legal Research

      • Court precedents (ํŒ๋ก€)

      • Constitutional Court decisions (ํ—Œ์žฌ๊ฒฐ์ •๋ก€)

      • Legal interpretations (๋ฒ•๋ นํ•ด์„๋ก€)

      • Administrative appeal decisions (ํ–‰์ •์‹ฌํŒ๋ก€)

    • Phase 4 - Article Citation Extraction

      • Extract legal citations from any law article (100% accuracy)

    • NEW: Phase 5 - AI-Powered Search

      • Semantic search for natural language queries (aiSearch)

      • Related laws discovery (aiRltLs_search)

  • 100% Semantic Validation - All 26 tools confirmed returning real law data

  • Session Configuration - Configure once, use across all tool calls

  • Error Handling - Actionable error messages with resolution hints

  • Korean Text Support - Proper UTF-8 encoding for Korean characters

  • Response Formats - HTML or XML (multiple formats supported)

Project Status

๐ŸŽ‰ Production Ready - Phase 5 Complete!

Metric

Status

Tools Implemented

26/26 (100%) โœ…

Semantic Validation

26/26 (100%) โœ…

MCP Prompts

6/6 (100%) โœ…

API Coverage

~17% of 150+ endpoints

LLM Integration

โœ… Validated (Gemini)

Code Quality

Clean, documented, tested

Version

v1.3.0

Latest Achievement: Phase 5 complete! Added AI-powered semantic search tools (aiSearch, aiRltLs_search) for natural language queries.

Prerequisites

Quick Start

1. Install Dependencies

uv sync

2. Configure Your OC Identifier

Choose one of three methods:

Option A: Session Configuration (Recommended)

# Start dev server with OC in URL uv run dev # Then in Smithery UI, set oc field in session config

Option B: Environment Variable

# Copy example file cp .env.example .env # Edit .env and set your OC OC=your_id_here

Option C: Pass in Tool Arguments

# Override OC in each tool call eflaw_search(query="๋ฒ•๋ น๋ช…", oc="your_id")

3. Run the Server

# Development mode (with hot reload) uv run dev # Interactive testing with Smithery Playground uv run playground

Available Tools

Phase 1: Core Law APIs (6 tools)

1. eflaw_search - Search Laws by Effective Date

Search for laws organized by effective date (์‹œํ–‰์ผ ๊ธฐ์ค€).

eflaw_search( query="์ž๋™์ฐจ๊ด€๋ฆฌ๋ฒ•", # Search keyword display=10, # Results per page type="XML", # Response format ef_yd="20240101~20241231" # Optional date range )

2. law_search - Search Laws by Announcement Date

Search for laws organized by announcement date (๊ณตํฌ์ผ ๊ธฐ์ค€).

law_search( query="๋ฏผ๋ฒ•", display=10, type="XML" )

3. eflaw_service - Retrieve Law Content (Effective Date)

Get full law text and articles by effective date.

IMPORTANT: For specific article queries (e.g., "์ œ174์กฐ"), use the jo parameter. Some laws have 400+ articles and responses can exceed 1MB without jo.

# Get specific article (RECOMMENDED) eflaw_service( mst="279823", # Law MST jo="017400", # Article 174 (์ œ174์กฐ) type="XML" ) # Get full law (WARNING: large response) eflaw_service( id="001823", type="XML" )

4. law_service - Retrieve Law Content (Announcement Date)

Get full law text and articles by announcement date.

IMPORTANT: For specific article queries (e.g., "์ œ174์กฐ"), use the jo parameter. Some laws have 400+ articles and responses can exceed 1MB without jo.

# Get specific article (RECOMMENDED) law_service( mst="279823", # Law MST jo="017400", # Article 174 (์ œ174์กฐ) type="XML" )

5. eflaw_josub - Query Article/Paragraph (Effective Date)

Best tool for querying specific articles. Returns only the requested article/paragraph.

eflaw_josub( mst="279823", # Law MST jo="017400", # Article 174 (์ œ174์กฐ) type="XML" ) # jo format: "XXXXXX" where first 4 digits = article (zero-padded), last 2 = branch (00=main) # Examples: "017400" (์ œ174์กฐ), "000300" (์ œ3์กฐ), "001502" (์ œ15์กฐ์˜2)

6. law_josub - Query Article/Paragraph (Announcement Date)

Best tool for querying specific articles. Returns only the requested article/paragraph.

law_josub( mst="279823", # Law MST jo="017200", # Article 172 (์ œ172์กฐ) type="XML" )

Phase 2: Extended APIs (9 tools)

7. elaw_search - Search English-Translated Laws

Search for Korean laws translated to English.

elaw_search( query="employment", display=10, type="XML" )

8. elaw_service - Retrieve English Law Content

Get full English-translated law text.

elaw_service( id="009589", type="XML" )

9. admrul_search - Search Administrative Rules

Search administrative rules (ํ›ˆ๋ น, ์˜ˆ๊ทœ, ๊ณ ์‹œ, ๊ณต๊ณ , ์ง€์นจ).

admrul_search( query="ํ•™๊ต", display=10, type="XML" )

10. admrul_service - Retrieve Administrative Rule Content

Get full administrative rule text with annexes.

admrul_service( id="62505", type="XML" )

11. lnkLs_search - Search Law-Ordinance Linkage

Find laws linked to local ordinances.

lnkLs_search( query="๊ฑด์ถ•", display=10, type="XML" )

12. lnkLsOrdJo_search - Search Ordinance Articles by Law

Find ordinance articles linked to specific law articles.

lnkLsOrdJo_search( knd="002118", # Law ID display=10, type="XML" )

13. lnkDep_search - Search Law-Ordinance Links by Ministry

Find laws linked to ordinances by government ministry.

lnkDep_search( org="1400000", # Ministry code display=10, type="XML" )

14. drlaw_search - Retrieve Law-Ordinance Linkage Statistics

Get linkage statistics table (HTML format).

drlaw_search( lid="001823", # Law ID type="HTML" )

15. lsDelegated_service - Retrieve Delegated Law Information

Get information about delegated laws, rules, and ordinances.

lsDelegated_service( id="001823", type="XML" )

16. prec_search - Search Court Precedents

Search Korean court precedents from Supreme Court and lower courts.

prec_search( query="๋‹ด๋ณด๊ถŒ", display=10, type="XML", curt="๋Œ€๋ฒ•์›" # Optional: Court name filter )

17. prec_service - Retrieve Court Precedent Full Text

Get complete court precedent text with case details.

prec_service( id="228541", type="XML" )

18. detc_search - Search Constitutional Court Decisions

Search Korean Constitutional Court decisions.

detc_search( query="๋ฒŒ๊ธˆ", display=10, type="XML" )

19. detc_service - Retrieve Constitutional Court Decision Full Text

Get complete Constitutional Court decision text.

detc_service( id="58386", type="XML" )

20. expc_search - Search Legal Interpretations

Search legal interpretation precedents issued by government agencies.

expc_search( query="์ž„์ฐจ", display=10, type="XML" )

21. expc_service - Retrieve Legal Interpretation Full Text

Get complete legal interpretation text.

expc_service( id="334617", type="XML" )

22. decc_search - Search Administrative Appeal Decisions

Search Korean administrative appeal decisions.

decc_search( query="*", # Search all decisions display=10, type="XML" )

23. decc_service - Retrieve Administrative Appeal Decision Full Text

Get complete administrative appeal decision text.

decc_service( id="243263", type="XML" )

Phase 4: Article Citation Extraction (1 tool - NEW!)

24. article_citation - Extract Citations from Law Article

Extract all legal citations referenced by a specific law article.

# First, search for the law to get MST eflaw_search(query="๊ฑด์ถ•๋ฒ•") # Returns MST: 268611 # Then extract citations article_citation( mst="268611", # Law MST from search result law_name="๊ฑด์ถ•๋ฒ•", # Law name article=3 # Article number (์ œ3์กฐ) )

Response:

{ "success": true, "law_name": "๊ฑด์ถ•๋ฒ•", "article": "์ œ3์กฐ", "citation_count": 12, "internal_count": 4, "external_count": 8, "citations": [ { "type": "external", "target_law_name": "ใ€Œ๊ตญํ† ์˜ ๊ณ„ํš ๋ฐ ์ด์šฉ์— ๊ด€ํ•œ ๋ฒ•๋ฅ ใ€", "target_article": 56, "target_paragraph": 1 } ] }

Key Features:

  • 100% accuracy via HTML parsing (not LLM-based)

  • Zero API cost (no external LLM calls)

  • ~350ms average extraction time

  • Distinguishes internal vs external citations

Phase 5: AI-Powered Search (2 tools - NEW!)

25. aiSearch - AI-Powered Semantic Law Search

โญ PREFERRED TOOL for vague or natural language queries. Use this FIRST when user's intent is unclear or conversational.

Uses intelligent/semantic search to find relevant law articles with full article text.

aiSearch( query="๋บ‘์†Œ๋‹ˆ ์ฒ˜๋ฒŒ", # Natural language query search=0, # 0: law articles, 1: appendix, 2: admin rules, 3: admin appendix display=20, # Results per page page=1, # Page number type="XML" # Response format (XML only) )

Best for: Natural language queries like "์Œ์ฃผ์šด์ „ ๋ฒŒ๊ธˆ", "์ดํ˜ผ ์žฌ์‚ฐ๋ถ„ํ• ", "์ƒ์† ๋ฌธ์ œ"

26. aiRltLs_search - AI-Powered Related Laws Search

โญ PREFERRED TOOL for discovering related laws from vague topics. Use this when user wants to explore laws around a general subject.

Finds laws semantically related to a given law name or keyword.

aiRltLs_search( query="๋ฏผ๋ฒ•", # Law name or keyword search=0, # 0: law articles, 1: admin rule articles type="XML" # Response format (XML only) )

Best for: Finding related laws like "๋ฏผ๋ฒ•" โ†’ ์ƒ๋ฒ•, ์˜๋ฃŒ๋ฒ•, ์†Œ์†ก์ด‰์ง„๋ฒ•

Tool Selection Guide

When searching Korean law, select tools based on query clarity:

Query Type

Recommended Tools

Examples

๐Ÿ” Vague/Natural language

aiSearch, aiRltLs_search

"์Œ์ฃผ์šด์ „ ์ฒ˜๋ฒŒ", "์ดํ˜ผ ์žฌ์‚ฐ๋ถ„ํ• "

๐Ÿ“‹ Specific law/article

eflaw_search, law_search

"ํ˜•๋ฒ• ์ œ148์กฐ์˜2", "๋ฏผ๋ฒ• ์ƒ์†ํŽธ"

โš–๏ธ Case law

prec_search, detc_search

"๋Œ€๋ฒ•์› 2023๋‹ค12345"

๐Ÿ”— Related laws

aiRltLs_search

"๋ฏผ๋ฒ•๊ณผ ๊ด€๋ จ๋œ ๋ฒ•๋ฅ "

Configuration

Session Configuration Schema

Configure once in Smithery UI or URL parameters:

{ "oc": "your_id", # Required: law.go.kr user ID "http_timeout_s": 60 # Optional: HTTP timeout (5-120s, default: 60) }

Parameter Priority

When resolving the OC identifier:

  1. Tool argument (highest priority) - oc parameter in tool call

  2. Session config - Set in Smithery UI/URL

  3. Environment variable - OC in .env file

Usage Examples

# Search for automobile management law result = eflaw_search( query="์ž๋™์ฐจ๊ด€๋ฆฌ๋ฒ•", display=5, type="XML" ) # Returns: { "status": "ok", "request_id": "uuid", "upstream_type": "XML", "data": { # Law search results... } }

Example 2: Search with Date Range

# Find laws effective in 2024 result = eflaw_search( query="๊ตํ†ต", ef_yd="20240101~20241231", type="XML" )

Example 3: Error Handling

# Missing OC parameter result = eflaw_search(query="test") # Returns helpful error: { "status": "error", "error_code": "MISSING_OC", "message": "OC parameter is required but not provided.", "hints": [ "1. Tool argument: oc='your_value'", "2. Session config: Set 'oc' in Smithery settings", "3. Environment variable: OC=your_value" ] }

Golden MCP Tool Trajectories

These examples demonstrate real-world conversation flows showing how LLMs interact with LexLink tools to answer legal research questions.

Trajectory 1: Basic Law Research

User Query: "What is Article 20 of the Civil Code?"

Tool Calls:

  1. law_search(query="๋ฏผ๋ฒ•", display=50, type="XML") โ†’ Find Civil Code ID

  2. law_service(id="000021", jo="002000", type="XML") โ†’ Retrieve Article 20 text

Result: LLM provides formatted explanation of Civil Code Article 20 with full legal text and context.


Trajectory 2: Court Precedent Analysis

User Query: "Find recent Supreme Court precedents about security interests"

Tool Calls:

  1. prec_search(query="๋‹ด๋ณด๊ถŒ", curt="๋Œ€๋ฒ•์›", display=50, type="XML") โ†’ Search Supreme Court precedents

  2. prec_service(id="228541", type="XML") โ†’ Retrieve top precedent details

Result: LLM summarizes key precedents with case numbers, dates, and holdings related to security interests.


User Query: "How does the Labor Standards Act handle overtime, and are there relevant court precedents?"

Tool Calls:

  1. eflaw_search(query="๊ทผ๋กœ๊ธฐ์ค€๋ฒ•", display=50, type="XML") โ†’ Find Labor Standards Act

  2. eflaw_service(id="001234", jo="005000", type="XML") โ†’ Retrieve Article 50 (overtime provisions)

  3. prec_search(query="๊ทผ๋กœ๊ธฐ์ค€๋ฒ• ์—ฐ์žฅ๊ทผ๋กœ", display=30, type="XML") โ†’ Search overtime precedents

  4. prec_service(id="234567", type="XML") โ†’ Retrieve leading precedent

Result: LLM provides comprehensive analysis combining statutory text with judicial interpretation, showing how courts apply the overtime provisions.


Trajectory 4: Constitutional Review

User Query: "Has the Constitutional Court reviewed laws about fines?"

Tool Calls:

  1. detc_search(query="๋ฒŒ๊ธˆ", display=50, type="XML") โ†’ Search Constitutional Court decisions

  2. detc_service(id="58386", type="XML") โ†’ Retrieve decision full text

  3. law_search(query=<law_name_from_decision>, type="XML") โ†’ Find related law for context

Result: LLM explains Constitutional Court holdings on fine-related provisions and their impact on specific laws.


Trajectory 5: Administrative Law Research

User Query: "What administrative rules exist for schools, and are there related legal interpretations?"

Tool Calls:

  1. admrul_search(query="ํ•™๊ต", display=50, type="XML") โ†’ Search school-related administrative rules

  2. admrul_service(id="62505", type="XML") โ†’ Retrieve rule content

  3. expc_search(query="ํ•™๊ต", display=30, type="XML") โ†’ Search legal interpretations

  4. expc_service(id="334617", type="XML") โ†’ Retrieve interpretation details

Result: LLM provides overview of administrative framework for schools with official agency interpretations.


User Query: "I'm researching rental housing disputes. Show me the relevant law, court precedents, and administrative appeal decisions."

Tool Calls:

  1. eflaw_search(query="์ฃผํƒ์ž„๋Œ€์ฐจ๋ณดํ˜ธ๋ฒ•", display=50, type="XML") โ†’ Find Housing Lease Protection Act

  2. eflaw_service(id="002876", type="XML") โ†’ Retrieve full law text

  3. prec_search(query="์ฃผํƒ์ž„๋Œ€์ฐจ", display=50, type="XML") โ†’ Search housing lease precedents

  4. prec_service(id="156789", type="XML") โ†’ Retrieve key precedent

  5. decc_search(query="์ฃผํƒ์ž„๋Œ€์ฐจ", display=30, type="XML") โ†’ Search administrative appeal decisions

  6. decc_service(id="243263", type="XML") โ†’ Retrieve appeal decision

Result: LLM provides comprehensive legal research report covering statutory framework, judicial interpretation, and administrative precedents for rental housing disputes.


Trajectory 7: Citation Network Analysis (Phase 4)

User Query: "What laws does Article 3 of the Building Act cite?"

Tool Calls:

  1. eflaw_search(query="๊ฑด์ถ•๋ฒ•", display=50, type="XML") โ†’ Find Building Act, get MST

  2. article_citation(mst="268611", law_name="๊ฑด์ถ•๋ฒ•", article=3) โ†’ Extract all citations

Result: LLM provides complete citation analysis showing 12 citations (8 external laws, 4 internal references) including specific article and paragraph references.


Trajectory 8: AI-Powered Natural Language Search (Phase 5)

User Query: "What's the penalty for hit-and-run accidents?"

Tool Calls:

  1. aiSearch(query="๋บ‘์†Œ๋‹ˆ ์ฒ˜๋ฒŒ", search=0, display=20, type="XML") โ†’ Semantic search for hit-and-run penalties

Result: LLM receives full article text from relevant laws (ํŠน์ •๋ฒ”์ฃ„ ๊ฐ€์ค‘์ฒ˜๋ฒŒ ๋“ฑ์— ๊ด€ํ•œ ๋ฒ•๋ฅ  ์ œ5์กฐ์˜3) with complete provisions about hit-and-run penalties, enabling comprehensive answer without needing to know specific law names.


User Query: "What laws are related to the Civil Code?"

Tool Calls:

  1. aiRltLs_search(query="๋ฏผ๋ฒ•", search=0, type="XML") โ†’ Find semantically related laws

Result: LLM discovers related laws like ์ƒ๋ฒ• (Commercial Act), ์˜๋ฃŒ๋ฒ• (Medical Service Act), ์†Œ์†ก์ด‰์ง„๋ฒ• (Act on Special Cases Concerning Expedition of Litigation), showing connections across legal domains.


Key Patterns

  1. AI Tools for Vague Queries: Use aiSearch or aiRltLs_search FIRST when user intent is unclear or conversational

  2. Search First, Then Retrieve: Always search to find IDs before calling service tools

  3. Use display=50-100 for Law Searches: Ensures exact matches are found due to relevance ranking

  4. Combine Phases: Mix Phase 1 (laws), Phase 2 (administrative rules), Phase 3 (precedents), and Phase 5 (AI search) for complete research

  5. Type Parameter: Always specify type="XML" for consistent, parseable results

  6. Article Numbers: Use 6-digit format (e.g., "002000" for Article 20) when querying specific articles

Development

Project Structure

lexlink-ko-mcp/ โ”œโ”€โ”€ src/lexlink/ โ”‚ โ”œโ”€โ”€ server.py # Main MCP server with 26 tools โ”‚ โ”œโ”€โ”€ http_server.py # HTTP/SSE server for Kakao PlayMCP โ”‚ โ”œโ”€โ”€ config.py # Session configuration schema โ”‚ โ”œโ”€โ”€ params.py # Parameter resolution & mapping โ”‚ โ”œโ”€โ”€ validation.py # Input validation โ”‚ โ”œโ”€โ”€ parser.py # XML parsing utilities โ”‚ โ”œโ”€โ”€ ranking.py # Relevance ranking โ”‚ โ”œโ”€โ”€ citation.py # Article citation extraction (Phase 4) โ”‚ โ”œโ”€โ”€ client.py # HTTP client for law.go.kr API โ”‚ โ”œโ”€โ”€ errors.py # Error codes & responses โ”‚ โ”œโ”€โ”€ raw_logger.py # PlayMCP traffic logging โ”‚ โ””โ”€โ”€ log_processor.py # Log format converter โ”œโ”€โ”€ logs/playmcp/ # PlayMCP traffic logs (daily JSONL) โ”œโ”€โ”€ pyproject.toml # Project configuration โ””โ”€โ”€ README.md # This file

Running Tests

# Install test dependencies uv sync # Run all tests uv run pytest # Run with coverage uv run pytest --cov=src/lexlink --cov-report=html # Run specific test category uv run pytest tests/unit/ uv run pytest tests/integration/ uv run pytest tests/e2e/

Adding New Tools

Current Status: 26/26 tools implemented and validated (Phase 1-5 complete)

For implementing additional tools from the 124+ remaining APIs:

  1. Follow the pattern established in src/lexlink/server.py

  2. Use Context injection for session configuration

  3. Use generic parser functions (extract_items_list, update_items_list)

  4. Add semantic validation tests

Tool Implementation Pattern:

  • Each tool is a decorated function with MCP schema

  • Uses ctx: Context = None parameter for session config

  • 3-tier parameter resolution: tool arg > session > env

  • Generic parser functions work with any XML tag

  • Comprehensive error handling with actionable hints

Deployment

Deploy to Smithery

  1. Create a GitHub repository:

    git init git add . git commit -m "Initial commit" git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPO.git git push -u origin main
  2. Deploy at smithery.ai/new

  3. Configure session settings in Smithery UI

Deploy to Kakao PlayMCP (HTTP Server)

LexLink can also be deployed as an HTTP server for platforms like Kakao PlayMCP.

Important: Kakao PlayMCP does not accept port numbers in URLs. You must use Nginx as a reverse proxy to serve on port 80.

Quick Start (Local Testing):

# Run the HTTP server OC=your_oc uv run serve # Server starts at: http://localhost:8000/sse

Production Setup:

Internet โ†’ Nginx (port 80) โ†’ LexLink (port 8000)

PlayMCP Registration:

Field

Value

MCP Endpoint

http://YOUR_SERVER_IP/sse (no port!)

Authentication

Key/Token (Header: OC)

For detailed deployment instructions (AWS EC2, Nginx, systemd, HTTPS), see assets/DEPLOYMENT_GUIDE.md.

PlayMCP Traffic Logging

LexLink includes built-in logging for PlayMCP traffic analysis. Logs are saved in dashboard-compatible JSONL format.

Log Location: logs/playmcp/YYYY-MM-DD.jsonl

Log Schema:

{ "rpc_id": "3", "request_id": "d8ee45eb", "session_id": "9ff9dc23431848a4901b4cb6326ba5bd", "timestamp": "2025-12-25T05:40:23.957987", "duration_ms": 1.52, "method": "tools/call", "tool_name": "aiSearch", "params": { "arguments": {"query": "๋บ‘์†Œ๋‹ˆ ์ฒ˜๋ฒŒ"} }, "client": "PlayMCP", "client_version": "2025.0.0", "protocol_version": "2025-06-18", "client_ip": "220.64.111.219", "oc": "user_id", "status": "success", "status_code": 200, "result": { ... } }

Features:

  • Daily log rotation (one file per day)

  • Dashboard-compatible format for filtering and analysis

  • Captures request/response pairs with timing

  • SSE streaming response parsing

Converting Old Raw Logs:

uv run python -m lexlink.log_processor input.jsonl output.jsonl

Troubleshooting

"OC parameter is required" error

Solution: Set your OC identifier using one of the three methods above.

Korean characters not displaying correctly

Solution: Ensure your terminal supports UTF-8:

export PYTHONIOENCODING=utf-8

"Timeout" errors

Solution: Increase timeout in session config:

{ "oc": "your_id", "http_timeout_s": 90 # Increase from default 60s }

Server won't start after updating dependencies

Solution: Re-sync dependencies:

uv sync --reinstall

Contributing

Contributions are welcome! Please:

  1. Fork the repository

  2. Create a feature branch (git checkout -b feature/amazing-feature)

  3. Write tests for new functionality

  4. Ensure all tests pass (uv run pytest)

  5. Commit changes (git commit -m 'Add amazing feature')

  6. Push to branch (git push origin feature/amazing-feature)

  7. Open a Pull Request

License

This project is open source. See LICENSE file for details.

Acknowledgments

  • law.go.kr - Korean National Law Information API

  • MCP - Model Context Protocol by Anthropic

  • Smithery - MCP server deployment platform

Support


Changelog

v1.3.1 - 2025-12-25

Feature: PlayMCP Traffic Logging

  • New Modules:

    • raw_logger.py - Dashboard-compatible MCP traffic logger

    • log_processor.py - Log format converter utility

  • Implementation:

    • RawLoggingMiddleware in HTTP server for request/response capture

    • JSONL format with merged request/response pairs

    • Daily log rotation at logs/playmcp/YYYY-MM-DD.jsonl

    • SSE streaming response parsing

  • Log Schema:

    • request_id, timestamp, duration_ms

    • method, tool, arguments, result

    • status_code, client_ip, headers

  • Impact:

    • Enables traffic analysis for PlayMCP deployments

    • Dashboard-compatible format for monitoring

v1.3.0 - 2025-12-24

Feature: Phase 5 - AI-Powered Search Tools

  • New Tools:

    • aiSearch - AI-powered semantic law search (Tool 25)

    • aiRltLs_search - AI-powered related laws search (Tool 26)

  • Implementation:

    • Uses law.go.kr's intelligent search system (์ง€๋Šฅํ˜• ๋ฒ•๋ น๊ฒ€์ƒ‰)

    • Semantic search for natural language queries

    • Returns full article text (์กฐ๋ฌธ๋‚ด์šฉ) for comprehensive results

    • XML parsing with ranked_data for LLM consumption

  • LLM Guidance:

    • Added โญ PREFERRED TOOL hints in tool descriptions

    • Added tool-selection-guide MCP prompt for tool selection guidance

    • Tools marked as preferred for vague/unclear queries

  • Impact:

    • Tool count: 24 โ†’ 26 tools

    • MCP prompts: 5 โ†’ 6 prompts

    • Better handling of natural language legal queries

v1.2.9 - 2025-12-09

Fix: Case-insensitive item key matching for API inconsistency

  • Issue: law.go.kr API uses inconsistent XML tag casing

    • prec search โ†’ <prec> (lowercase)

    • detc search โ†’ <Detc> (capitalized)

    • expc search โ†’ <Expc> (capitalized)

  • Fix: Made extract_items_list, update_items_list, and slim_response case-insensitive

v1.2.8 - 2025-12-09

Fix: Case-sensitive item key extraction for non-law searches

  • Issue: extract_items_list() used capitalized keys ('Prec', 'Detc', 'Expc', 'Decc') but XML parser outputs lowercase ('prec', 'detc', etc.)

  • Result: ranked_data never set โ†’ empty responses for all non-law searches

  • Fix: Changed all 8 calls to use lowercase keys

v1.2.7 - 2025-12-09

Refactor: Pattern-based essential field detection

  • Issue: Manual field definitions per data type required maintenance for each new API

  • Solution: Regex pattern matching for automatic field detection

  • Patterns: *์ผ๋ จ๋ฒˆํ˜ธ (IDs), *๋ช…ํ•œ๊ธ€/*๋ช… (names), *์ผ์ž (dates), etc.

  • Benefit: Works automatically for any data type without manual definitions

v1.2.6 - 2025-12-09

Fix: Data-type-specific essential fields for slim response

  • Issue: slim_response() used law-specific field names for all data types

    • Precedent searches (prec_search) returned empty results

    • Fields like ํŒ๋ก€์ผ๋ จ๋ฒˆํ˜ธ, ์‚ฌ๊ฑด๋ช… were filtered out because they didn't match law fields

  • Solution:

    • Implemented essential_fields_by_type dictionary with correct fields per data type

    • Each API type (law, prec, detc, expc, decc, admrul, elaw) now has its own essential fields

v1.2.5 - 2025-12-09

Fix: Add ๋ฒ•๋ นID to essential fields for correct parameter usage

  • Issue: LLM was confusing ๋ฒ•๋ น์ผ๋ จ๋ฒˆํ˜ธ (MST) with ๋ฒ•๋ นID in slimmed responses

    • Example: Calling eflaw_service(id="235555") when 235555 is MST, not ๋ฒ•๋ นID

    • Correct usage should be eflaw_service(mst=235555) or eflaw_service(id="001624")

  • Solution:

    • Added ๋ฒ•๋ นID back to essential_fields in slim_response()

    • Now LLM can see both fields and use correct parameter

  • Essential fields: ๋ฒ•๋ น๋ช…ํ•œ๊ธ€, ๋ฒ•๋ น์ผ๋ จ๋ฒˆํ˜ธ, ๋ฒ•๋ นID, ํ˜„ํ–‰์—ฐํ˜์ฝ”๋“œ, ์‹œํ–‰์ผ์ž

  • Note: If ranking not working, ensure EC2 has latest code with relevance ranking

v1.2.4 - 2025-12-09

Fix: Slim response mode for PlayMCP size limits

  • Issue: v1.2.3's truncation approach was insufficient because ranked_data still contained full data (~25KB per 50 results)

  • Solution:

    • Replaced truncate_response() with slim_response() function

    • When SLIM_RESPONSE=true: removes raw_content entirely and keeps only essential fields in ranked_data

    • Essential fields kept: ๋ฒ•๋ น๋ช…ํ•œ๊ธ€, ๋ฒ•๋ น์ผ๋ จ๋ฒˆํ˜ธ, ํ˜„ํ–‰์—ฐํ˜์ฝ”๋“œ, ์‹œํ–‰์ผ์ž

    • Fields removed: ๋ฒ•๋ น์•ฝ์นญ๋ช…, ๊ณตํฌ์ผ์ž, ๊ณตํฌ๋ฒˆํ˜ธ, ์ œ๊ฐœ์ •๊ตฌ๋ถ„๋ช…, ์†Œ๊ด€๋ถ€์ฒ˜์ฝ”๋“œ, ์†Œ๊ด€๋ถ€์ฒ˜๋ช…, ๋ฒ•๋ น๊ตฌ๋ถ„๋ช…, ๊ณต๋™๋ถ€๋ น์ •๋ณด, ์ž๋ฒ•ํƒ€๋ฒ•์—ฌ๋ถ€, ๋ฒ•๋ น์ƒ์„ธ๋งํฌ

  • Configuration:

    • Smithery: No change needed (full response)

    • PlayMCP: Set SLIM_RESPONSE=true in systemd service

  • Impact:

    • Response size reduced from ~50KB to ~3-5KB for 50 results

    • PlayMCP works reliably without size errors

v1.2.3 - 2025-12-08

Fix: Response truncation for PlayMCP size limits

  • Issue: PlayMCP has response size limits (~50KB), causing "Tool call returned too large content part" errors

  • Solution:

    • Added truncate_response() helper function for optional response size limiting

    • Applied truncation to all 11 search tools (eflaw_search, law_search, elaw_search, admrul_search, lnkLs_search, lnkLsOrdJo_search, lnkDep_search, prec_search, detc_search, expc_search, decc_search)

    • Added MAX_RESPONSE_SIZE environment variable (only truncates when set)

  • Configuration:

    • Smithery: No change needed (no size limit)

    • PlayMCP: Set MAX_RESPONSE_SIZE=50000 in systemd service

  • Impact:

    • Smithery keeps full functionality (unlimited responses)

    • PlayMCP avoids size errors with truncated responses + Korean message

v1.2.2 - 2025-12-06

Feature: HTTP/SSE Server for Kakao PlayMCP

  • New Feature:

    • Added HTTP/SSE server support for Kakao PlayMCP deployment

    • New uv run serve command to start HTTP server

    • OCHeaderMiddleware extracts OC from HTTP headers (Key/Token auth)

    • Supports both SSE (/sse) and Streamable HTTP (/mcp) transports

  • Breaking Changes:

    • Renamed LAW_OC environment variable to OC (matches official law.go.kr API naming)

  • Configuration Changes:

    • Removed base_url from Smithery UI config (kept as internal field only)

    • Updated default timeout from 15s to 60s

    • Timeout range extended to 5-120s

  • Documentation:

    • Added Kakao PlayMCP deployment guide (assets/DEPLOYMENT_GUIDE.md)

    • Updated README with PlayMCP deployment section

    • Added http_server.py to project structure

  • Impact:

    • LexLink can now be deployed to Kakao PlayMCP and similar HTTP-based platforms

    • Each PlayMCP user provides their own OC via HTTP header (uses their own API quota)

v1.2.1 - 2025-11-30

Fix: Improve LLM guidance for specific article queries

  • Issue: LLMs were fetching entire laws (1MB+ for ์ž๋ณธ์‹œ์žฅ๋ฒ•) instead of using jo parameter for specific articles like "์ œ174์กฐ"

  • Solution:

    • Added IMPORTANT notices in eflaw_service and law_service docstrings about using jo parameter

    • Added BEST TOOL guidance in eflaw_josub and law_josub docstrings

    • Added practical examples: jo="017400" for ์ œ174์กฐ, jo="000300" for ์ œ3์กฐ

    • Warned about large response sizes (400+ articles, 1MB+ responses)

  • Impact:

    • LLMs now correctly use jo parameter for specific article queries

    • LLMs prefer law_josub/eflaw_josub for article queries

    • Faster responses and cleaner output for specific article requests

v1.2.0 - 2025-11-30

Feature: Phase 4 - Article Citation Extraction

  • New Tool:

    • article_citation - Extract legal citations from any law article (Tool 24)

  • Implementation:

    • HTML parsing approach for 100% accuracy (no LLM hallucination risk)

    • CSS class-based citation type detection (sfon1-4 classes)

    • MST โ†” lsiSeq ID mapping between XML API and HTML pages

    • Zero external API costs (no LLM calls required)

    • ~350ms average extraction time

  • Features:

    • Distinguishes internal vs external citations

    • Extracts article, paragraph, and sub-item references

    • Consolidates duplicate citations with citation counts

    • Preserves raw citation text for context

  • MCP Prompts Added:

    • extract-law-citations - Extract and explain citations from a law article

    • analyze-citation-network - Analyze legal citation network for a law

  • Test Coverage:

    • Unit tests: Citation module 100% coverage

    • Integration tests: End-to-end extraction validated

    • LLM workflow tests: Gemini 2.0 Flash validated

  • Known Limitations:

    • Range references (e.g., "์ œ88์กฐ ๋‚ด์ง€ ์ œ93์กฐ") return first article only

    • External law names require separate search for MST lookup

  • Impact:

    • Tool count: 23 โ†’ 24 tools

    • MCP prompts: 3 โ†’ 5 prompts

    • Enables citation network analysis workflows

v1.1.0 - 2025-11-14

Feature: Phase 3 - Case Law & Legal Research APIs

  • Changes:

    • Added 8 new tools for case law and legal research (15 โ†’ 23 tools)

    • prec_search, prec_service - Court precedents (ํŒ๋ก€)

    • detc_search, detc_service - Constitutional Court decisions (ํ—Œ์žฌ๊ฒฐ์ •๋ก€)

    • expc_search, expc_service - Legal interpretations (๋ฒ•๋ นํ•ด์„๋ก€)

    • decc_search, decc_service - Administrative appeal decisions (ํ–‰์ •์‹ฌํŒ๋ก€)

  • Implementation:

    • Added generic parser functions (extract_items_list, update_items_list) that work with any XML tag

    • Added 13 new Phase 3 parameters: prnc_yd, dat_src_nm, ed_yd, reg_yd, expl_yd, dpa_yd, rsl_yd, curt, inq, rpl, itmno, cls

    • All ranking and validation functions compatible with Phase 3 tools

    • Zero breaking changes to existing Phase 1 & 2 tools

  • Impact:

    • Tool count increased by 53% (15 โ†’ 23 tools)

    • API coverage increased from ~10% to ~15%

    • Legal research categories expanded by 133% (3 โ†’ 7 categories)

    • All 23 tools validated and working in production

v1.0.8 - 2025-11-13

Fix: Complete parameter type consistency across all tools

  • Issue: v1.0.2 fixed 7 tools but missed 2 additional tools (eflaw_josub, law_josub), creating inconsistency where same parameters had different types across tools

  • Root Cause:

    • eflaw_josub and law_josub still had id: Optional[str] and mst: Optional[str] instead of Union[str, int]

    • lnkLsOrdJo_search had jo: Optional[int] instead of Union[str, int]

    • Caused validation errors when LLMs passed integers to these specific tools

  • Solution:

    • Fixed eflaw_josub: id and mst now accept Union[str, int]

    • Fixed law_josub: id and mst now accept Union[str, int]

    • Fixed lnkLsOrdJo_search: jo now accepts Union[str, int]

  • Verification:

    • All 7 tools with id parameter now consistently Optional[Union[str, int]]

    • All 6 tools with mst parameter now consistently Optional[Union[str, int]]

    • All 5 tools with jo parameter now consistently Optional[Union[str, int]]

  • Impact:

    • 100% parameter type consistency achieved

    • No validation errors regardless of which tool LLMs choose

    • Better developer experience - same parameters work identically everywhere

v1.0.7 - 2025-11-10

Fix: Improve search reliability and LLM guidance

  • Issue: LLMs often failed to find common laws like "๋ฏผ๋ฒ•" (Civil Code) because:

    1. Ranking fetch limit (50 results) was too small for large result sets (e.g., 77 results for "๋ฏผ๋ฒ•")

    2. LLMs defaulted to small display values (e.g., 5), missing exact matches

    3. jo parameter rejected integers, causing validation errors and retry loops

  • Root Cause:

    • v1.0.5 ranking fetched only 50 results; "๋ฏผ๋ฒ•" was beyond position 50 alphabetically

    • Tool descriptions didn't guide LLMs to use larger display values

    • Parameter type strictness caused UX friction

  • Solution:

    • Increased ranking fetch limit from 50 to 100 results (API maximum)

    • Updated jo parameter to accept Union[str, int] with auto-conversion

    • Added guidance in tool descriptions: "Recommend 50-100 for law searches (๋ฒ•๋ น ๊ฒ€์ƒ‰) to ensure exact matches are found"

  • Changes:

    • All 4 search tools now fetch up to 100 results for ranking

    • All 4 tools with jo parameter (eflaw_service, law_service, eflaw_josub, law_josub) now accept integers

    • All 7 search tool descriptions updated with display recommendations

  • Impact:

    • LLMs now find "๋ฏผ๋ฒ•" correctly even with small initial display values

    • No more validation errors when LLMs pass article numbers as integers

    • Better guidance leads to more efficient searches

v1.0.6 - 2025-11-10

Enhancement: Improve MCP server quality score (Smithery.ai optimization)

  • Changes:

    • Set OC configuration default value to "test" for easier onboarding

    • Added tool annotations to all 15 tools (readOnlyHint=True, destructiveHint=False, idempotentHint=True)

    • Enhanced parameter descriptions in docstrings for all tools

    • Implemented 3 MCP prompts for common use cases

  • Prompts Added:

    • search-korean-law: Search for a Korean law by name and provide a summary

    • get-law-article: Retrieve and explain a specific article from a law

    • search-admin-rules: Search administrative rules by keyword

  • Impact: Expected Smithery quality score improvement from 47/100 to ~73/100 (+26 points)

    • Tool annotations: +9pts

    • Parameter descriptions: +12pts

    • MCP prompts: +5pts

v1.0.5 - 2025-11-10

Fix: Improve ranking by fetching more results before ranking

  • Issue: v1.0.4 ranking was not working properly because it only ranked the limited results returned by the API (e.g., with display=5, only 5 alphabetically-ordered results were fetched). If "๋ฏผ๋ฒ•" wasn't in those first 5 results, ranking couldn't help.

  • Root Cause: Ranking logic was applied AFTER API returned limited results, so relevant matches outside the initial page were never considered.

  • Solution:

    • When ranking is enabled and display < 50, automatically fetch up to 50 results from API

    • Apply ranking to the larger result set (50 results)

    • Trim back to original requested display amount after ranking

    • Update numOfRows in response to reflect actual number of results returned

  • Implementation:

    • Updated all 4 search tools: eflaw_search, law_search, elaw_search, admrul_search

    • Added original_display tracking and ranking_enabled flag

    • Fetch 50 results when ranking applies, then trim to requested amount

  • Examples:

    • User requests display=5 for query "๋ฏผ๋ฒ•"

    • System fetches 50 results (includes "๋ฏผ๋ฒ•" even if it's not in first 5 alphabetically)

    • Ranking places "๋ฏผ๋ฒ•" first

    • System returns top 5 ranked results (now "๋ฏผ๋ฒ•" appears first)

  • Impact: Ranking now actually works - exact matches appear first regardless of alphabetical position in API results

v1.0.4 - 2025-11-10

Feature: Add relevance ranking to search results

  • Issue: law.go.kr API returns results in alphabetical order, causing irrelevant matches to appear first (e.g., searching "๋ฏผ๋ฒ•" returned "๋‚œ๋ฏผ๋ฒ•" first instead of exact match "๋ฏผ๋ฒ•")

  • Solution:

    • Added intelligent relevance ranking that prioritizes exact matches over alphabetical ordering

    • Ranking applies automatically to XML responses for keyword searches

    • Results are reordered: exact match โ†’ starts with query โ†’ contains query โ†’ other matches

  • Implementation:

    • Added ranking.py module with rank_search_results(), should_apply_ranking(), and detect_query_language() functions

    • Added parser.py module for XML parsing and structured data extraction

    • Updated 4 major search tools: eflaw_search, law_search, elaw_search, admrul_search

    • Ranking preserves raw XML while adding ranked_data field for LLM consumption

    • Special handling for elaw_search: Detects query language (Korean vs English) and ranks by matching name field

  • Examples:

    • Query "๋ฏผ๋ฒ•" now returns: "๋ฏผ๋ฒ•" (exact) โ†’ "๋ฏผ๋ฒ• ์‹œํ–‰๋ น" (starts with) โ†’ "๋‚œ๋ฏผ๋ฒ•" (alphabetical)

    • Query "insurance" ranks: "Insurance Act" โ†’ "Insurance Business Act" โ†’ other matches

  • Impact: Significantly improves search relevance, reducing LLM confusion and providing better user experience

v1.0.3 - 2025-11-10

Fix: Clarify article number format in tool descriptions

  • Issue: LLMs misinterpreted the 6-digit article number format (jo parameter), generating "000200" for Article 20 (์ œ20์กฐ) instead of correct "002000", resulting in wrong article retrieval

  • Root Cause: Tool descriptions used ambiguous example "000200" for "Article 2", leading LLMs to incorrectly pattern-match Article 20 โ†’ "000200"

  • Solution:

    • Added comprehensive article number format documentation with multiple examples

    • Added format_article_number() helper function in validation.py for future use

    • Clarified that XXXXXX format = first 4 digits (article number, zero-padded) + last 2 digits (branch article suffix)

  • Changes:

    • Updated 4 tools: eflaw_service, law_service, eflaw_josub, law_josub

    • Updated lnkLsOrdJo_search which uses separate 4+2 digit format

    • Added clear examples: "000200" (Art. 2), "002000" (Art. 20), "001502" (Art. 15-2)

  • Impact: LLMs will now correctly format article numbers, preventing queries from returning wrong articles

v1.0.2 - 2025-11-10

Fix: Accept both string and integer for id/mst parameters

  • Issue: LLMs extract numeric values from XML responses as integers (e.g., <๋ฒ•๋ น์ผ๋ จ๋ฒˆํ˜ธ>188376</๋ฒ•๋ น์ผ๋ จ๋ฒˆํ˜ธ> โ†’ mst=188376), but tools expected strings, causing Pydantic validation errors

  • Solution: Changed parameter types to accept both strings and integers with automatic conversion

  • Changes:

    • Updated 7 tool signatures: id: Optional[str] โ†’ id: Optional[Union[str, int]]

    • Added automatic string conversion at start of each affected tool

    • Applied to: eflaw_service, law_service, eflaw_josub, law_josub, elaw_service, admrul_service, lsDelegated_service

  • Impact: LLMs can now pass numeric IDs as integers without validation errors

v1.0.1 - 2025-11-10

Fix: Remove JSON format option from all tools

  • Issue: LLMs were selecting JSON format, but law.go.kr API does not support JSON despite documentation (returns HTML error pages with "๋ฏธ์‹ ์ฒญ๋œ ๋ชฉ๋ก/๋ณธ๋ฌธ" message)

  • Solution: Removed JSON as an option from all 14 tool descriptions

  • Changes:

    • Updated type parameter documentation to explicitly state "JSON not supported by API"

    • Added warning in module docstring about JSON format limitation

    • Tool defaults remain XML (working format)

  • Impact: Prevents LLMs from requesting JSON format and receiving error pages

v1.0.0 - 2025-11-10

Initial Release

  • 15 MCP tools for Korean law information access

  • 6 core law APIs (eflaw/law search and retrieval)

  • 9 extended APIs (English laws, administrative rules, law-ordinance linkage)

  • Session configuration via Context injection

  • 100% semantic validation

  • Production-ready for Smithery deployment


Built with

-
security - not tested
F
license - not found
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rabqatab/LexLink-ko-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server