MCP Weather Lab
Hands-on lab for learning MCP servers, transport protocols, and data-layer design using the National Weather Service API: https://api.weather.gov/
Learning goals
- Build MCP tools that call external APIs.
- Understand STDIO vs Streamable HTTP transport.
- Separate server transport logic from data-layer code.
- Connect an MCP client to your server.
- Add resilience for production-style behavior.
Required Weather Tools (Core Scope)
To avoid confusion, the required MCP weather tool set is exactly two tools:
- get_alerts(state: str)
- get_forecast(latitude: float, longitude: float)
Students can be creative with output format and implementation details, but these two tools must exist and be functional in both transports.
Folder layout
- stdio_srv.py: MCP server over stdio transport.
- http_srv.py: MCP server over streamable HTTP transport.
- src/weather_data.py: shared Weather.gov data layer.
- gemini_client.py: optional Gemini + LangChain MCP client.
- solutions/: reference implementations (use only after attempting assignments).
- requirements.txt: lab dependencies.
- .env.example: environment variable template.
Starter vs Solution
- The main files in this folder are student starter files with TODO markers.
- Full reference implementations are in the solutions folder.
- Recommended flow: attempt assignments first, then compare with solutions if blocked.
Setup
- Create and activate a Python virtual environment.
- Install dependencies: pip install -r requirements.txt
- Copy .env.example to .env and set values if needed.
Windows PowerShell example:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
copy .env.example .env
Run
Start STDIO server
python stdio_srv.py
Note: The stdio server is normally launched by an MCP client process. Running it directly is useful only for smoke checks.
Start HTTP server
python http_srv.py
Default HTTP endpoint is http://127.0.0.1:8000/mcp
Run optional Gemini client exercise
python gemini_client.py
To use HTTP mode in the client, set:
- MCP_CLIENT_MODE=http
- MCP_HTTP_URL=http://127.0.0.1:8000/mcp
PowerShell example:
$env:MCP_CLIENT_MODE="http"
$env:MCP_HTTP_URL="http://127.0.0.1:8000/mcp"
python gemini_client.py
Assignments
Implement assignments in these starter files only:
- src/weather_data.py
- stdio_srv.py
- http_srv.py
- gemini_client.py
Assignment 1: Data Layer Implementation (src/weather_data.py)
Goal: implement all Weather.gov API logic in one shared place.
What to do in this file:
- Implement _request_json(url) with headers, timeout, and error handling.
- Implement _format_alert(feature) into readable multiline output.
- Implement get_alerts_for_state(state):
- validate 2-letter state code,
- call /alerts/active/area/{state},
- return user-friendly messages for no data/errors.
- Implement get_forecast_for_coordinates(latitude, longitude):
- call /points/{lat},{lon},
- read forecast URL,
- fetch forecast periods,
- return up to 5 periods with readable formatting.
Deliverable:
- A working src/weather_data.py that returns useful text for both required tools.
Success criteria:
- No transport-specific code here.
- Functions return stable output for valid and invalid input.
Assignment 2: STDIO MCP Wiring (stdio_srv.py)
Goal: expose the two required tools over stdio transport.
What to do in this file:
- Wire get_alerts tool to call get_alerts_for_state.
- Wire get_forecast tool to call get_forecast_for_coordinates.
- Keep logging on stderr only.
- Keep mcp.run(transport="stdio") in main().
Deliverable:
- A working stdio server with both required tools.
Success criteria:
- Tool names and signatures match required scope.
- No Weather.gov request logic duplicated here.
Assignment 3: HTTP MCP Wiring (http_srv.py)
Goal: expose the same two tools over streamable HTTP transport.
What to do in this file:
- Wire get_alerts tool to call get_alerts_for_state.
- Wire get_forecast tool to call get_forecast_for_coordinates.
- Ensure behavior/output is consistent with stdio server.
- Run with streamable HTTP transport.
Deliverable:
- A working HTTP server with both required tools.
Success criteria:
- Same tool behavior as stdio server.
- No Weather.gov request logic duplicated here.
Assignment 4: Client Validation Flow (gemini_client.py)
Goal: use client-side checks to verify your server tools in both transports.
What to do in this file:
- Keep stdio and http client modes functional.
- Confirm tool discovery works in both modes.
- Use Gemini mode only after tool discovery succeeds.
- Update prompt text so it demonstrates both required weather tools.
Deliverable:
- A client script that can validate tools in stdio and HTTP modes.
Success criteria:
- Tools are listed in both modes.
- Gemini call (if key is set) produces weather-related output.
Assignment 5: Reliability Pass (src/weather_data.py)
Goal: make upstream API calls more resilient.
What to do in this file:
- Add retry with backoff for transient failures.
- Improve timeout/error messaging.
- Keep output user-friendly when Weather.gov fails.
Deliverable:
- Improved resilience behavior in src/weather_data.py.
Success criteria:
- Retry behavior is visible in code.
- Failures do not crash server tools.
Assignment 6: Extra Practice - Separate File Inspector Server
Goal: practice stdio MCP with strict local file access boundaries.
What to build:
- Create a new file: file_inspector_stdio_server.py.
- Add tool 1: list file names in configured folder.
- Add tool 2: list file sizes for files in configured folder.
- Folder path must be set in server config only (not client input).
- Log to stderr only.
Deliverable:
- A separate working stdio MCP file-inspector server.
Success criteria:
- Folder boundary enforced on server side.
- Tools return both file names and sizes clearly.
Troubleshooting
1) ModuleNotFoundError or import errors
Symptom:
- Running a server or client fails with missing package errors.
Fix:
- Ensure the venv is activated.
- Reinstall dependencies with pip install -r requirements.txt.
- Confirm python and pip point to the same environment.
2) HTTP MCP server unreachable
Symptom:
- Client cannot connect to http://127.0.0.1:8000/mcp.
Fix:
- Start http_srv.py first.
- Confirm MCP_PORT and MCP_PATH values.
- Check for port conflicts and change MCP_PORT if needed.
3) No tools discovered in client
Symptom:
- Client prints no tools or fails during discovery.
Fix:
- For stdio mode, run client from this folder so it can launch stdio_srv.py.
- For http mode, verify MCP_HTTP_URL exactly matches the server endpoint.
- Check server logs for startup failures.
4) Gemini key not detected
Symptom:
- Client says no Gemini key set.
Fix:
- Set GEMINI_API_KEY or GOOGLE_API_KEY in .env.
- Restart terminal or rerun process after updating environment.
- Verify there are no extra quotes or spaces in key values.
5) Weather.gov errors or empty responses
Symptom:
- Alerts/forecast return no data or request failures.
Fix:
- Use valid US state codes and US coordinates.
- Retry after a short delay; transient issues can happen.
- Verify outbound internet access from your environment.
6) STDIO server behaves strangely
Symptom:
- JSON-RPC parsing errors or unstable client-server interaction.
Fix:
- Do not print to stdout in stdio server code.
- Use stderr for logs.
- Keep tool return values as structured text only.
Suggested grading rubric
- Correctness of MCP tools and schemas: 30%
- Transport understanding and comparison quality: 20%
- Data-layer design and reuse: 25%
- Error handling and resilience: 20%
- Documentation and maintainability: 5%











