VoidLight00/krds-mcp-server
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.
KRDS MCP ์๋ฒ ๐ฐ๐ท
KRDS ์น์ฌ์ดํธ(https://v04.krds.go.kr)์ UI/UX ๋์์ธ ์์คํ ์ ์ถ์ถํ๊ณ ๋ถ์ํ๋ Model Context Protocol(MCP) ์๋ฒ์ ๋๋ค. Magic MCP์ ์ ์ฌํ๊ฒ ๋์์ธ ํจํด์ ์ถ์ถํ์ฌ ๋ค์ํ ํ๋ ์์ํฌ์์ ์ฌ์ฉํ ์ ์๋ ์ปดํฌ๋ํธ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
๐ ์ฃผ์ ๊ธฐ๋ฅ
๋์์ธ ์์คํ MCP ๋๊ตฌ (Magic MCP ์คํ์ผ)
์ด ์๋ฒ๋ KRDS ์น์ฌ์ดํธ์ ๋์์ธ ์์คํ ์ ์ค์๊ฐ์ผ๋ก ๋ถ์ํ๊ณ ์ถ์ถํ์ฌ, ๊ฐ๋ฐ์๊ฐ ์ ๋ถ ํ์ค UI๋ฅผ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋๋ก ์ง์ํฉ๋๋ค.
๐จ 4๊ฐ์ง ํต์ฌ ๋๊ตฌ
-
analyze_design
- KRDS ๋์์ธ ์์คํ ๋ถ์- ์์ ํ๋ ํธ ์ถ์ถ
- ํ์ดํฌ๊ทธ๋ํผ ๊ท์น ๋ถ์
- ์ฌ๋ฐฑ ๋ฐ ๋ ์ด์์ ํจํด ํ์
- UI ์ปดํฌ๋ํธ ๋ชฉ๋กํ
-
extract_component
- ํน์ UI ์ปดํฌ๋ํธ ์ถ์ถ- ํค๋, ํธํฐ, ๋ค๋น๊ฒ์ด์ ๋ฑ ์ฃผ์ ์ปดํฌ๋ํธ ๊ตฌ์กฐ ์ถ์ถ
- HTML ๊ตฌ์กฐ ๋ฐ CSS ์คํ์ผ ๋ถ์
- ์ปดํฌ๋ํธ๋ณ ๋์์ธ ํ ํฐ ์ถ์ถ
- ์ค์ ์ฌ์ฉ ์์ ํฌํจ
-
get_design_tokens
- ๋์์ธ ํ ํฐ ์ถ์ถ- CSS ๋ณ์ ๋ฐ ์ปค์คํ ์์ฑ ์ถ์ถ
- ์์ ์์คํ (Primary, Secondary, ์ํ ์์)
- ํ์ดํฌ๊ทธ๋ํผ ์ค์ผ์ผ (ํฐํธ ํฌ๊ธฐ, ํ๊ฐ, ์๊ฐ)
- ์ฌ๋ฐฑ ์์คํ (Spacing, Padding, Margin)
- ๊ทธ๋ฆผ์ ๋ฐ ํ ๋๋ฆฌ ์คํ์ผ
-
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 (์ ํ์ฌํญ, ๋ถ์ฐ ์บ์ฑ์ฉ)
๋น ๋ฅธ ์์
-
์ ์ฅ์ ๋ณต์
git clone https://github.com/yourusername/krds-mcp-server.git cd krds-mcp-server
-
์ข ์์ฑ ์ค์น
npm install
-
ํ๊ฒฝ ์ค์
cp .env.example .env # .env ํ์ผ์ ํธ์งํ์ฌ ์ค์ ์ ์ ๋ ฅํ์ธ์
-
ํ๋ก์ ํธ ๋น๋
npm run build
-
์๋ฒ ์์
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 ๋ฌธ์ URLdocumentId
(๋ฌธ์์ด) - 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-200ms | 300-1200 ํ ์คํธ/๋ถ |
๊ฒ์ ์ฟผ๋ฆฌ | 0.8-2์ด | 30-75 ์ฟผ๋ฆฌ/๋ถ |
์บ์ ํํธ | 5-20ms | 3000+ ์ฐ์ฐ/๋ถ |
๋ชจ๋ํฐ๋ง
# ์ฑ๋ฅ ๋ฉํธ๋ฆญ ๋ณด๊ธฐ
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
์๋ก์ด ๋๊ตฌ ์ถ๊ฐ
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) {
// ๊ตฌํ ์ฝ๋
}
src/tools/index.ts
์ ๋ฑ๋กtests/unit/tools/your-tool.test.ts
์ ํ ์คํธ ์ถ๊ฐ- ๋ฌธ์ ์ ๋ฐ์ดํธ
๐ข ๋ฐฐํฌ
ํ๋ก๋์ ๋ฐฐํฌ
# ํ๋ก๋์
์ฉ ๋น๋
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 ํธํ ๋ฉํธ๋ฆญ ์๋ํฌ์ธํธ
- ์ค๋ฅ ์ถ์ : ์คํ ํธ๋ ์ด์ค๋ฅผ ํฌํจํ ํฌ๊ด์ ์ธ ์ค๋ฅ ๋ก๊น
- ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง: ์์ฒญ ์๊ฐ ๋ฐ ๋ฆฌ์์ค ์ฌ์ฉ๋
๐ค ๊ธฐ์ฌ
๊ธฐ์ฌ๋ฅผ ํ์ํฉ๋๋ค! ์์ธํ ๋ด์ฉ์ ๋ฅผ ์ฐธ์กฐํ์ธ์.
๊ธฐ์ฌ์๋ฅผ ์ํ ๋น ๋ฅธ ์์
- ์ ์ฅ์ ํฌํฌ
- ๊ธฐ๋ฅ ๋ธ๋์น ์์ฑ:
git checkout -b feature/amazing-feature
- ๋ณ๊ฒฝ ์ฌํญ ์์ฑ
- ์๋ก์ด ๊ธฐ๋ฅ์ ๋ํ ํ ์คํธ ์ถ๊ฐ
- ๋ชจ๋ ํ
์คํธ ํต๊ณผ ํ์ธ:
npm test
- ๋ณ๊ฒฝ ์ฌํญ ์ปค๋ฐ:
git commit -m 'Add amazing feature'
- ๋ธ๋์น์ ํธ์:
git push origin feature/amazing-feature
- Pull Request ์ด๊ธฐ
๊ฐ๋ฐ ๊ฐ์ด๋๋ผ์ธ
- TypeScript ๋ชจ๋ฒ ์ฌ๋ก ์ค์
- ์๋ก์ด ๊ธฐ๋ฅ์ ๋ํ ํฌ๊ด์ ์ธ ํ ์คํธ ์ถ๊ฐ
- API ๋ณ๊ฒฝ์ ๋ํ ๋ฌธ์ ์ ๋ฐ์ดํธ
- ๋ฐ์ ์ปค๋ฐ ๋ฉ์์ง ์ฌ์ฉ
- ํ๊ตญ์ด ํ ์คํธ ์ฒ๋ฆฌ๊ฐ ์ ๋๋ก ํ ์คํธ๋๋๋ก ๋ณด์ฅ
๐ ๋ผ์ด์ ์ค
MIT ๋ผ์ด์ ์ค - ์์ธํ ๋ด์ฉ์ ํ์ผ์ ์ฐธ์กฐํ์ธ์.
๐ ๋ฌธ์ ๋ฐ ์ง์
- ๋ฒ๊ทธ ๋ฆฌํฌํธ: GitHub Issues
- ๊ธฐ๋ฅ ์์ฒญ: GitHub Discussions
- ๋ณด์ ๋ฌธ์ : security@yourserver.com์ผ๋ก ์ด๋ฉ์ผ ์ก๋ถ
๐ ์ถ๊ฐ ๋ฌธ์
๐ ๊ฐ์ฌ ์ธ์ฌ
- KRDS ๋ฐ์ดํฐ ์ก์ธ์ค๋ฅผ ์ ๊ณตํด์ฃผ์ ํ๊ตญ ์ ๋ถ
- MCP SDK ๊ฐ๋ฐ์๋ค๊ณผ ์ปค๋ฎค๋ํฐ
- ํ๊ตญ์ด ์ธ์ด ์ฒ๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์ง๋ณด์์๋ค
- ์คํ์์ค ํ ์คํธ ๋ฐ ๊ฐ๋ฐ ๋๊ตฌ๋ค
- ๊ธฐ์ฌ์๋ค๊ณผ ์ปค๋ฎค๋ํฐ ๋ฉค๋ฒ๋ค
ํ๊ตญ ์ ๋ถ ๋ฐ์ดํฐ ์ปค๋ฎค๋ํฐ๋ฅผ ์ํด โค๏ธ์ผ๋ก ์ ์๋์์ต๋๋ค