MCP weather server
# MCP weather server (Python)
A minimal [Model Context Protocol](https://modelcontextprotocol.io) server with one tool, `get_forecast`, that answers
"what's the weather in a city on a day?" using the free [Open-Meteo](https://open-meteo.com) API (no key needed).
It's the code from the video **How to Build an MCP Server in Python (From Scratch)**: [VIDEO LINK]
```
Claude Desktop --(MCP over stdio)--> weather.py --(HTTPS)--> Open-Meteo
```
## Requirements
- Python 3.10 or newer
- [uv](https://docs.astral.sh/uv/)
- Claude Desktop, or any other MCP host
## Run it
```bash
uv sync
```
Test it on its own in the MCP Inspector (a local web page for trying out servers):
```bash
uv run mcp dev weather.py
```
In the Inspector: **Connect**, then **Tools** and **List Tools**, then pick `get_forecast`, enter a city (`Lisbon`) and a date
within the next 16 days (`YYYY-MM-DD`), and click **Run Tool**.
Or test it from the terminal, the way a host talks to it (lists the tools, then calls the tool twice):
```bash
uv run python check_client.py
```
## Connect it to Claude Desktop
1. Find your full paths: `which uv` (on Windows `where uv`), and `pwd` in this folder.
2. Open Claude Desktop's config file (Claude Desktop: **Settings, Developer, Edit Config**), or create it if it's missing:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
3. Add the `weather` entry from [`claude_desktop_config.example.json`](claude_desktop_config.example.json) inside
`mcpServers`, with your two paths. Keep any servers already there.
4. Quit Claude Desktop completely and reopen it. Ask: *Is it sunny in Lisbon on Saturday?*
Claude asks for your permission before it runs the tool, and shows the arguments it chose.
## If the tool doesn't appear
1. **The path must be absolute.** `--directory` needs the full path to this folder.
2. **Claude may not find `uv`.** Use the full path from `which uv` as `command`.
3. **Nothing may print to stdout.** Over stdio, stdout carries the protocol messages; a stray `print()` breaks them.
Log with `logging` (it goes to stderr) instead.
Claude Desktop's own log for the server is in `~/Library/Logs/Claude/mcp-server-weather.log` (macOS).
## How it works
- `MCPServer("weather")` is the server; `@mcp.tool()` turns `get_forecast` into a tool.
- The type hints (`city: str, day: str`) become the tool's input schema; the docstring becomes the description the model reads.
- The tool looks the city up with Open-Meteo's geocoding API, gets the daily forecast, and returns one short sentence,
such as `Rainy, 20 °C on 2026-11-07.`
- An unknown city returns a message instead of raising an error, so the model can tell the user.
## Credits
Weather data by [Open-Meteo](https://open-meteo.com), free for non-commercial use.
Built with the [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk).
## License
MIT, see [LICENSE](LICENSE).
TDQS
Scored across 1 tool
With a single tool there is nothing to confuse it with; the purpose (daily forecast for a city) is unambiguous. An agent cannot misselect among tools here.
get_forecast follows a clear verb_noun convention, though with only one tool there is no pattern to actually verify. It is readable and predictable, but consistency is untested.
One tool is thin even for a narrowly scoped weather server; users would reasonably expect current conditions or multi-day output. It is not mismatched to the stated purpose, but it is on the sparse edge.
The surface covers only a single-day forecast, with no tool for current conditions, multi-day ranges, alerts, or location lookup/geocoding. These are standard weather operations that agents would commonly need and cannot work around with this set.