블로그 (Blog)/개발로그 (Devlogs)
날씨 정보 MCP 서버
티클러
2026. 4. 29. 12:43
FastMCP로 구현함..
from mcp.server.fastmcp import FastMCP
import httpx
from datetime import datetime
from geopy.geocoders import Nominatim
# FastMCP 서버 초기화
mcp = FastMCP("Weather Server")
def get_weather_description(code: int) -> str:
"""WMO 날씨 코드를 한글 설명으로 변환"""
weather_codes = {
0: "맑음",
1: "대체로 맑음",
2: "부분적으로 흐림",
3: "흐림",
45: "안개",
48: "서리 안개",
51: "가벼운 이슬비",
53: "보통 이슬비",
55: "강한 이슬비",
61: "약한 비",
63: "보통 비",
65: "강한 비",
71: "약한 눈",
73: "보통 눈",
75: "강한 눈",
77: "진눈깨비",
80: "약한 소나기",
81: "보통 소나기",
82: "강한 소나기",
85: "약한 눈 소나기",
86: "강한 눈 소나기",
95: "뇌우",
96: "약한 우박을 동반한 뇌우",
99: "강한 우박을 동반한 뇌우",
}
return weather_codes.get(code, f"알 수 없는 날씨 (코드: {code})")
@mcp.tool()
async def get_weather(region: str) -> str:
"""
주소로 검색하여 현재 날씨 정보를 가져옵니다. (예: 서울특별시 강남구 역삼동)
Args:
region: 주소
Returns:
날씨 정보 문자열
"""
geolocator = Nominatim(user_agent="SouthKorea")
location = geolocator.geocode(region)
if location:
print(f"위도: {location.latitude}, 경도: {location.longitude}")
else:
return f"'{region}' 주소를 찾을수 없습니다."
try:
# Open-Meteo API 사용 (무료, API 키 불필요)
url = "https://api.open-meteo.com/v1/forecast"
params = {
"latitude": location.latitude,
"longitude": location.longitude,
"current": "temperature_2m,relative_humidity_2m,weather_code,wind_speed_10m",
"timezone": "Asia/Seoul"
}
async with httpx.AsyncClient() as client:
response = await client.get(url, params=params)
response.raise_for_status()
data = response.json()
current = data["current"]
temp = current["temperature_2m"]
humidity = current["relative_humidity_2m"]
wind_speed = current["wind_speed_10m"]
weather_code = current["weather_code"]
weather_description = get_weather_description(weather_code)
result = f"""
{location} 날씨 정보
━━━━━━━━━━━━━━━━━━━━
온도: {temp}°C
습도: {humidity}%
풍속: {wind_speed} km/h
날씨: {weather_description}
━━━━━━━━━━━━━━━━━━━━
조회 시간: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
"""
return result.strip()
except Exception as e:
return f"날씨 정보를 가져오는 중 오류가 발생했습니다: {str(e)}"
def main():
mcp.run()
if __name__ == "__main__":
main()
테스트..
