krds-mcp-server

VoidLight00/krds-mcp-server

3.2

If you are the rightful owner of krds-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

The KRDS MCP Server is a comprehensive Model Context Protocol server designed for scraping, processing, and analyzing Korean government documents from the KRDS website.

Tools
5
Resources
0
Prompts
0

KRDS MCP ์„œ๋ฒ„ ๐Ÿ‡ฐ๐Ÿ‡ท

KRDS ์›น์‚ฌ์ดํŠธ(https://v04.krds.go.kr)์˜ UI/UX ๋””์ž์ธ ์‹œ์Šคํ…œ์„ ์ถ”์ถœํ•˜๊ณ  ๋ถ„์„ํ•˜๋Š” Model Context Protocol(MCP) ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค. Magic MCP์™€ ์œ ์‚ฌํ•˜๊ฒŒ ๋””์ž์ธ ํŒจํ„ด์„ ์ถ”์ถœํ•˜์—ฌ ๋‹ค์–‘ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๐Ÿš€ ์ฃผ์š” ๊ธฐ๋Šฅ

๋””์ž์ธ ์‹œ์Šคํ…œ MCP ๋„๊ตฌ (Magic MCP ์Šคํƒ€์ผ)

์ด ์„œ๋ฒ„๋Š” KRDS ์›น์‚ฌ์ดํŠธ์˜ ๋””์ž์ธ ์‹œ์Šคํ…œ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ถ„์„ํ•˜๊ณ  ์ถ”์ถœํ•˜์—ฌ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ •๋ถ€ ํ‘œ์ค€ UI๋ฅผ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

๐ŸŽจ 4๊ฐ€์ง€ ํ•ต์‹ฌ ๋„๊ตฌ
  1. analyze_design - KRDS ๋””์ž์ธ ์‹œ์Šคํ…œ ๋ถ„์„

    • ์ƒ‰์ƒ ํŒ”๋ ˆํŠธ ์ถ”์ถœ
    • ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ ๊ทœ์น™ ๋ถ„์„
    • ์—ฌ๋ฐฑ ๋ฐ ๋ ˆ์ด์•„์›ƒ ํŒจํ„ด ํŒŒ์•…
    • UI ์ปดํฌ๋„ŒํŠธ ๋ชฉ๋กํ™”
  2. extract_component - ํŠน์ • UI ์ปดํฌ๋„ŒํŠธ ์ถ”์ถœ

    • ํ—ค๋”, ํ‘ธํ„ฐ, ๋„ค๋น„๊ฒŒ์ด์…˜ ๋“ฑ ์ฃผ์š” ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐ ์ถ”์ถœ
    • HTML ๊ตฌ์กฐ ๋ฐ CSS ์Šคํƒ€์ผ ๋ถ„์„
    • ์ปดํฌ๋„ŒํŠธ๋ณ„ ๋””์ž์ธ ํ† ํฐ ์ถ”์ถœ
    • ์‹ค์ œ ์‚ฌ์šฉ ์˜ˆ์‹œ ํฌํ•จ
  3. get_design_tokens - ๋””์ž์ธ ํ† ํฐ ์ถ”์ถœ

    • CSS ๋ณ€์ˆ˜ ๋ฐ ์ปค์Šคํ…€ ์†์„ฑ ์ถ”์ถœ
    • ์ƒ‰์ƒ ์‹œ์Šคํ…œ (Primary, Secondary, ์ƒํƒœ ์ƒ‰์ƒ)
    • ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ ์Šค์ผ€์ผ (ํฐํŠธ ํฌ๊ธฐ, ํ–‰๊ฐ„, ์ž๊ฐ„)
    • ์—ฌ๋ฐฑ ์‹œ์Šคํ…œ (Spacing, Padding, Margin)
    • ๊ทธ๋ฆผ์ž ๋ฐ ํ…Œ๋‘๋ฆฌ ์Šคํƒ€์ผ
  4. generate_code - ํ”„๋ ˆ์ž„์›Œํฌ๋ณ„ ์ปดํฌ๋„ŒํŠธ ์ฝ”๋“œ ์ƒ์„ฑ

    • React: JSX + CSS/Styled Components/Tailwind
    • Vue: SFC (Single File Component) ํ˜•์‹
    • Angular: TypeScript + ํ…œํ”Œ๋ฆฟ
    • ์ˆœ์ˆ˜ HTML: ๋ฐ”๋‹๋ผ HTML + CSS

์ฃผ์š” ํŠน์ง•

  • ๐Ÿ”„ ์‹ค์‹œ๊ฐ„ ์ถ”์ถœ: KRDS ์›น์‚ฌ์ดํŠธ์—์„œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋””์ž์ธ ์ •๋ณด ์ถ”์ถœ
  • ๐Ÿ›ก๏ธ ํด๋ฐฑ ๋ชจ๋“œ: ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜ ์‹œ ์ •์  ๋””์ž์ธ ํŒจํ„ด ์ œ๊ณต
  • ๐ŸŽฏ ์ •๋ถ€ ํ‘œ์ค€ ์ค€์ˆ˜: ํ•œ๊ตญ ์ •๋ถ€ ์›น ์ ‘๊ทผ์„ฑ ๋ฐ ๋””์ž์ธ ๊ฐ€์ด๋“œ๋ผ์ธ ๋ฐ˜์˜
  • โšก ์„ฑ๋Šฅ ์ตœ์ ํ™”: ์บ์‹ฑ ๋ฐ ์žฌ์‹œ๋„ ๋กœ์ง์œผ๋กœ ์•ˆ์ •์ ์ธ ์„œ๋น„์Šค ์ œ๊ณต
  • ๐Ÿ‡ฐ๐Ÿ‡ท ํ•œ๊ธ€ ์ง€์›: ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ๋ฐ UI ๋ผ๋ฒจ ์™„๋ฒฝ ์ง€์›

๐Ÿ“ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

krds-mcp-server/
โ”œโ”€โ”€ src/                      # ์†Œ์Šค ์ฝ”๋“œ
โ”‚   โ”œโ”€โ”€ server.ts            # MCP ์„œ๋ฒ„ ๋ฉ”์ธ ์ง„์ž…์ 
โ”‚   โ”œโ”€โ”€ tools/               # MCP ๋„๊ตฌ ๊ตฌํ˜„์ฒด
โ”‚   โ”‚   โ”œโ”€โ”€ content-retrieval.ts  # ์ฝ˜ํ…์ธ  ๊ฒ€์ƒ‰ ๋„๊ตฌ
โ”‚   โ”‚   โ”œโ”€โ”€ search.ts        # ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ
โ”‚   โ”‚   โ”œโ”€โ”€ navigation.ts    # ์›น์‚ฌ์ดํŠธ ๋‚ด๋น„๊ฒŒ์ด์…˜
โ”‚   โ”‚   โ”œโ”€โ”€ export.ts        # ๋ฐ์ดํ„ฐ ๋‚ด๋ณด๋‚ด๊ธฐ ๋„๊ตฌ
โ”‚   โ”‚   โ”œโ”€โ”€ image-tools.ts   # ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ
โ”‚   โ”‚   โ””โ”€โ”€ korean-text.ts   # ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ๋ถ„์„
โ”‚   โ”œโ”€โ”€ scraping/            # ์›น ์Šคํฌ๋ž˜ํ•‘ ๋ชจ๋“ˆ
โ”‚   โ”‚   โ”œโ”€โ”€ krds-scraper.ts  # KRDS ๋ฉ”์ธ ์Šคํฌ๋ž˜ํผ
โ”‚   โ”‚   โ”œโ”€โ”€ navigation-crawler.ts  # ๋‚ด๋น„๊ฒŒ์ด์…˜ ํฌ๋กค๋Ÿฌ
โ”‚   โ”‚   โ”œโ”€โ”€ content-integration.ts # ์ฝ˜ํ…์ธ  ํ†ตํ•ฉ
โ”‚   โ”‚   โ””โ”€โ”€ rate-limiter.ts        # ์†๋„ ์ œํ•œ๊ธฐ
โ”‚   โ”œโ”€โ”€ parsing/             # ์ฝ˜ํ…์ธ  ํŒŒ์‹ฑ
โ”‚   โ”‚   โ”œโ”€โ”€ content-parser.ts      # ์ฝ˜ํ…์ธ  ํŒŒ์„œ
โ”‚   โ”‚   โ”œโ”€โ”€ korean-text-processor.ts # ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ํ”„๋กœ์„ธ์„œ
โ”‚   โ”‚   โ”œโ”€โ”€ image-extractor.ts     # ์ด๋ฏธ์ง€ ์ถ”์ถœ๊ธฐ
โ”‚   โ”‚   โ”œโ”€โ”€ metadata-extractor.ts  # ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ถ”์ถœ๊ธฐ
โ”‚   โ”‚   โ””โ”€โ”€ table-parser.ts        # ํ…Œ์ด๋ธ” ํŒŒ์„œ
โ”‚   โ”œโ”€โ”€ cache/               # ์บ์‹ฑ ์‹œ์Šคํ…œ
โ”‚   โ”‚   โ”œโ”€โ”€ cache-manager.ts       # ์บ์‹œ ๊ด€๋ฆฌ์ž
โ”‚   โ”‚   โ”œโ”€โ”€ memory-cache.ts        # ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ
โ”‚   โ”‚   โ”œโ”€โ”€ redis-cache.ts         # Redis ์บ์‹œ
โ”‚   โ”‚   โ”œโ”€โ”€ file-cache.ts          # ํŒŒ์ผ ์บ์‹œ
โ”‚   โ”‚   โ””โ”€โ”€ cache-strategies.ts    # ์บ์‹œ ์ „๋žต
โ”‚   โ”œโ”€โ”€ korean/              # ํ•œ๊ตญ์–ด ์–ธ์–ด ์ฒ˜๋ฆฌ
โ”‚   โ”œโ”€โ”€ types/               # TypeScript ํƒ€์ž… ์ •์˜
โ”‚   โ”‚   โ””โ”€โ”€ index.ts
โ”‚   โ””โ”€โ”€ utils/               # ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜
โ”‚       โ”œโ”€โ”€ config.ts        # ์„ค์ •
โ”‚       โ””โ”€โ”€ logger.ts        # ๋กœ๊น…
โ”œโ”€โ”€ tests/                   # ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ
โ”‚   โ”œโ”€โ”€ unit/               # ๋‹จ์œ„ ํ…Œ์ŠคํŠธ
โ”‚   โ”œโ”€โ”€ integration/        # ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ
โ”‚   โ”œโ”€โ”€ e2e/               # ์—”๋“œํˆฌ์—”๋“œ ํ…Œ์ŠคํŠธ
โ”‚   โ”œโ”€โ”€ helpers/           # ํ…Œ์ŠคํŠธ ์œ ํ‹ธ๋ฆฌํ‹ฐ
โ”‚   โ””โ”€โ”€ mock-data/         # ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ
โ”œโ”€โ”€ docs/                   # ๋ฌธ์„œ
โ”œโ”€โ”€ config/                 # ์„ค์ • ํŒŒ์ผ
โ””โ”€โ”€ dist/                  # ์ปดํŒŒ์ผ๋œ ์ถœ๋ ฅ๋ฌผ

๐Ÿ› ๏ธ ์„ค์น˜ ๋ฐฉ๋ฒ•

์‚ฌ์ „ ์š”๊ตฌ์‚ฌํ•ญ

  • Node.js 18.0.0 ์ด์ƒ
  • npm 9.0.0 ์ด์ƒ
  • TypeScript 5.3.0 ์ด์ƒ
  • Redis (์„ ํƒ์‚ฌํ•ญ, ๋ถ„์‚ฐ ์บ์‹ฑ์šฉ)

๋น ๋ฅธ ์‹œ์ž‘

  1. ์ €์žฅ์†Œ ๋ณต์ œ

    git clone https://github.com/yourusername/krds-mcp-server.git
    cd krds-mcp-server
    
  2. ์ข…์†์„ฑ ์„ค์น˜

    npm install
    
  3. ํ™˜๊ฒฝ ์„ค์ •

    cp .env.example .env
    # .env ํŒŒ์ผ์„ ํŽธ์ง‘ํ•˜์—ฌ ์„ค์ •์„ ์ž…๋ ฅํ•˜์„ธ์š”
    
  4. ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ

    npm run build
    
  5. ์„œ๋ฒ„ ์‹œ์ž‘

    npm start
    

๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •

# ํ•ซ ๋ฆฌ๋กœ๋”ฉ์„ ์‚ฌ์šฉํ•œ ๊ฐœ๋ฐœ ๋ชจ๋“œ ์‹คํ–‰
npm run dev

# ํŠน์ • ์„ค์ •์œผ๋กœ ์‹คํ–‰
NODE_ENV=development LOG_LEVEL=debug npm run dev

Docker ์„ค์ •

# Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ
npm run docker:build

# Docker Compose๋กœ ์‹คํ–‰
docker-compose up -d

# ๋˜๋Š” ๋‹จ์ผ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰
npm run docker:run

โš™๏ธ ์„ค์ •

ํ™˜๊ฒฝ ๋ณ€์ˆ˜

ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— .env ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์„ธ์š”:

# ์„œ๋ฒ„ ์„ค์ •
NODE_ENV=production
PORT=3000
LOG_LEVEL=info

# KRDS ์›น์‚ฌ์ดํŠธ ์„ค์ •
KRDS_BASE_URL=https://v04.krds.go.kr
KRDS_TIMEOUT=30000
KRDS_RETRY_ATTEMPTS=3
KRDS_RETRY_DELAY=1000
KRDS_USER_AGENT=KRDS-MCP-Server/1.0.0

# ์†๋„ ์ œํ•œ ์„ค์ •
KRDS_RATE_LIMIT_ENABLED=true
KRDS_REQUESTS_PER_MINUTE=60
KRDS_CONCURRENT_REQUESTS=5

# Puppeteer ์„ค์ •
PUPPETEER_HEADLESS=true
PUPPETEER_TIMEOUT=30000
PUPPETEER_SLOWMO=0
PUPPETEER_VIEWPORT_WIDTH=1920
PUPPETEER_VIEWPORT_HEIGHT=1080

# ์บ์‹œ ์„ค์ •
CACHE_TYPE=memory,redis,file
CACHE_TTL=3600
CACHE_MAX_SIZE=104857600

# ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ
CACHE_MEMORY_MAX_MB=100
CACHE_MEMORY_CLEANUP_INTERVAL=300

# Redis ์บ์‹œ (์„ ํƒ์‚ฌํ•ญ)
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
REDIS_KEY_PREFIX=krds:

# ํŒŒ์ผ ์บ์‹œ
CACHE_FILE_BASE_DIR=/tmp/krds-cache
CACHE_FILE_MAX_SIZE_MB=500
CACHE_FILE_CLEANUP_INTERVAL=3600

# ํ•œ๊ตญ์–ด ์–ธ์–ด ์ฒ˜๋ฆฌ
KOREAN_PROCESSING_ENABLED=true
KOREAN_STEMMING_ENABLED=true
KOREAN_ROMANIZATION_ENABLED=true
KOREAN_KEYWORD_EXTRACTION_ENABLED=true

# ๋‚ด๋ณด๋‚ด๊ธฐ ์„ค์ •
EXPORT_MAX_FILE_SIZE_MB=50
EXPORT_DEFAULT_FORMAT=json

# ๋ณด์•ˆ ์„ค์ •
CORS_ENABLED=true
CORS_ORIGIN=*
HELMET_ENABLED=true
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_REQUESTS=100

๊ณ ๊ธ‰ ์„ค์ •

์ž์„ธํ•œ ์„ค์ • ์˜ต์…˜์€ ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๐Ÿงช ํ…Œ์ŠคํŠธ

ํ…Œ์ŠคํŠธ ์‹คํ–‰

# ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์‹คํ–‰
npm test

# ํŠน์ • ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ ์‹คํ–‰
npm run test:unit          # ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋งŒ ์‹คํ–‰
npm run test:integration   # ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋งŒ ์‹คํ–‰
npm run test:e2e          # ์—”๋“œํˆฌ์—”๋“œ ํ…Œ์ŠคํŠธ๋งŒ ์‹คํ–‰

# ์ปค๋ฒ„๋ฆฌ์ง€์™€ ํ•จ๊ป˜ ํ…Œ์ŠคํŠธ ์‹คํ–‰
npm run test:coverage

# ๊ฐ์‹œ ๋ชจ๋“œ์—์„œ ํ…Œ์ŠคํŠธ ์‹คํ–‰
npm run test:watch

# ํŠน์ • ํŒจํ„ด์œผ๋กœ ํ…Œ์ŠคํŠธ ์‹คํ–‰
npm test -- --testNamePattern="Korean.*processing"

ํ…Œ์ŠคํŠธ ๊ตฌ์กฐ

  • ๋‹จ์œ„ ํ…Œ์ŠคํŠธ (tests/unit/): ๊ฐœ๋ณ„ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ํ…Œ์ŠคํŠธ
  • ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ (tests/integration/): ๊ตฌ์„ฑ ์š”์†Œ ๊ฐ„์˜ ์ƒํ˜ธ์ž‘์šฉ ํ…Œ์ŠคํŠธ
  • E2E ํ…Œ์ŠคํŠธ (tests/e2e/): ์™„์ „ํ•œ ์›Œํฌํ”Œ๋กœ์™€ MCP ํ”„๋กœํ† ์ฝœ ์ค€์ˆ˜์„ฑ ํ…Œ์ŠคํŠธ

ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ํ…Œ์ŠคํŠธ

ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ์—๋Š” ํฌ๊ด„์ ์ธ ํ•œ๊ตญ์–ด ์–ธ์–ด ์ฒ˜๋ฆฌ ํ…Œ์ŠคํŠธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค:

// ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ํ…Œ์ŠคํŠธ ์˜ˆ์ œ
describe('ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ์ฒ˜๋ฆฌ', () => {
  it('์ •๋ถ€ ์ •์ฑ… ๋ฌธ์„œ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•จ', async () => {
    const koreanText = '๊ต์œก๋ถ€๋Š” ์ƒˆ๋กœ์šด ์ •์ฑ…์„ ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค.';
    const analysis = await koreanProcessor.analyzeText(koreanText);
    
    expect(analysis.keywords).toContain('๊ต์œก๋ถ€');
    expect(analysis.romanized).toBe('gyoyugbuneun saeroun jeongchaegeul balphyohaetsseumnida');
    expect(analysis.sentiment).toBe('positive');
  });
});

์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ

# ์„ฑ๋Šฅ ๋ฒค์น˜๋งˆํฌ ์‹คํ–‰
npm run test:performance

# ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ํ”„๋กœํŒŒ์ผ๋ง
NODE_OPTIONS="--max-old-space-size=2048" npm run test:e2e

๐Ÿ“š MCP ๋„๊ตฌ ๋ฌธ์„œ

์ฝ˜ํ…์ธ  ๊ฒ€์ƒ‰ ๋„๊ตฌ

์ „์ฒด ํ…์ŠคํŠธ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•œ ํ•œ๊ตญ ์ •๋ถ€ ๋ฌธ์„œ ๊ฒ€์ƒ‰.

{
  "name": "retrieve_content",
  "arguments": {
    "url": "https://v04.krds.go.kr/policy/education/2024/plan",
    "includeImages": true,
    "includeAttachments": true,
    "processKoreanText": true
  }
}

๋งค๊ฐœ๋ณ€์ˆ˜:

  • url (๋ฌธ์ž์—ด) - KRDS ๋ฌธ์„œ URL
  • documentId (๋ฌธ์ž์—ด) - URL ๋Œ€์‹  ์‚ฌ์šฉํ•  ๋ฌธ์„œ ์‹๋ณ„์ž
  • includeImages (๋ถˆ๋ฆฐ, ๊ธฐ๋ณธ๊ฐ’: true) - ์ด๋ฏธ์ง€ ์ถ”์ถœ ๋ฐ ์ฒ˜๋ฆฌ
  • includeAttachments (๋ถˆ๋ฆฐ, ๊ธฐ๋ณธ๊ฐ’: true) - ์ฒจ๋ถ€ ํŒŒ์ผ ํฌํ•จ
  • processKoreanText (๋ถˆ๋ฆฐ, ๊ธฐ๋ณธ๊ฐ’: true) - ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ์ฒ˜๋ฆฌ ํ™œ์„ฑํ™”

์‘๋‹ต:

{
  "success": true,
  "document": {
    "id": "krds-doc-2024-edu-001",
    "title": "Educational Policy Development Plan 2024",
    "titleKorean": "2024๋…„ ๊ต์œก์ •์ฑ… ๋ฐœ์ „๋ฐฉ์•ˆ",
    "content": "Full document content...",
    "contentKorean": "ํ•œ๊ตญ์–ด ๋ฌธ์„œ ๋‚ด์šฉ...",
    "metadata": {
      "agency": "Ministry of Education",
      "agencyKorean": "๊ต์œก๋ถ€",
      "keywords": ["education", "policy"],
      "keywordsKorean": ["๊ต์œก", "์ •์ฑ…"],
      "language": "ko"
    },
    "images": [...],
    "attachments": [...]
  },
  "executionTimeMs": 2500
}

๊ฒ€์ƒ‰ ๋„๊ตฌ

๊ณ ๊ธ‰ ํ•œ๊ตญ์–ด ์–ธ์–ด ์ง€์›์„ ํ†ตํ•œ KRDS ๋ฌธ์„œ ๊ฒ€์ƒ‰.

{
  "name": "search_documents",
  "arguments": {
    "query": "๊ต์œก์ •์ฑ…",
    "category": "๊ต์œก",
    "maxResults": 20,
    "sortBy": "date",
    "sortOrder": "desc"
  }
}

๋งค๊ฐœ๋ณ€์ˆ˜:

  • query (๋ฌธ์ž์—ด) - ๊ฒ€์ƒ‰ ์ฟผ๋ฆฌ (ํ•œ๊ตญ์–ด ์ง€์›)
  • category (๋ฌธ์ž์—ด, ์„ ํƒ์‚ฌํ•ญ) - ๊ฒ€์ƒ‰ํ•  ์นดํ…Œ๊ณ ๋ฆฌ (์˜ˆ: "๊ต์œก", "๋ณด๊ฑด", "๊ฒฝ์ œ")
  • maxResults (์ˆซ์ž, ๊ธฐ๋ณธ๊ฐ’: 10) - ์ตœ๋Œ€ ๊ฒฐ๊ณผ ์ˆ˜
  • sortBy (๋ฌธ์ž์—ด, ๊ธฐ๋ณธ๊ฐ’: "relevance") - ์ •๋ ฌ ๊ธฐ์ค€ ("date", "relevance", "title")
  • sortOrder (๋ฌธ์ž์—ด, ๊ธฐ๋ณธ๊ฐ’: "desc") - ์ •๋ ฌ ์ˆœ์„œ ("asc", "desc")

ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ๋ถ„์„ ๋„๊ตฌ

์–ธ์–ดํ•™์  ๊ธฐ๋Šฅ์„ ํฌํ•จํ•œ ๊ณ ๊ธ‰ ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ๋ถ„์„ ์ˆ˜ํ–‰.

{
  "name": "analyze_korean_text",
  "arguments": {
    "texts": ["๊ต์œก๋ถ€๋Š” ์ƒˆ๋กœ์šด ์ •์ฑ…์„ ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค."],
    "includeRomanization": true,
    "includeSentiment": true,
    "extractKeywords": true,
    "analyzeStemming": true
  }
}

๋งค๊ฐœ๋ณ€์ˆ˜:

  • texts (๋ฐฐ์—ด) - ๋ถ„์„ํ•  ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ๋ฐฐ์—ด
  • includeRomanization (๋ถˆ๋ฆฐ, ๊ธฐ๋ณธ๊ฐ’: false) - ๋กœ๋งˆ์ž ๋ณ€ํ™˜ ํฌํ•จ
  • includeSentiment (๋ถˆ๋ฆฐ, ๊ธฐ๋ณธ๊ฐ’: false) - ๊ฐ์ • ๋ถ„์„ ํฌํ•จ
  • extractKeywords (๋ถˆ๋ฆฐ, ๊ธฐ๋ณธ๊ฐ’: true) - ํ‚ค์›Œ๋“œ ์ถ”์ถœ
  • analyzeStemming (๋ถˆ๋ฆฐ, ๊ธฐ๋ณธ๊ฐ’: false) - ์–ด๊ฐ„ ๋ถ„์„ ํฌํ•จ

์‘๋‹ต:

{
  "success": true,
  "analyses": [{
    "originalText": "๊ต์œก๋ถ€๋Š” ์ƒˆ๋กœ์šด ์ •์ฑ…์„ ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค.",
    "romanized": "gyoyugbuneun saeroun jeongchaegeul balphyohaetsseumnida",
    "keywords": ["๊ต์œก๋ถ€", "์ •์ฑ…", "๋ฐœํ‘œ"],
    "stemmed": ["๊ต์œก๋ถ€", "์ƒˆ๋กญ๋‹ค", "์ •์ฑ…", "๋ฐœํ‘œ"],
    "sentiment": "positive",
    "wordCount": 6,
    "characterCount": 19
  }]
}

๋‚ด๋น„๊ฒŒ์ด์…˜ ๋„๊ตฌ

KRDS ์›น์‚ฌ์ดํŠธ ๊ตฌ์กฐ ๋ฐ ์นดํ…Œ๊ณ ๋ฆฌ ํƒ์ƒ‰.

{
  "name": "navigate_site",
  "arguments": {
    "action": "list_categories"
  }
}

{
  "name": "navigate_site", 
  "arguments": {
    "action": "browse_category",
    "category": "education"
  }
}

๋งค๊ฐœ๋ณ€์ˆ˜:

  • action (๋ฌธ์ž์—ด) - ์ˆ˜ํ–‰ํ•  ์ž‘์—… ("list_categories", "browse_category", "get_sitemap")
  • category (๋ฌธ์ž์—ด, ์„ ํƒ์‚ฌํ•ญ) - ํƒ์ƒ‰ํ•  ์นดํ…Œ๊ณ ๋ฆฌ (์˜ˆ: "education", "health", "economy")
  • depth (์ˆซ์ž, ์„ ํƒ์‚ฌํ•ญ) - ํƒ์ƒ‰ ๊นŠ์ด (๊ธฐ๋ณธ๊ฐ’: 2)

๋‚ด๋ณด๋‚ด๊ธฐ ๋„๊ตฌ

๋‹ค์–‘ํ•œ ํ˜•์‹์œผ๋กœ ๋ฌธ์„œ ๋‚ด๋ณด๋‚ด๊ธฐ.

{
  "name": "export_documents",
  "arguments": {
    "documents": [/* ๋ฌธ์„œ ๊ฐ์ฒด๋“ค */],
    "format": "pdf",
    "includeImages": true,
    "filename": "education-policies-2024"
  }
}

๋งค๊ฐœ๋ณ€์ˆ˜:

  • documents (๋ฐฐ์—ด) - ๋‚ด๋ณด๋‚ผ ๋ฌธ์„œ ๊ฐ์ฒด ๋ฐฐ์—ด
  • format (๋ฌธ์ž์—ด) - ๋‚ด๋ณด๋‚ด๊ธฐ ํ˜•์‹ ("json", "csv", "xlsx", "pdf", "xml")
  • includeImages (๋ถˆ๋ฆฐ, ๊ธฐ๋ณธ๊ฐ’: false) - ์ด๋ฏธ์ง€ ํฌํ•จ ์—ฌ๋ถ€
  • filename (๋ฌธ์ž์—ด, ์„ ํƒ์‚ฌํ•ญ) - ์ถœ๋ ฅ ํŒŒ์ผ๋ช…
  • encoding (๋ฌธ์ž์—ด, ๊ธฐ๋ณธ๊ฐ’: "utf-8") - ํ…์ŠคํŠธ ์ธ์ฝ”๋”ฉ

์ง€์› ํ˜•์‹: json, csv, xlsx, pdf, xml

๐Ÿš€ ์„ฑ๋Šฅ

์ตœ์ ํ™” ๊ธฐ๋Šฅ

  • โšก ์—ฐ๊ฒฐ ํ’€๋ง: ๋ธŒ๋ผ์šฐ์ € ์ธ์Šคํ„ด์Šค ๋ฐ HTTP ์—ฐ๊ฒฐ ์žฌ์‚ฌ์šฉ
  • ๐Ÿง  ์ง€๋Šฅํ˜• ์บ์‹ฑ: ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ์ตœ์ ํ™”๋ฅผ ํฌํ•จํ•œ ๋‹ค์ธต ์บ์‹ฑ
  • ๐Ÿ”„ ๋™์‹œ ์ฒ˜๋ฆฌ: ๋ณ‘๋ ฌ ๋ฌธ์„œ ์ฒ˜๋ฆฌ
  • โฐ ์†๋„ ์ œํ•œ: ์„ค์ • ๊ฐ€๋Šฅํ•œ ์ œํ•œ์œผ๋กœ ์ •์ค‘ํ•œ ์Šคํฌ๋ž˜ํ•‘
  • ๐Ÿ—„๏ธ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ: ์ž๋™ ์ •๋ฆฌ ๋ฐ ๋ฆฌ์†Œ์Šค ๋ชจ๋‹ˆํ„ฐ๋ง

์„ฑ๋Šฅ ๋ฒค์น˜๋งˆํฌ

์ตœ์‹  ํ•˜๋“œ์›จ์–ด์—์„œ์˜ ์ผ๋ฐ˜์ ์ธ ์„ฑ๋Šฅ ์ง€ํ‘œ:

์ž‘์—…์‹œ๊ฐ„์ฒ˜๋ฆฌ๋Ÿ‰
๋ฌธ์„œ ๊ฒ€์ƒ‰1.5-3์ดˆ20-40 ๋ฌธ์„œ/๋ถ„
ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ๋ถ„์„50-200ms300-1200 ํ…์ŠคํŠธ/๋ถ„
๊ฒ€์ƒ‰ ์ฟผ๋ฆฌ0.8-2์ดˆ30-75 ์ฟผ๋ฆฌ/๋ถ„
์บ์‹œ ํžˆํŠธ5-20ms3000+ ์—ฐ์‚ฐ/๋ถ„

๋ชจ๋‹ˆํ„ฐ๋ง

# ์„ฑ๋Šฅ ๋ฉ”ํŠธ๋ฆญ ๋ณด๊ธฐ
curl http://localhost:3000/metrics

# ์บ์‹œ ํ†ต๊ณ„ ํ™•์ธ
curl http://localhost:3000/cache/stats

# ๊ฑด๊ฐ• ์ƒํƒœ ํ™•์ธ
curl http://localhost:3000/health

๐Ÿ”ง ๊ฐœ๋ฐœ

์ฝ”๋“œ ํ’ˆ์งˆ

# ๋ฆฐํŒ…
npm run lint
npm run lint:fix

# ํฌ๋งคํŒ…  
npm run format
npm run format:check

# ํƒ€์ž… ๊ฒ€์‚ฌ
npm run typecheck

๋””๋ฒ„๊น…

# ๋””๋ฒ„๊ทธ ๋กœ๊ทธ์™€ ํ•จ๊ป˜ ์‹คํ–‰
LOG_LEVEL=debug npm run dev

# ํŠน์ • ๋””๋ฒ„๊ทธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ํ™œ์„ฑํ™”
DEBUG=krds:scraper,krds:parser npm run dev

# ์„ฑ๋Šฅ ํ”„๋กœํŒŒ์ผ๋ง
NODE_OPTIONS="--inspect" npm run dev

์ƒˆ๋กœ์šด ๋„๊ตฌ ์ถ”๊ฐ€

  1. src/tools/your-tool.ts์— ๋„๊ตฌ ํŒŒ์ผ ์ƒ์„ฑ:
import type { Tool } from '@modelcontextprotocol/sdk/types.js';

export const yourTool: Tool = {
  name: 'your_tool_name',
  description: '๋„๊ตฌ ์„ค๋ช…',
  inputSchema: {
    type: 'object',
    properties: {
      param: { type: 'string', description: '๋งค๊ฐœ๋ณ€์ˆ˜ ์„ค๋ช…' }
    },
    required: ['param']
  }
};

export async function yourToolHandler(params: any, context: ToolContext) {
  // ๊ตฌํ˜„ ์ฝ”๋“œ
}
  1. src/tools/index.ts์— ๋“ฑ๋ก
  2. tests/unit/tools/your-tool.test.ts์— ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€
  3. ๋ฌธ์„œ ์—…๋ฐ์ดํŠธ

๐Ÿšข ๋ฐฐํฌ

ํ”„๋กœ๋•์…˜ ๋ฐฐํฌ

# ํ”„๋กœ๋•์…˜์šฉ ๋นŒ๋“œ
npm run build

# ํ”„๋กœ๋•์…˜ ์„œ๋ฒ„ ์‹œ์ž‘
NODE_ENV=production npm start

# ๋˜๋Š” PM2 ์‚ฌ์šฉ
pm2 start ecosystem.config.js

Docker ๋ฐฐํฌ

# ์ด๋ฏธ์ง€ ๋นŒ๋“œ
docker build -t krds-mcp-server .

# ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰
docker run -d \
  --name krds-mcp-server \
  -p 3000:3000 \
  -e NODE_ENV=production \
  -e REDIS_HOST=redis \
  krds-mcp-server

ํ™˜๊ฒฝ๋ณ„ ์„ค์ •

  • ๊ฐœ๋ฐœ: .env.development
  • ํ…Œ์ŠคํŠธ: .env.test
  • ์Šคํ…Œ์ด์ง•: .env.staging
  • ํ”„๋กœ๋•์…˜: .env.production

๊ฑด๊ฐ• ์ƒํƒœ ๊ฒ€์‚ฌ

์„œ๋ฒ„๋Š” ๊ฑด๊ฐ• ์ƒํƒœ ๊ฒ€์‚ฌ ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค:

# ๊ธฐ๋ณธ ๊ฑด๊ฐ• ์ƒํƒœ ๊ฒ€์‚ฌ
GET /health

# ์ƒ์„ธ ๊ฑด๊ฐ• ์ƒํƒœ ๊ฒ€์‚ฌ
GET /health/detailed

# ์ค€๋น„ ์ƒํƒœ ๊ฒ€์‚ฌ
GET /ready

๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ๋กœ๊น…

  • ๊ตฌ์กฐํ™”๋œ ๋กœ๊น…: ์ƒ๊ด€๊ด€๊ณ„ ID๊ฐ€ ํฌํ•จ๋œ JSON ๋กœ๊ทธ
  • ๋ฉ”ํŠธ๋ฆญ: Prometheus ํ˜ธํ™˜ ๋ฉ”ํŠธ๋ฆญ ์—”๋“œํฌ์ธํŠธ
  • ์˜ค๋ฅ˜ ์ถ”์ : ์Šคํƒ ํŠธ๋ ˆ์ด์Šค๋ฅผ ํฌํ•จํ•œ ํฌ๊ด„์ ์ธ ์˜ค๋ฅ˜ ๋กœ๊น…
  • ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง: ์š”์ฒญ ์‹œ๊ฐ„ ๋ฐ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ๋Ÿ‰

๐Ÿค ๊ธฐ์—ฌ

๊ธฐ์—ฌ๋ฅผ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค! ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๊ธฐ์—ฌ์ž๋ฅผ ์œ„ํ•œ ๋น ๋ฅธ ์‹œ์ž‘

  1. ์ €์žฅ์†Œ ํฌํฌ
  2. ๊ธฐ๋Šฅ ๋ธŒ๋žœ์น˜ ์ƒ์„ฑ: git checkout -b feature/amazing-feature
  3. ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ž‘์„ฑ
  4. ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€
  5. ๋ชจ๋“  ํ…Œ์ŠคํŠธ ํ†ต๊ณผ ํ™•์ธ: npm test
  6. ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ปค๋ฐ‹: git commit -m 'Add amazing feature'
  7. ๋ธŒ๋žœ์น˜์— ํ‘ธ์‹œ: git push origin feature/amazing-feature
  8. Pull Request ์—ด๊ธฐ

๊ฐœ๋ฐœ ๊ฐ€์ด๋“œ๋ผ์ธ

  • TypeScript ๋ชจ๋ฒ” ์‚ฌ๋ก€ ์ค€์ˆ˜
  • ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ํฌ๊ด„์ ์ธ ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€
  • API ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ๋ฌธ์„œ ์—…๋ฐ์ดํŠธ
  • ๋ฐ˜์‹ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ์‚ฌ์šฉ
  • ํ•œ๊ตญ์–ด ํ…์ŠคํŠธ ์ฒ˜๋ฆฌ๊ฐ€ ์ œ๋Œ€๋กœ ํ…Œ์ŠคํŠธ๋˜๋„๋ก ๋ณด์žฅ

๐Ÿ“„ ๋ผ์ด์„ ์Šค

MIT ๋ผ์ด์„ ์Šค - ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํŒŒ์ผ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

๐Ÿ› ๋ฌธ์ œ ๋ฐ ์ง€์›

๐Ÿ“– ์ถ”๊ฐ€ ๋ฌธ์„œ

๐Ÿ™ ๊ฐ์‚ฌ ์ธ์‚ฌ

  • KRDS ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค๋ฅผ ์ œ๊ณตํ•ด์ฃผ์‹  ํ•œ๊ตญ ์ •๋ถ€
  • MCP SDK ๊ฐœ๋ฐœ์ž๋“ค๊ณผ ์ปค๋ฎค๋‹ˆํ‹ฐ
  • ํ•œ๊ตญ์–ด ์–ธ์–ด ์ฒ˜๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์œ ์ง€๋ณด์ˆ˜์ž๋“ค
  • ์˜คํ”ˆ์†Œ์Šค ํ…Œ์ŠคํŠธ ๋ฐ ๊ฐœ๋ฐœ ๋„๊ตฌ๋“ค
  • ๊ธฐ์—ฌ์ž๋“ค๊ณผ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฉค๋ฒ„๋“ค

ํ•œ๊ตญ ์ •๋ถ€ ๋ฐ์ดํ„ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ์œ„ํ•ด โค๏ธ์œผ๋กœ ์ œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค