Skip to main content
Glama
huanhuang1

Weather MCP Demo

by huanhuang1
README.md
# Weather MCP demo (Python)

This project demonstrates the complete flow requested in the onboarding task:

```text
User query -> sample agent / Codex -> MCP tool -> REST API -> 4-field response
```

It contains three sample REST APIs backed by **live US National Weather Service
(NWS)** data and three matching MCP tools:

| User intent | REST API | MCP tool |
|---|---|---|
| Current weather | `GET /api/weather/current` | `get_weather` |
| 1-7 day forecast | `GET /api/weather/forecast` | `get_forecast` |
| Weather warnings | `GET /api/weather/alerts` | `get_weather_alerts` |

Every API returns exactly four top-level attributes:

```json
{
  "id": "demo-1",
  "location": "Chicago",
  "status": "success",
  "data": {}
}
```

The MCP input schemas intentionally mirror the API query parameters. FastMCP
derives JSON Schema from the Python function type hints and validates tool calls.

## 1. Install

Python 3.11+ is required.

```bash
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e ".[dev]"
```

## 2. Start the sample APIs

Keep this terminal running:

```bash
source .venv/bin/activate
python -m uvicorn weather_mcp.api:app --host 127.0.0.1 --port 8000
```

Useful pages:

- Swagger UI: <http://127.0.0.1:8000/docs>
- OpenAPI JSON: <http://127.0.0.1:8000/openapi.json>

Try an API directly:

```bash
curl "http://127.0.0.1:8000/api/weather/current?id=demo-1&city=Chicago"
```

## 3. Run the sample agent

In a second terminal:

```bash
source .venv/bin/activate
python -m weather_mcp.agent "What is the current weather in Chicago? id: demo-1"
python -m weather_mcp.agent "Give me the 5 day forecast for New York. id: demo-2"
python -m weather_mcp.agent "Are there any severe weather alerts in Miami? id: demo-3"
```

The agent is deliberately deterministic and local, so it needs no model API key.
It still uses a real MCP client session: it launches the MCP server, lists its
tools, selects one from the user intent, and invokes it over stdio.

## 4. Connect it to Codex

First start the REST API as shown above. This checkout already includes
`.codex/config.toml` with the correct absolute paths. Restart/open a new Codex
task in this trusted project so Codex loads the `weather` MCP server.

If the project is moved or cloned elsewhere, copy `.codex/config.toml.example`
to `.codex/config.toml` and replace both absolute paths.

Example prompts:

- "Use the weather tool to get current conditions in Chicago. ID: codex-1."
- "Get the 4 day forecast for New York. ID: codex-2."
- "Are there any active weather alerts in Miami? ID: codex-3."

Codex acts as the intelligent agent/host: it reads the tool names, descriptions,
and input schemas exposed by this server and chooses the appropriate MCP tool.

## 5. Test

```bash
source .venv/bin/activate
pytest -q
```

## Design notes

- `weather_mcp/api.py` is the API layer.
- `weather_mcp/server.py` is the MCP connector sitting on top of the APIs.
- `weather_mcp/agent.py` is a minimal local agent and MCP client.
- `weather_mcp/models.py` defines the stable four-field response contract.
- Weather and alert data comes from `api.weather.gov`.
- City names are geocoded through Open-Meteo's geocoding endpoint because NWS
  accepts coordinates rather than city names.
- NWS covers US locations only. Prefer `City, State` when a name is ambiguous.
- Set `NWS_USER_AGENT` to an application name and contact address in production.
- NWS requests can occasionally fail or time out; the REST layer maps upstream
  failures to clear `502`/`503` responses and MCP returns them as tool errors.
- MCP uses stdio locally; stdout is reserved for protocol traffic.