get_station_observation
Get the latest METAR observation for a specified city from its weather station. Supports NYC, Chicago, Denver, Miami, and LA.
Instructions
Get the latest METAR observation from the settlement station for one city.
Args: city: One of nyc, chicago, denver, miami, la.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| city | Yes |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/weather_edge_mcp/mcp_server.py:70-78 (handler)MCP tool handler for get_station_observation - decorates function with @mcp.tool(), calls get_city, fetch_station_observation, and format_station_observation.
@mcp.tool() def get_station_observation(city: str) -> str: """Get the latest METAR observation from the settlement station for one city. Args: city: One of nyc, chicago, denver, miami, la. """ cfg = get_city(city) return format_station_observation(cfg.key, _run(fetch_station_observation(cfg.key))) - src/weather_edge_mcp/core.py:135-158 (helper)Async function that fetches METAR observation data from aviationweather.gov API, parses the JSON response, and returns transformed result with temp in °C and °F, wind speed, station info, and raw METAR text.
async def fetch_station_observation(city_key: str) -> dict[str, Any]: cached = get_cached(f"station_{city_key}") if cached: return cached cfg = CITIES[city_key] async with httpx.AsyncClient(timeout=10) as client: resp = await client.get(AVIATION_WEATHER_BASE, params={"ids": cfg.metar_station, "format": "json"}) resp.raise_for_status() payload = resp.json() if not payload: raise RuntimeError(f"No METAR observation for {cfg.metar_station}") obs = payload[0] result = { "city": city_key, "station": cfg.station, "icao": cfg.metar_station, "observed_at": obs.get("obsTime") or obs.get("observationTime") or "", "temp_c": obs.get("temp") if obs.get("temp") is not None else obs.get("tempC"), "wind_speed_kt": obs.get("wspd") or obs.get("windSpeed"), "raw": obs.get("rawOb") or obs.get("rawText") or "", } result["temp_f"] = round((float(result["temp_c"]) * 9 / 5) + 32, 1) if result["temp_c"] is not None else None set_cached(f"station_{city_key}", result) return result - src/weather_edge_mcp/core.py:287-295 (helper)Formats the station observation data dict into a human-readable string output (station name, ICAO, timestamp, temp °F, wind, raw METAR).
def format_station_observation(city_key: str, obs: dict[str, Any]) -> str: return ( f"# Station Observation — {CITIES[city_key].label}\n\n" f"Station: {obs['station']} ({obs['icao']})\n" f"Observed at: {obs['observed_at']}\n" f"Temperature: {obs['temp_f']}°F\n" f"Wind: {obs['wind_speed_kt']} kt\n" f"Raw METAR: {obs['raw']}" ) - src/weather_edge_mcp/core.py:19-39 (schema)CityConfig dataclass defines the schema including metar_station field used to identify the settlement station for observations.
@dataclass(frozen=True) class CityConfig: key: str label: str station: str metar_station: str nws_office: str nws_grid_x: int nws_grid_y: int kalshi_series: str sigma: float forecast_bias: float CITIES: dict[str, CityConfig] = { "nyc": CityConfig("nyc", "New York City", "Central Park", "KNYC", "OKX", 33, 37, "KXHIGHNY", 3.0, -1.0), "chicago": CityConfig("chicago", "Chicago", "Midway", "KMDW", "LOT", 76, 73, "KXHIGHCHI", 3.0, -0.5), "denver": CityConfig("denver", "Denver", "Denver", "KDEN", "BOU", 62, 60, "KXHIGHDEN", 4.0, 0.0), "miami": CityConfig("miami", "Miami", "MIA Airport", "KMIA", "MFL", 75, 54, "KXHIGHMIA", 3.5, -3.0), "la": CityConfig("la", "Los Angeles", "Los Angeles Downtown", "KLAX", "LOX", 154, 44, "HIGHLA", 3.5, 0.0), } - src/weather_edge_mcp/mcp_server.py:21-29 (registration)FastMCP server instantiation with 'weather-edge' name and instructions mentioning get_station_observation tool.
mcp = FastMCP( name="weather-edge", instructions=( "Weather Edge MCP Server for calibrated Kalshi weather-market intelligence. " "Use list_cities for supported markets, get_weather_signals for one city, " "get_all_signals for a full scan, get_forecast for raw forecast context, and " "get_station_observation for live settlement-station readings." ), )