algorhythym commited on
Commit
cabcd28
·
verified ·
1 Parent(s): 6bfcb72

Update mcpserver/server.py

Browse files
Files changed (1) hide show
  1. mcpserver/server.py +107 -107
mcpserver/server.py CHANGED
@@ -1,108 +1,108 @@
1
- from typing import Any
2
- import httpx
3
- from mcp.server.fastmcp import FastMCP
4
-
5
-
6
- # Create an MCP server
7
- mcp = FastMCP(
8
- name="weather",
9
- host="0.0.0.0", # only used for SSE transport (localhost)
10
- port=8000, # only used for SSE transport (set this to any port)
11
- )
12
-
13
- # Constants
14
- NWS_API_BASE = "https://api.weather.gov"
15
- USER_AGENT = "weather-app/1.0"
16
-
17
-
18
- async def make_nws_request(url: str) -> dict[str, Any] | None:
19
- """Make a request to the NWS API with proper error handling."""
20
- headers = {
21
- "User-Agent": USER_AGENT,
22
- "Accept": "application/geo+json"
23
- }
24
- async with httpx.AsyncClient() as client:
25
- try:
26
- response = await client.get(url, headers=headers, timeout=30.0)
27
- response.raise_for_status()
28
- return response.json()
29
- except Exception:
30
- return None
31
-
32
- def format_alert(feature: dict) -> str:
33
- """Format an alert feature into a readable string."""
34
- props = feature["properties"]
35
- return f"""
36
- Event: {props.get('event', 'Unknown')}
37
- Area: {props.get('areaDesc', 'Unknown')}
38
- Severity: {props.get('severity', 'Unknown')}
39
- Description: {props.get('description', 'No description available')}
40
- Instructions: {props.get('instruction', 'No specific instructions provided')}
41
- """
42
-
43
- @mcp.tool()
44
- async def get_alerts(state: str) -> str:
45
- """Get weather alerts for a US state.
46
-
47
- Args:
48
- state: Two-letter US state code (e.g. CA, NY)
49
- """
50
- url = f"{NWS_API_BASE}/alerts/active/area/{state}"
51
- data = await make_nws_request(url)
52
-
53
- if not data or "features" not in data:
54
- return "Unable to fetch alerts or no alerts found."
55
-
56
- if not data["features"]:
57
- return "No active alerts for this state."
58
-
59
- alerts = [format_alert(feature) for feature in data["features"]]
60
- return "\n---\n".join(alerts)
61
-
62
- @mcp.tool()
63
- async def get_forecast(latitude: float, longitude: float) -> str:
64
- """Get weather forecast for a location.
65
-
66
- Args:
67
- latitude: Latitude of the location
68
- longitude: Longitude of the location
69
- """
70
- # First get the forecast grid endpoint
71
- points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
72
- points_data = await make_nws_request(points_url)
73
-
74
- if not points_data:
75
- return "Unable to fetch forecast data for this location."
76
-
77
- # Get the forecast URL from the points response
78
- forecast_url = points_data["properties"]["forecast"]
79
- forecast_data = await make_nws_request(forecast_url)
80
-
81
- if not forecast_data:
82
- return "Unable to fetch detailed forecast."
83
-
84
- # Format the periods into a readable forecast
85
- periods = forecast_data["properties"]["periods"]
86
- forecasts = []
87
- for period in periods[:5]: # Only show next 5 periods
88
- forecast = f"""
89
- {period['name']}:
90
- Temperature: {period['temperature']}°{period['temperatureUnit']}
91
- Wind: {period['windSpeed']} {period['windDirection']}
92
- Forecast: {period['detailedForecast']}
93
- """
94
- forecasts.append(forecast)
95
-
96
- return "\n---\n".join(forecasts)
97
-
98
- # Run the server
99
- if __name__ == "__main__":
100
- transport = "sse"
101
- if transport == "stdio":
102
- print("Running server with stdio transport")
103
- mcp.run(transport="stdio")
104
- elif transport == "sse":
105
- print("Running server with SSE transport")
106
- mcp.run(transport="sse")
107
- else:
108
  raise ValueError(f"Unknown transport: {transport}")
 
