We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/seo-jinseok/korean-law-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
import os
import requests
import xmltodict
from typing import Optional, Dict, Any
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
class KoreanLawClient:
BASE_URL = "https://www.law.go.kr"
def __init__(self):
self.user_id = os.getenv("OPEN_LAW_ID")
if not self.user_id:
raise ValueError("OPEN_LAW_ID environment variable is not set")
def search_law(self, query: str, target: str = "law") -> Dict[str, Any]:
"""
Search for laws/regulations.
Target: 'law' (statute), 'prec' (precedent), etc.
"""
# Endpoint construction (this is a guess based on standard patterns, verifying with actual docs is key)
# Usually: /DRF/lawSearch.do?OC={user_id}&target={target}&type=XML&query={query}
url = f"{self.BASE_URL}/DRF/lawSearch.do"
params = {
"OC": self.user_id,
"target": target,
"type": "XML",
"query": query
}
response = requests.get(url, params=params)
response.raise_for_status()
# Parse XML to Dict
data = xmltodict.parse(response.content)
return data
def get_law_detail(self, law_id: str) -> Dict[str, Any]:
"""
Get details of a specific law (statute).
"""
# Endpoint: /DRF/lawService.do?OC={user_id}&target=law&type=XML&MST={law_id}
url = f"{self.BASE_URL}/DRF/lawService.do"
params = {
"OC": self.user_id,
"target": "law",
"type": "XML",
"MST": law_id
}
response = requests.get(url, params=params)
response.raise_for_status()
data = xmltodict.parse(response.content)
return data
def get_precedent_detail(self, prec_id: str) -> Dict[str, Any]:
"""
Get details of a specific precedent.
"""
# Endpoint: /DRF/lawService.do?OC={user_id}&target=prec&type=XML&ID={prec_id}
url = f"{self.BASE_URL}/DRF/lawService.do"
params = {
"OC": self.user_id,
"target": "prec",
"type": "XML",
"ID": prec_id
}
response = requests.get(url, params=params)
response.raise_for_status()
data = xmltodict.parse(response.content)
return data
def get_admin_rule_detail(self, adm_id: str) -> Dict[str, Any]:
"""
Get details of an administrative rule (admrul).
"""
# Endpoint: /DRF/lawService.do?target=admrul&ID={adm_id}
url = f"{self.BASE_URL}/DRF/lawService.do"
params = {
"OC": self.user_id,
"target": "admrul",
"type": "XML",
"ID": adm_id
}
response = requests.get(url, params=params)
response.raise_for_status()
return xmltodict.parse(response.content)
def get_prec_const_detail(self, detc_id: str) -> Dict[str, Any]:
"""
Get details of a Constitutional Court decision (detc).
"""
# Endpoint: /DRF/lawService.do?target=detc&ID={detc_id}
url = f"{self.BASE_URL}/DRF/lawService.do"
params = {
"OC": self.user_id,
"target": "detc",
"type": "XML",
"ID": detc_id
}
response = requests.get(url, params=params)
response.raise_for_status()
return xmltodict.parse(response.content)
def get_autonomous_law_detail(self, ordin_id: str) -> Dict[str, Any]:
"""
Get details of an autonomous law (ordin).
Note: Uses 'MST' parameter instead of 'ID'.
"""
# Endpoint: /DRF/lawService.do?target=ordin&MST={ordin_id}
url = f"{self.BASE_URL}/DRF/lawService.do"
params = {
"OC": self.user_id,
"target": "ordin",
"type": "XML",
"MST": ordin_id
}
response = requests.get(url, params=params)
response.raise_for_status()
return xmltodict.parse(response.content)
def get_legal_term_list(self, query: str) -> Dict[str, Any]:
"""
Search for legal terms (Law Terms).
"""
# Endpoint: /DRF/lawSearch.do?target=lstrm&query={query}
url = f"{self.BASE_URL}/DRF/lawSearch.do"
params = {
"OC": self.user_id,
"target": "lstrm",
"type": "XML",
"query": query
}
response = requests.get(url, params=params)
response.raise_for_status()
return xmltodict.parse(response.content)
def get_legal_term_detail(self, term_id: str) -> Dict[str, Any]:
"""
Get details of a legal term.
"""
# Endpoint: /DRF/lawService.do?target=lstrm&MST={term_id} (or ID?)
# Guide says ID or MST. Usually MST for terms.
url = f"{self.BASE_URL}/DRF/lawService.do"
params = {
"OC": self.user_id,
"target": "lstrm",
"type": "XML",
"MST": term_id # Verified in docs: Uses MST
}
response = requests.get(url, params=params)
response.raise_for_status()
return xmltodict.parse(response.content)
def get_statutory_interpretation_list(self, query: str) -> Dict[str, Any]:
"""
Search for statutory interpretations (expc).
"""
# Endpoint: /DRF/lawSearch.do?target=expc&query={query}
url = f"{self.BASE_URL}/DRF/lawSearch.do"
params = {
"OC": self.user_id,
"target": "expc",
"type": "XML",
"query": query
}
response = requests.get(url, params=params)
response.raise_for_status()
return xmltodict.parse(response.content)
def get_statutory_interpretation_detail(self, interp_id: str) -> Dict[str, Any]:
"""
Get details of a statutory interpretation.
"""
# Endpoint: /DRF/lawService.do?target=expc&ID={interp_id}
url = f"{self.BASE_URL}/DRF/lawService.do"
params = {
"OC": self.user_id,
"target": "expc",
"type": "XML",
"ID": interp_id # Verified in docs: Uses ID (sometimes MST, will try ID first)
}
response = requests.get(url, params=params)
response.raise_for_status()
return xmltodict.parse(response.content)
def get_law_history(self, law_id: str) -> Dict[str, Any]:
"""
Get revision history of a law.
Returns the list of amendments/revisions with dates and summary.
Endpoint: /DRF/lawService.do?target=lsHistory&MST={law_id}
"""
url = f"{self.BASE_URL}/DRF/lawService.do"
params = {
"OC": self.user_id,
"target": "lsHistory",
"type": "XML",
"MST": law_id
}
response = requests.get(url, params=params)
response.raise_for_status()
return xmltodict.parse(response.content)
def get_old_new_comparison(self, law_id: str) -> Dict[str, Any]:
"""
Get old/new article comparison for a law (신구조문대비).
Returns the comparison table of changed articles.
Endpoint: /DRF/lawService.do?target=lsOnC&MST={law_id}
"""
url = f"{self.BASE_URL}/DRF/lawService.do"
params = {
"OC": self.user_id,
"target": "lsOnC",
"type": "XML",
"MST": law_id
}
response = requests.get(url, params=params)
response.raise_for_status()
return xmltodict.parse(response.content)
if __name__ == "__main__":
# Test connection
try:
client = KoreanLawClient()
print(f"Client initialized with ID: {client.user_id}")
# Try a simple search for "건축법" (Building Act)
print("Testing search_law('건축법')...")
result = client.search_law("건축법")
print("Search successful!")
# Print a snippet of the result to verify structure
if 'LawSearch' in result and 'law' in result['LawSearch']:
laws = result['LawSearch']['law']
if isinstance(laws, list):
print(f"Found {len(laws)} laws. First one: {laws[0].get('법령명한글')}")
else:
print(f"Found 1 law: {laws.get('법령명한글')}")
else:
print("Response structure unexpected:", result.keys())
# Test Legal Term Search
print("\nTesting get_legal_term_list('근로자')...")
term_res = client.get_legal_term_list("근로자")
if 'LawTermSearch' in term_res and 'lawTerm' in term_res['LawTermSearch']:
items = term_res['LawTermSearch']['lawTerm']
if not isinstance(items, list): items = [items]
print(f"Found {len(items)} terms. First: {items[0].get('법령용어명')}")
else:
print("Term search failed/empty.")
# Test Statutory Interpretation Search
print("\nTesting get_statutory_interpretation_list('학교폭력')...")
interp_res = client.get_statutory_interpretation_list("학교폭력")
if 'Expc' in interp_res and 'expc' in interp_res['Expc']:
items = interp_res['Expc']['expc']
# items can be a single dict or list
if not isinstance(items, list): items = [items]
print(f"Found {len(items)} interpretations. First: {items[0].get('안건명')}")
elif 'ExpcSearch' in interp_res:
# Fallback just in case
print("Found ExpcSearch (unexpected but handled)")
else:
print("Interpretation search failed/empty. Raw keys:", interp_res.keys())
except Exception as e:
print(f"Test failed: {e}")