Skip to main content
Glama
scvcoder

korean-privacy-law-mcp

by scvcoder

get_related_laws

Retrieve the hierarchy of related laws—enforcement decrees, rules, and notices—for a given law using its serial number or law ID.

Instructions

관련 법령·하위 행정규칙 조회 (법제처 lawService · target=lsStmd, 법령 체계도). 본법 → 시행령 → 시행규칙 → 고시·훈령·예규의 상하위 관계와 직접 매핑된 관련법령을 반환. PIPC가 결합법령으로 지정한 관계 외에 법제처 자체 매핑도 포함. mst(권장) 또는 lawId 필요. 다음: get_law_text(lawId·mst)로 본문, search_admin_rule(W2)로 PIPC 고시 본문.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
mstNo법령일련번호 (search_law 결과의 [브래킷] 안 숫자, 권장)
lawIdNo법령ID (search_law 결과의 lawId 필드)

Implementation Reference

  • The main tool definition and handler function. The `getRelatedLaws` export is a Tool object with name='get_related_laws', an async handler that calls the lawService.do API with target=lsStmd to fetch the law system tree, then walks the JSON to extract related laws (상하위법 and 관련법령), deduplicates the base law, groups by type, and returns formatted text with suggestions.
    export const getRelatedLaws: Tool<typeof inputSchema> = {
      name: "get_related_laws",
      description:
        "관련 법령·하위 행정규칙 조회 (법제처 lawService · target=lsStmd, 법령 체계도). " +
        "본법 → 시행령 → 시행규칙 → 고시·훈령·예규의 상하위 관계와 직접 매핑된 관련법령을 반환. " +
        "PIPC가 결합법령으로 지정한 관계 외에 법제처 자체 매핑도 포함. mst(권장) 또는 lawId 필요. " +
        "다음: get_law_text(lawId·mst)로 본문, search_admin_rule(W2)로 PIPC 고시 본문.",
      inputSchema,
    
      async handler(args, client) {
        try {
          if (!args.mst && !args.lawId) {
            throw new ValidationError("mst 또는 lawId 필수");
          }
    
          const extraParams: Record<string, string> = {};
          if (args.mst) extraParams.MST = args.mst;
          else if (args.lawId) extraParams.ID = args.lawId;
    
          const jsonText = await client.fetchApi({
            endpoint: "lawService.do",
            target: "lsStmd",
            type: "JSON",
            extraParams,
          });
    
          let parsed: SystemTreeResponse;
          try {
            parsed = JSON.parse(jsonText) as SystemTreeResponse;
          } catch {
            return notFoundResponse(
              `법령 체계도 응답 파싱 실패 (mst=${args.mst ?? "-"}, lawId=${args.lawId ?? "-"})`,
              [`search_law(query="...") — 유효한 mst·lawId 확인`]
            );
          }
    
          const tree = parsed.법령체계도;
          if (!tree) {
            return notFoundResponse(
              `법령 체계도 데이터 없음 (mst=${args.mst ?? "-"}, lawId=${args.lawId ?? "-"})`,
              [`search_law(query="...") — 유효한 식별자 확인`]
            );
          }
    
          const baseInfo = tree.기본정보 ?? {};
          const baseName = baseInfo.법령명 ?? "(법령명 없음)";
    
          const items: RelatedLawItem[] = [];
          collectInfos(tree.상하위법, "", items);
          collectInfos(tree.관련법령, "관련법령", items);
    
          // 본법 자체 제거 (체계도에 자기 자신이 포함될 수 있음)
          const filtered = items.filter(
            (i) => i.id !== baseInfo.법령ID && i.mst !== baseInfo.법령일련번호
          );
    
          if (filtered.length === 0) {
            return notFoundResponse(`관련 법령·하위 규칙 없음: ${baseName}`, [
              `intelligent_law_search(query="${baseName}") — 키워드로 관련 조문 검색`,
            ]);
          }
    
          let text = `관련 법령·하위 규칙 — ${baseName}\n`;
          text += `총 ${filtered.length}건 (시행령·시행규칙·행정규칙·관련법령)\n\n`;
    
          // type별 그룹핑
          const grouped = new Map<string, RelatedLawItem[]>();
          for (const item of filtered) {
            const list = grouped.get(item.type) ?? [];
            list.push(item);
            grouped.set(item.type, list);
          }
    
          for (const [type, list] of grouped) {
            text += `[${type}] ${list.length}건\n`;
            for (const item of list) {
              text += `  - ${item.name}`;
              if (item.id) text += ` (ID: ${item.id})`;
              if (item.effectiveDate) text += ` · 시행 ${item.effectiveDate}`;
              text += "\n";
            }
            text += "\n";
          }
    
          const firstItem = filtered[0];
          if (firstItem) {
            text = appendSuggestions(text, [
              {
                tool: "get_law_text",
                args: firstItem.mst ? { mst: firstItem.mst } : { lawId: firstItem.id },
                reason: `${firstItem.name} 본문 조회`,
              },
            ]);
          }
          text += `\n${formatLawAttribution(baseName)}`;
    
          return { content: [{ type: "text", text }] };
        } catch (err) {
          return formatToolError(err, "get_related_laws");
        }
      },
    };
  • Zod input schema: accepts optional 'mst' (law serial number) and optional 'lawId' fields, with a refinement ensuring at least one is provided.
    const inputSchema = z
      .object({
        mst: z
          .string()
          .optional()
          .describe("법령일련번호 (search_law 결과의 [브래킷] 안 숫자, 권장)"),
        lawId: z.string().optional().describe("법령ID (search_law 결과의 lawId 필드)"),
      })
      .refine((d) => d.mst || d.lawId, {
        message: "mst 또는 lawId 중 하나는 필수입니다",
      });
  • Import of getRelatedLaws from primitives (line 10) and registration in the ALL_TOOLS array (line 53), making it available as a server tool.
    import { getRelatedLaws } from "./primitives/get-related-laws.js";
    import { getAnnexes } from "./primitives/get-annexes.js";
    import { searchAdminRule } from "./primitives/search-admin-rule.js";
    import { searchPipcDecisions } from "./primitives/search-pipc-decisions.js";
    import { searchConstitutionalDecisions } from "./primitives/search-constitutional-decisions.js";
    import { searchAdminAppeals } from "./primitives/search-admin-appeals.js";
    import { searchInterpretations } from "./primitives/search-interpretations.js";
    import { searchEnglishLaw } from "./primitives/search-english-law.js";
    import { getAdminRuleText } from "./primitives/get-admin-rule-text.js";
    import { getPipcDecisionText } from "./primitives/get-pipc-decision-text.js";
    import { getConstitutionalDecisionText } from "./primitives/get-constitutional-decision-text.js";
    import { getAdminAppealText } from "./primitives/get-admin-appeal-text.js";
    import { getInterpretationText } from "./primitives/get-interpretation-text.js";
    import { getEnglishLawText } from "./primitives/get-english-law-text.js";
    import { compareAdminRuleOldNew } from "./primitives/compare-admin-rule-old-new.js";
    import { getLawHistory } from "./primitives/get-law-history.js";
    import { getHistoricalLaw } from "./primitives/get-historical-law.js";
    import { compareOldNew } from "./primitives/compare-old-new.js";
    import { getThreeTier } from "./primitives/get-three-tier.js";
    import { getArticleChangeHistory } from "./primitives/get-article-change-history.js";
    import { getDelegatedLaws } from "./primitives/get-delegated-laws.js";
    import { getLawSystemTree } from "./primitives/get-law-system-tree.js";
    import { getIntelligentRelatedLaws } from "./primitives/get-intelligent-related-laws.js";
    import { compareArticles } from "./primitives/compare-articles.js";
    import { getLegalTerm } from "./primitives/get-legal-term.js";
    import { getTermArticles } from "./primitives/get-term-articles.js";
    import { getLawAbbreviations } from "./primitives/get-law-abbreviations.js";
    import { getLawTree } from "./primitives/get-law-tree.js";
    // W3 — Layer C corpus
    import { searchPrivacyCorpus } from "./corpus/search-privacy-corpus.js";
    import { searchPrivacyCases } from "./corpus/search-privacy-cases.js";
    import { searchPrivacyGuides } from "./corpus/search-privacy-guides.js";
    // W3 — Layer B+ hints (PIPC 공식 출처 인덱스화)
    import { getSectoralRelatedLaws } from "./hints/get-sectoral-related-laws.js";
    import { getPipcCuratedCorpus } from "./hints/get-pipc-curated-corpus.js";
    // W4 — Validator (4계층 환각 검증)
    import { verifyPipaCitation } from "./validator/verify-pipa-citation.js";
    
    export const ALL_TOOLS: Tool[] = [
      // W1.5
      searchLaw,
      getLawText,
      intelligentLawSearch,
      getRelatedLaws,
      getAnnexes,
  • Helper function `collectInfos` that recursively walks the system tree JSON to collect all '기본정보' nodes, categorizing them by parentKey as type.
    function collectInfos(node: unknown, parentKey: string, out: RelatedLawItem[]): void {
      if (!node || typeof node !== "object") return;
    
      // 배열이면 각 요소를 동일 parentKey로 재귀
      if (Array.isArray(node)) {
        for (const item of node) collectInfos(item, parentKey, out);
        return;
      }
    
      const obj = node as Record<string, unknown>;
    
      // 이 노드 자체에 기본정보가 있으면 항목으로 추가
      if (obj.기본정보 && typeof obj.기본정보 === "object") {
        addInfo(obj.기본정보, parentKey || "기타", out);
      }
    
      // 다른 자식 노드도 walk
      for (const [key, value] of Object.entries(obj)) {
        if (key === "기본정보") continue;
        collectInfos(value, key, out);
      }
    }
  • Helper function `addInfo` that extracts name, id, mst, and effectiveDate from a '기본정보' node and pushes a RelatedLawItem to the output array.
    function addInfo(info: unknown, type: string, out: RelatedLawItem[]): void {
      if (!info || typeof info !== "object") return;
      const i = info as Record<string, unknown>;
    
      const name =
        typeof i.법령명 === "string"
          ? i.법령명
          : typeof i.행정규칙명 === "string"
            ? i.행정규칙명
            : null;
      if (!name) return; // 기본정보 노드가 아닌 다른 객체일 수 있음
    
      out.push({
        type,
        name,
        id: typeof i.법령ID === "string" ? i.법령ID : typeof i.행정규칙ID === "string" ? i.행정규칙ID : "",
        mst:
          typeof i.법령일련번호 === "string"
            ? i.법령일련번호
            : typeof i.행정규칙일련번호 === "string"
              ? i.행정규칙일련번호
              : "",
        effectiveDate: typeof i.시행일자 === "string" ? i.시행일자 : undefined,
      });
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description bears full responsibility for behavioral disclosure. It transparently explains that the tool returns both hierarchical relations and directly mapped related laws, including PIPC and ministry mappings. However, it does not describe the output format or any limits (e.g., pagination, rate limits), and it doesn't explicitly state that it is a read-only operation, though it is implied.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured paragraph. It starts with the tool's purpose, then describes the output scope, parameter requirements, and ends with clear next steps. Every sentence provides useful information without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of legal hierarchy and the large number of sibling tools, the description covers the essential context: what the tool returns, what it includes, parameter choices, and subsequent steps. There is no output schema, but the description sufficiently informs an agent how to use the tool. Minor omission: it could detail the exact output fields, but the next steps compensate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already covers both parameters (mst, lawId) with descriptions. The description adds that mst is recommended and necessary, but this is redundant with the schema's mention of '권장' (recommended). It also mentions that mst comes from search_law results, which is already in the schema. With 100% schema coverage, the description provides minimal additional value for parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves related laws and subordinate administrative rules, including hierarchical relationships (from primary law to enforcement decrees, rules, and notices). It specifies the scope includes both PIPC-designated combined laws and the ministry's own mappings. This distinguishes it from siblings like get_law_text (text retrieval) and get_law_system_tree (tree structure).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells when to use this tool (to find hierarchical and mapped relationships) and provides clear next steps: after obtaining related laws, use get_law_text for the law text and search_admin_rule for PIPC notices. It also recommends using the 'mst' parameter from search_law results, giving practical guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/scvcoder/korean-privacy-law-mcp'

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