1
+ from typing import Any
2
+ import httpx
3
+ from mcp.server.fastmcp import FastMCP
4
+
5
+
6
+ # Create an MCP server
7
+ mcp = FastMCP(
8
+ name="weather",
9
+ host="0.0.0.0", # only used for SSE transport (localhost)
10
+ port=8001, # only used for SSE transport (set this to any port)
11
+ )
12
+
13
+ # Constants
14
+ NWS_API_BASE = "https://api.weather.gov"
15
+ USER_AGENT = "weather-app/1.0"
16
+
17
+
18
+ async def make_nws_request(url: str) -> dict[str, Any] | None:
19
+ """Make a request to the NWS API with proper error handling."""
20
+ headers = {
21
+ "User-Agent": USER_AGENT,
22
+ "Accept": "application/geo+json"
23
+ }
24
+ async with httpx.AsyncClient() as client:
25
+ try:
26
+ response = await client.get(url, headers=headers, timeout=30.0)
27
+ response.raise_for_status()
28
+ return response.json()
29
+ except Exception:
30
+ return None
31
+
32
+ def format_alert(feature: dict) -> str:
33
+ """Format an alert feature into a readable string."""
34
+ props = feature["properties"]
35
+ return f"""
36
+ Event: {props.get('event', 'Unknown')}
37
+ Area: {props.get('areaDesc', 'Unknown')}
38
+ Severity: {props.get('severity', 'Unknown')}
39
+ Description: {props.get('description', 'No description available')}
40
+ Instructions: {props.get('instruction', 'No specific instructions provided')}
41
+ """
42
+
43
+ @mcp.tool()
44
+ async def get_alerts(state: str) -> str:
45
+ """Get weather alerts for a US state.
46
+
47
+ Args:
48
+ state: Two-letter US state code (e.g. CA, NY)
49
+ """
50
+ url = f"{NWS_API_BASE}/alerts/active/area/{state}"
51
+ data = await make_nws_request(url)
52
+
53
+ if not data or "features" not in data:
54
+ return "Unable to fetch alerts or no alerts found."
55
+
56
+ if not data["features"]:
57
+ return "No active alerts for this state."
58
+
59
+ alerts = [format_alert(feature) for feature in data["features"]]
60
+ return "\n---\n".join(alerts)
61
+
62
+ @mcp.tool()
63
+ async def get_forecast(latitude: float, longitude: float) -> str:
64
+ """Get weather forecast for a location.
65
+
66
+ Args:
67
+ latitude: Latitude of the location
68
+ longitude: Longitude of the location
69
+ """
70
+ # First get the forecast grid endpoint
71
+ points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
72
+ points_data = await make_nws_request(points_url)
73
+
74
+ if not points_data:
75
+ return "Unable to fetch forecast data for this location."
76
+
77
+ # Get the forecast URL from the points response
78
+ forecast_url = points_data["properties"]["forecast"]
79
+ forecast_data = await make_nws_request(forecast_url)
80
+
81
+ if not forecast_data:
82
+ return "Unable to fetch detailed forecast."
83
+
84
+ # Format the periods into a readable forecast
85
+ periods = forecast_data["properties"]["periods"]
86
+ forecasts = []
87
+ for period in periods[:5]: # Only show next 5 periods
88
+ forecast = f"""
89
+ {period['name']}:
90
+ Temperature: {period['temperature']}°{period['temperatureUnit']}
91
+ Wind: {period['windSpeed']} {period['windDirection']}
92
+ Forecast: {period['detailedForecast']}
93
+ """
94
+ forecasts.append(forecast)
95
+
96
+ return "\n---\n".join(forecasts)
97
+
98
+ # Run the server
99
+ if __name__ == "__main__":
100
+ transport = "sse"
101
+ if transport == "stdio":
102
+ print("Running server with stdio transport")
103
+ mcp.run(transport="stdio")
104
+ elif transport == "sse":
105
+ print("Running server with SSE transport")
106
+ mcp.run(transport="sse")
107
+ else:
108
  raise ValueError(f"Unknown transport: {transport}")