π Nara Market FastMCP 2.0 Server
νκ΅ μ λΆμ‘°λ¬(G2B) λ° λλΌμ₯ν° μΌνλͺ° λ°μ΄ν°λ₯Ό μμ§νλ FastMCPμλ²μ λλ€.
π οΈ μ¬μ© κ°λ₯ν MCP λꡬ (μ΄ 15κ°)
ποΈ κΈ°λ³Έ API νΈμΆ λꡬ (4κ°)
| Tool | κΈ°λ₯ | μ§μ API |
|---|---|---|
call_public_data_standard_api | 곡곡λ°μ΄ν°κ°λ°©νμ€ API νΈμΆ | μ μ°°κ³΅κ³ , λμ°°μ 보, κ³μ½μ 보 λ± |
call_procurement_statistics_api | 곡곡쑰λ¬ν΅κ³μ 보 API νΈμΆ | μ 체/κΈ°κ΄λ³/κΈ°μ λ³ μ‘°λ¬ ν΅κ³ |
call_product_list_api | λ¬Όνλͺ©λ‘μ 보 API νΈμΆ | μνλΆλ₯, λ¬Όνμ 보 λ± |
call_shopping_mall_api | μ’ ν©μΌνλͺ°νλͺ©μ 보 API νΈμΆ | MAS κ³μ½ μνμ 보 |
π€ AI μΉν κ°νΈ λꡬ (4κ°)
| Tool | κΈ°λ₯ | νΉμ§ |
|---|---|---|
get_recent_bid_announcements | μ΅κ·Ό μ μ°°κ³΅κ³ μ‘°ν | νκΈ μ 무ꡬλΆ, μλ λ μ§ κ³μ° |
get_successful_bids_by_business_type | μ 무ꡬλΆλ³ λμ°°μ 보 μ‘°ν | νκΈ μ λ ₯, μλ μ½λ λ³ν |
get_procurement_statistics_by_year | μ°λλ³ μ‘°λ¬ν΅κ³ μ‘°ν | κ°λ¨ν μ°λ μ λ ₯ |
search_shopping_mall_products | μΌνλͺ° μ ν κ²μ | μ νλͺ /μ 체λͺ κ²μ |
π§ κ³ κΈ λΆμ λꡬ (4κ°)
| Tool | κΈ°λ₯ | μ©λ |
|---|---|---|
get_all_api_services_info | μ 체 API μλΉμ€ μ 보 | μ¬μ© κ°λ₯ν λͺ¨λ μλΉμ€ λ° μ€νΌλ μ΄μ μ‘°ν |
get_api_operations | μλΉμ€λ³ μ€νΌλ μ΄μ λͺ©λ‘ | νΉμ μλΉμ€μ μΈλΆ κΈ°λ₯ νμΈ |
call_api_with_pagination_support | νμ΄μ§ μ§μ API νΈμΆ | λλ λ°μ΄ν° μ‘°ν λ° νμ κ°μ΄λ |
get_data_exploration_guide | λ°μ΄ν° νμ κ°μ΄λ | νλΌλ―Έν° μ‘°ν© λ° κ²μ μ λ΅ μ 곡 |
π¦ κΈ°λ³Έ κΈ°λ₯ λꡬ (3κ°)
| Tool | κΈ°λ₯ | μ€λͺ |
|---|---|---|
crawl_list | λλΌμ₯ν° μν λͺ©λ‘ μ‘°ν | κΈ°λ³Έ μν 리μ€νΈ μμ§ |
get_detailed_attributes | μν μμΈ μμ± μ‘°ν | κ°λ³ μνμ μΈλΆ μ 보 |
server_info | μλ² μ 보 | λ²μ λ° μ¬μ© κ°λ₯ν λꡬ λͺ©λ‘ |
π AI κ°μ΄λ 리μμ€ (3κ° Resource + 3κ° Prompt)
MCP Resources
api_parameter_requirements- APIλ³ νμ/μ ν νλΌλ―Έν° κ°μ΄λparameter_value_examples- νλΌλ―Έν° κ° μμ λ° νμ κ°μ΄λcommon_search_patterns- μμ£Ό μ¬μ©λλ κ²μ ν¨ν΄ λ° μ΅μ ν μ λ΅
MCP Prompts
workflow_guide- λ¨κ³λ³ μν¬νλ‘μ° κ°μ΄λ (5κ°μ§ λΆμ μλ리μ€)parameter_selection_guide- νλΌλ―Έν° μ ν λ° μ΅μ ν κ°μ΄λreal_world_query_examples- μ€μ μ 무 μλ리μ€λ³ 쿼리 μμ (8κ°μ§)
π§ μ€μΉ λ° μ€ν
μμ€ν μꡬμ¬ν
- Python: 3.10 μ΄μ
- λ©λͺ¨λ¦¬: μ΅μ 2GB (λλ λ°μ΄ν° μμ§ μ 4GB+ κΆμ₯)
- λμ€ν¬: μμ§ λ°μ΄ν° ν¬κΈ°μ λ°λΌ μ‘°μ
1. λ‘컬 μ€μΉ (κ°λ°/ν μ€νΈ)
# μ μ₯μ ν΄λ‘
git clone <repository-url>
cd naramarketmcp
# νκ²½ μ€μ
cp .env.example .env
# .env νμΌμμ NARAMARKET_SERVICE_KEY μ€μ
# μμ‘΄μ± μ€μΉ
pip install -r requirements.txt
# STDIO λͺ¨λλ‘ μ€ν (MCP ν΄λΌμ΄μΈνΈμ©)
python -m src.main
# HTTP μλ² λͺ¨λλ‘ μ€ν (ν
μ€νΈμ©)
export FASTMCP_TRANSPORT=http
export FASTMCP_HOST=127.0.0.1
export FASTMCP_PORT=8000
python -m src.main
2. ν¨ν€μ§ μ€μΉ
# ν¨ν€μ§ μ€μΉ
pip install .
# μ½μ μ€ν¬λ¦½νΈλ‘ μ€ν
naramarket-mcp
# SSE λͺ¨λ μ§μ (μ νμ¬ν)
pip install .[sse]
export FASTMCP_TRANSPORT=sse
naramarket-mcp
3. Docker μ€ν
# μ΄λ―Έμ§ λΉλ
docker build -t naramarket-mcp .
# 컨ν
μ΄λ μ€ν
docker run --rm \
-e NARAMARKET_SERVICE_KEY=your-api-key \
-p 8000:8000 \
naramarket-mcp
π Smithery.ai ν΄λΌμ°λ λ°°ν¬
λΉ λ₯Έ λ°°ν¬
-
Smithery CLI μ€μΉ
npm install -g @smithery/cli -
API ν€ μ€λΉ
- data.go.krμμ λλΌμ₯ν° API ν€ λ°κΈ
- Smithery.ai λμ보λμμ
NARAMARKET_SERVICE_KEYμν¬λ¦Ώ μ€μ
-
λ°°ν¬ μ€ν
./deploy.sh # λλ μλ: smithery deploy
λ°°ν¬ κ΅¬μ±
- β
smithery.yaml: λ©μΈ λ°°ν¬ μ€μ - β
Dockerfile: νλ‘λμ μ΅μ ν 컨ν μ΄λ - β
.env.example: νκ²½λ³μ ν νλ¦Ώ - β
deploy.sh: μλ λ°°ν¬ μ€ν¬λ¦½νΈ
μ£Όμ λ°°ν¬ νΉμ§
- HTTP Transport: Smithery.aiμ HTTP κΈ°λ° MCP νλ‘ν μ½
- λμ ν¬νΈ:
PORTνκ²½λ³μ μλ κ°μ§ - ν¬μ€μ²΄ν¬:
/mcpμλν¬μΈνΈ λͺ¨λν°λ§ - μν¬λ¦Ώ κ΄λ¦¬: νκ²½λ³μ κΈ°λ° API ν€ μ€μ
- μ€ν μ€μΌμΌλ§: λ‘λμ λ°λ₯Έ 1-10 μΈμ€ν΄μ€ μλ νμ₯
MCP μλν¬μΈνΈ
λ°°ν¬ μλ£ ν λ€μ μλν¬μΈνΈ μ¬μ© κ°λ₯:
GET /mcp- ν¬μ€μ²΄ν¬ λ° μλ² μ 보POST /mcp- MCP λꡬ νΈμΆDELETE /mcp- 리μ /μ 리 μμ
π API μ¬μ© μμ
λλΌμ₯ν° μν λͺ©λ‘ μ‘°ν
{
"method": "tools/call",
"params": {
"name": "crawl_list",
"arguments": {
"category": "λ°μ€ν¬ν±μ»΄ν¨ν°",
"page_no": 1,
"num_rows": 50,
"days_back": 30
}
}
}
G2B μ μ°°κ³΅κ³ μ 보 μ‘°ν
{
"method": "tools/call",
"params": {
"name": "get_bid_announcement_info",
"arguments": {
"num_rows": 20,
"page_no": 1,
"start_date": "20240101",
"end_date": "20240131"
}
}
}
λλ λ°μ΄ν° CSV μμ§ (λΆν μ²λ¦¬)
{
"method": "tools/call",
"params": {
"name": "crawl_to_csv",
"arguments": {
"category": "λ
ΈνΈλΆμ»΄ν¨ν°",
"output_csv": "laptops_2024.csv",
"total_days": 365,
"window_days": 30,
"max_windows_per_call": 2,
"append": false,
"explode_attributes": true
}
}
}
βοΈ νκ²½ λ³μ μ€μ
νμ νκ²½ λ³μ
# λλΌμ₯ν° API μλΉμ€ ν€ (νμ)
NARAMARKET_SERVICE_KEY=your-service-key-here
μ ν νκ²½ λ³μ
# FastMCP Transport λͺ¨λ
FASTMCP_TRANSPORT=stdio # stdio, sse, http
# HTTP λͺ¨λ μ€μ (FASTMCP_TRANSPORT=httpμΌ λ)
FASTMCP_HOST=127.0.0.1
FASTMCP_PORT=8000
# API νκ²½ μ€μ
API_ENVIRONMENT=production # production, development
# λ‘κΉ
λ 벨
LOG_LEVEL=INFO
π λμ©λ λ°μ΄ν° μμ§ κ°μ΄λ
μλμ° λΆν μ λ΅
λλ λ°μ΄ν° μμ§ μ λ©λͺ¨λ¦¬ ν¨μ¨μ±κ³Ό μ¬μμ κ°λ₯μ±μ μν΄ μλμ° λΆν μ μ¬μ©ν©λλ€.
{
"method": "tools/call",
"params": {
"name": "crawl_to_csv",
"arguments": {
"category": "λ°μ€ν¬ν±μ»΄ν¨ν°",
"output_csv": "desktop_full.csv",
"total_days": 365,
"window_days": 30,
"max_windows_per_call": 2,
"max_runtime_sec": 1800,
"append": false
}
}
}
μ΄μ΄λ°κΈ° μ€ν
{
"method": "tools/call",
"params": {
"name": "crawl_to_csv",
"arguments": {
"category": "λ°μ€ν¬ν±μ»΄ν¨ν°",
"output_csv": "desktop_full.csv",
"total_days": 300,
"anchor_end_date": "20240301",
"window_days": 30,
"max_windows_per_call": 2,
"append": true
}
}
}
μ£Όμ νλΌλ―Έν° μ€λͺ
| νλΌλ―Έν° | μ€λͺ | κΈ°λ³Έκ° |
|---|---|---|
total_days | μμ§ν μ΄ μΌμ (μμ) | 365 |
window_days | μλμ° ν¬κΈ° (μΌ) | 30 |
anchor_end_date | μμ κΈ°μ€ λ μ§ (YYYYMMDD) | μ€λ |
max_windows_per_call | νΈμΆλΉ μ΅λ μλμ° μ | 0 (무μ ν) |
max_runtime_sec | μ΅λ μ€ν μκ° (μ΄) | None |
append | κΈ°μ‘΄ νμΌμ μΆκ° μ¬λΆ | false |
explode_attributes | μμ± μ»¬λΌ νΌμΉκΈ° | false |
π νλ‘μ νΈ κ΅¬μ‘°
naramarketmcp/
βββ src/
β βββ __init__.py
β βββ main.py # FastMCP μλ² μ§μ
μ
β βββ core/ # ν΅μ¬ λͺ¨λ
β β βββ __init__.py
β β βββ config.py # μ€μ κ΄λ¦¬
β β βββ models.py # λ°μ΄ν° λͺ¨λΈ
β βββ api/ # API ν΄λΌμ΄μΈνΈ
β β βββ __init__.py
β β βββ client.py # API νΈμΆ λ‘μ§
β βββ services/ # λΉμ¦λμ€ λ‘μ§
β β βββ __init__.py
β β βββ data_service.py # λ°μ΄ν° μ²λ¦¬ μλΉμ€
β βββ tools/ # MCP λꡬ
β βββ __init__.py
β βββ base.py # κΈ°λ³Έ λꡬ ν΄λμ€
β βββ naramarket.py # λλΌμ₯ν° λꡬ
β βββ openapi_tools.py # G2B OpenAPI λꡬ
βββ tests/ # ν
μ€νΈ μ½λ
βββ deployments/ # λ°°ν¬ μ€μ
βββ .env.example # νκ²½λ³μ ν
νλ¦Ώ
βββ .gitignore
βββ Dockerfile # 컨ν
μ΄λ μ΄λ―Έμ§
βββ deploy.sh # λ°°ν¬ μ€ν¬λ¦½νΈ
βββ pyproject.toml # νλ‘μ νΈ μ€μ
βββ requirements.txt # μμ‘΄μ±
βββ smithery.yaml # Smithery λ°°ν¬ μ€μ
βββ README.md # νλ‘μ νΈ λ¬Έμ
π§ λ¬Έμ ν΄κ²°
μΌλ°μ μΈ λ¬Έμ
1. API ν€ μ€λ₯
Error: Missing or invalid NARAMARKET_SERVICE_KEY
ν΄κ²°λ°©λ²: .env νμΌ λλ νκ²½λ³μμ μ¬λ°λ₯Έ API ν€ μ€μ
2. λ©λͺ¨λ¦¬ λΆμ‘±
MemoryError: Unable to allocate array
ν΄κ²°λ°©λ²: window_days μ€μ΄κΈ°, max_windows_per_call κ°μ
3. λ€νΈμν¬ νμμμ
requests.exceptions.Timeout
ν΄κ²°λ°©λ²: max_runtime_sec μ€μ , μ¬μμ κ°λ₯ν λ°°μΉλ‘ λΆν
λ‘κ·Έ λΆμ
# λ‘κ·Έ λ 벨 μ‘°μ
export LOG_LEVEL=DEBUG
# μ€ν λ‘κ·Έ νμΈ
python -m src.main 2>&1 | tee server.log
μ±λ₯ μ΅μ ν
- λ©λͺ¨λ¦¬: ν° λ°μ΄ν°μ μ CSV μ§μ μ μ₯ μ¬μ©
- λ€νΈμν¬: μ μ ν
window_daysμ€μ μΌλ‘ λ°°μΉ ν¬κΈ° μ‘°μ - λμ€ν¬: SSD μ¬μ© κΆμ₯, μΆ©λΆν μ¬μ κ³΅κ° ν보
π€ κΈ°μ¬ λ°©λ²
κ°λ° νκ²½ μ€μ
# κ°λ° μμ‘΄μ± μ€μΉ
pip install .[dev]
# ν
μ€νΈ μ€ν
pytest tests/
# νμ
체ν¬
mypy src/
κΈ°μ¬ κ°μ΄λλΌμΈ
- μ΄μ μμ±: λ²κ·Έ 리ν¬νΈ λλ κΈ°λ₯ μμ²
- ν¬ν¬ & λΈλμΉ:
feature/your-feature-nameλΈλμΉ μμ± - κ°λ°: ν μ€νΈ μ½λμ ν¨κ» ꡬν
- ν μ€νΈ: λͺ¨λ ν μ€νΈ ν΅κ³Ό νμΈ
- Pull Request: μμΈν μ€λͺ κ³Ό ν¨κ» PR μμ±
μ½λ μ€νμΌ
- ν¬λ§€ν : Black μ¬μ©
- λ¦°ν : Flake8 μ€μ
- νμ : Type hints νμ
- λ¬Έμ: Docstring μμ±
π λΌμ΄μ μ€
Apache License 2.0 - μμΈν λ΄μ©μ LICENSE νμΌ μ°Έμ‘°
π κ΄λ ¨ λ§ν¬
- Smithery.ai: https://smithery.ai
- FastMCP: https://github.com/jlowin/fastmcp
- λλΌμ₯ν° Open API: https://www.data.go.kr/
- G2B μ μμ‘°λ¬μμ€ν : http://www.g2b.go.kr/
π λ³κ²½ μ΄λ ₯
v0.1.0 (Latest)
- β FastMCP 2.0 μ κ·Έλ μ΄λ
- β Smithery.ai λ°°ν¬ μ§μ μΆκ°
- β G2B OpenAPI 5κ° λꡬ ν΅ν©
- β HTTP Transport μ§μ
- β νλ‘λμ μ€λΉ μλ£
π‘ λ¬Έμμ¬νμ΄λ κΈ°μ μ§μμ΄ νμνμλ©΄ μ΄μλ₯Ό μμ±ν΄ μ£ΌμΈμ.