Skip to main content
Glama
scvcoder

korean-privacy-law-mcp

by scvcoder

get_annexes

Retrieve annexes, forms, and appendices from Korean statutes by law name. Filter by type to find standard documents like privacy policies and consent forms.

Instructions

법령 별표·서식 목록 (법제처 lawSearch · target=licbyl). 처리방침·동의서 같은 표준양식이 별표·서식에 위치. knd로 종류 필터(별표/서식/부칙). 응답에는 별표일련번호·관련법령ID·PDF 링크 포함 (PDF 본문 추출은 v1.1). 다음: get_law_text(lawId=관련법령ID)로 본문 맥락, search_admin_rule로 행정규칙 별표(W2).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
lawNameYes법령명 (약칭 가능). 별표·서식의 소속 법령.
kndNo종류: 1=별표, 2=서식, 3=부칙별표, 4=부칙서식, 5=전체 (기본)5
displayNo결과 개수 (기본 100)

Implementation Reference

  • The async handler that executes the get_annexes tool logic: resolves law name alias, calls lawSearch.do API with target=licbyl, parses XML response into AnnexItem objects, formats the results into text with PDF links, and suggests follow-up tools (get_law_text). Returns notFoundResponse if no results, formatToolError on exception.
    async handler(args, client) {
      try {
        const resolvedLawName = resolveLawAlias(args.lawName);
        const xml = await client.fetchApi({
          endpoint: "lawSearch.do",
          target: "licbyl",
          extraParams: {
            query: resolvedLawName,
            search: "2", // 해당법령으로 검색 (검증된 lawByl quirk)
            knd: args.knd,
            display: String(args.display),
          },
        });
    
        const result = parseSearchXML<AnnexItem>(
          xml,
          "licBylSearch",
          "licbyl",
          (itemXml) => ({
            별표일련번호: extractTag(itemXml, "별표일련번호"),
            관련법령일련번호: extractTag(itemXml, "관련법령일련번호"),
            관련법령ID: extractTag(itemXml, "관련법령ID"),
            별표번호: extractTag(itemXml, "별표번호"),
            별표명: extractTag(itemXml, "별표명"),
            별표종류: extractTag(itemXml, "별표종류"),
            관련법령명: extractTag(itemXml, "관련법령명"),
            공포일자: extractTag(itemXml, "공포일자"),
            법령종류: extractTag(itemXml, "법령종류"),
            별표서식파일링크: extractTag(itemXml, "별표서식파일링크"),
            별표서식PDF파일링크: extractTag(itemXml, "별표서식PDF파일링크"),
          })
        );
    
        const aliasNote =
          resolvedLawName !== args.lawName ? ` (정규화: "${resolvedLawName}")` : "";
    
        if (result.totalCnt === 0) {
          return notFoundResponse(
            `별표·서식 없음: "${args.lawName}"${aliasNote} (knd=${args.knd})`,
            [
              `get_annexes(lawName="${args.lawName}", knd="5") — 전체 종류 조회`,
              `search_law(query="${args.lawName}") — 법령명 정확성 확인`,
            ]
          );
        }
    
        let text = `별표·서식 — ${args.lawName}${aliasNote}\n`;
        text += `총 ${result.totalCnt}건 중 ${result.items.length}건 표시\n\n`;
    
        for (const item of result.items) {
          // 별표번호는 "000100" 형태 — 앞 0 제거하여 가독성 ("100" → "1")
          const numNormalized = item.별표번호.replace(/^0+/, "") || "0";
          const kind = item.별표종류 ? `[${item.별표종류}] ` : "";
          text += `${kind}별표${numNormalized}: ${item.별표명 || "(이름 없음)"}\n`;
          if (item.관련법령명) text += `  법령: ${item.관련법령명}`;
          if (item.법령종류) text += ` (${item.법령종류})`;
          text += "\n";
          if (item.관련법령ID) text += `  법령ID: ${item.관련법령ID}\n`;
          if (item.공포일자) text += `  공포: ${item.공포일자}\n`;
          const link = item.별표서식PDF파일링크 || item.별표서식파일링크;
          if (link) text += `  파일: https://www.law.go.kr${link}\n`;
          text += "\n";
        }
    
        const firstItem = result.items[0];
        if (firstItem) {
          const sugs: Array<{
            tool: string;
            args: Record<string, unknown>;
            reason: string;
          }> = [];
          if (firstItem.관련법령ID) {
            sugs.push({
              tool: "get_law_text",
              args: { lawId: firstItem.관련법령ID },
              reason: `${firstItem.관련법령명 || resolvedLawName} 본문 맥락 확인`,
            });
          }
          if (sugs.length) text = appendSuggestions(text, sugs);
        }
        text += `\n${formatLawAttribution(resolvedLawName)}`;
    
        return { content: [{ type: "text", text }] };
      } catch (err) {
        return formatToolError(err, "get_annexes");
      }
    },
  • Zod input schema defining three parameters: lawName (string, required), knd (enum of '1','2','3','4','5', default '5'), display (int 1-100, default 100).
    const inputSchema = z.object({
      lawName: z
        .string()
        .min(1)
        .describe("법령명 (약칭 가능). 별표·서식의 소속 법령."),
      knd: z
        .enum(["1", "2", "3", "4", "5"])
        .default("5")
        .describe("종류: 1=별표, 2=서식, 3=부칙별표, 4=부칙서식, 5=전체 (기본)"),
      display: z
        .number()
        .int()
        .min(1)
        .max(100)
        .default(100)
        .describe("결과 개수 (기본 100)"),
    });
  • Import of getAnnexes from ./primitives/get-annexes.js (line 11) and registration in the ALL_TOOLS array at line 54.
    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,
  • AnnexItem interface defining the shape of parsed XML items with fields like 별표일련번호, 관련법령ID, 별표번호, 별표명, 별표종류, PDF file links, etc.
    interface AnnexItem {
      별표일련번호: string;
      관련법령일련번호: string;
      관련법령ID: string;
      별표번호: string;
      별표명: string;
      별표종류: string;
      관련법령명: string;
      공포일자: string;
      법령종류: string;
      별표서식파일링크: string;
      별표서식PDF파일링크: string;
    }
  • Imports used by the get_annexes handler: zod (inputSchema), Tool type, extractTag/parseSearchXML from client, resolveLawAlias, notFoundResponse, formatToolError, appendSuggestions, formatLawAttribution.
    import { z } from "zod";
    import type { Tool } from "../types.js";
    import { extractTag, parseSearchXML } from "../../client/xml-parse.js";
    import { resolveLawAlias } from "../../lib/aliases.js";
    import { notFoundResponse } from "../../lib/not-found.js";
    import { formatToolError } from "../../lib/errors.js";
    import { appendSuggestions } from "../../lib/suggestions.js";
    import { formatLawAttribution } from "../../lib/external-links.js";
Behavior3/5

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

No annotations exist, so the description must carry the burden. It discloses that the operation is a list (read-only) and describes response fields, but does not mention auth, rate limits, or other behavioral traits beyond the basic functionality.

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

Conciseness4/5

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

The description is relatively long but well-structured: purpose, response details, follow-up suggestions. Each sentence contributes value, though minor redundancy in listing types.

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?

No output schema, but the description partially explains response (serial number, law ID, PDF link) and mentions PDF extraction version. It also suggests related tools, providing a complete picture for a list operation.

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?

Schema coverage is 100%, so baseline is 3. The description adds some context to lawName (affiliated statute) and explains knd filter with examples, but does not significantly enhance understanding of parameters beyond the schema.

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 it lists annexes/forms of statutes, specifies the source (법제처 lawSearch), and explains the response content. It distinguishes itself from siblings by suggesting next steps like get_law_text and search_admin_rule.

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

Usage Guidelines4/5

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

Provides context on when to use (for annexes/forms) and explicitly suggests alternative tools for related tasks (e.g., get_law_text for text context). However, it does not explicitly state when not to use this tool.

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