michaelwybraniec/mcp-server-weather
If you are the rightful owner of mcp-server-weather and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
The MCP Server Weather is a microservice that provides weather forecasts and current weather data using the Open-Meteo API, built with FastMCP.
get_forecast
Fetches a daily weather forecast for a given latitude and longitude.
get_current_weather
Fetches current weather data for a given latitude and longitude.
MCP Server Weather
A simple weather microservice built with FastMCP, providing weather forecasts and current weather data using the Open-Meteo API.
Table of Contents
- Features
- Requirements
- Installation
- Usage
- API & Tool Schema
- Project Structure
- Architecture
- Tutorial
- Contributing
- License
- Author
Features
- Get weather forecast for any location (latitude/longitude)
- Get current weather for any location (latitude/longitude)
- Asynchronous HTTP requests for fast responses
- Easy integration as an MCP tool
Requirements
- Python >= 3.13
- httpx >= 0.28.1
- mcp[cli] >= 1.9.2
Installation
- Clone the repository:
git clone https://github.com/yourusername/mcp-server-weather.git cd mcp-server-weather
- (Optional) Create and activate a virtual environment:
python3 -m venv .venv source .venv/bin/activate
- Install dependencies:
pip install -r requirements.txt # or, if using pyproject.toml pip install .
Usage
Run the server:
python server.py
The server exposes two main tools:
1. Get Forecast
Fetches a daily weather forecast for a given latitude and longitude.
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str
- Returns: Formatted string with daily max/min temperature, precipitation, and weather code.
Example Output:
Date: 2024-06-01
Max Temperature: 22°C
Min Temperature: 14°C
Precipitation: 0.5 mm
Weather Code: 2
---
Date: 2024-06-02
Max Temperature: 20°C
Min Temperature: 13°C
Precipitation: 1.2 mm
Weather Code: 3
2. Get Current Weather
Fetches current weather data for a given latitude and longitude.
@mcp.tool()
async def get_current_weather(latitude: float, longitude: float) -> str
- Returns: JSON string with current weather details (temperature, wind, humidity, etc.)
Example Output:
{
"current": {
"temperature_2m": 21.3,
"is_day": 1,
"showers": 0.0,
"cloud_cover": 45,
"wind_speed_10m": 5.2,
"wind_direction_10m": 180,
"pressure_msl": 1012.3,
"snowfall": 0.0,
"precipitation": 0.0,
"relative_humidity_2m": 60,
"apparent_temperature": 21.0,
"rain": 0.0,
"weather_code": 2,
"surface_pressure": 1012.3,
"wind_gusts_10m": 8.0
}
}
API & Tool Schema
get_forecast
- Input:
latitude
(float)longitude
(float)
- Output:
- Formatted string with daily weather data (see example above)
get_current_weather
- Input:
latitude
(float)longitude
(float)
- Output:
- JSON object with current weather data (see example above)
Project Structure
.
āāā server.py # Main server code, defines weather tools
āāā pyproject.toml # Project metadata and dependencies
āāā README.md # Project documentation
āāā project.md # Project code summary
āāā .gitignore # Git ignore file
āāā .python-version # Python version file
āāā uv.lock # Lock file for uv package manager
āāā .venv/ # Virtual environment (not committed)
āāā __pycache__/ # Python cache files
Architecture
graph TD;
A[Client (Claude Desktop, etc)] -- stdio --> B(MCP Server: server.py)
B -- HTTPX async requests --> C(Open-Meteo API)
B -- Exposes tools --> D[LLM/Client]
B -- Returns weather data --> A
- Client: Connects to the MCP server via stdio (e.g., Claude Desktop)
- MCP Server: Handles requests, exposes tools, fetches data from Open-Meteo
- Open-Meteo API: Provides weather and forecast data
- LLM/Client: Consumes the data and generates responses
Tutorial
Creating an MCP Server Using Python and the Open-Meteo API
MCP servers extend the capabilities of language models by connecting them to data sources and services.
MCP servers expose three main primitives:
Resources (client-controlled)
- Exposes data to be used as context to clients on request.
- Use a resource when you want to passively expose data or content to an MCP client and let the client choose when to access it.
Tools (model-controlled)
- Exposes executable functionality to client models.
- Use a tool when you want the client to perform an action, for example to request content from an API, transform data, or send an email.
Prompts (user-controlled)
- Exposes reusable prompts and workflows to users.
- Use a prompt when you want the client to surface prompts and workflows to the user, for example to streamline interaction with a resource or tool.
Example: Weather Data to Natural Language
LLMs are great for transforming data into natural language. For example, they can translate weather data like temperature, wind speed, dew point, etc. into descriptions of what the weather will feel like and recommendations on what type of clothing to wear.
Step-by-Step Tutorial
0. Requirements
- Claude.ai account (MCP support is available for all account types)
- Claude Desktop app (macOS/Windows)
- Code editor (e.g., VS Code)
- uv (Rust-based Python package manager)
- macOS:
brew install uv
- Windows:
winget install --id=astral-sh.uv -e
- macOS:
1. Setting up the project
To set up your project, open your code editor to the folder you want to add your project. Then follow these steps to set up your project:
Create a new folder called mcp-server-weather using the editor tools or terminal:
mkdir mcp-server-weather
Navigate to the folder in terminal:
cd mcp-server-weather
Initiate a new uv project:
uv init
Create a virtual environment using uv:
uv venv
Start the virtual environment:
source .venv/bin/activate
Note: To stop the virtual environment, run deactivate in terminal.
Install the Python MCP SDK with the CLI extension and additional Python dependencies in the virtual environment:
uv add "mcp[cli]" httpx
2. Building the weather MCP server
Create server.py
and add the following scaffolding:
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
# Initialize FastMCP server
mcp = FastMCP("weather")
# ... your code here ...
if __name__ == "__main__":
mcp.run(transport='stdio')
Add constants and helper function
OPENMETEO_API_BASE = "https://api.open-meteo.com/v1"
USER_AGENT = "weather-app/1.0"
# Helper function to make a request to the Open-Meteo API
async def make_openmeteo_request(url: str) -> dict[str, Any] | None:
"""Make a request to the Open-Meteo API with proper error handling."""
headers = {
"User-Agent": USER_AGENT,
"Accept": "application/json"
}
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None
Add tools
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
# ...
@mcp.tool()
async def get_current_weather(latitude: float, longitude: float) -> str:
"""Get current weather for a location.
Args:
latitude: Latitude of the location
longitude: Longitude of the location
"""
url = f"{OPENMETEO_API_BASE}/forecast?latitude={latitude}&longitude={longitude}¤t=temperature_2m,is_day,showers,cloud_cover,wind_speed_10m,wind_direction_10m,pressure_msl,snowfall,precipitation,relative_humidity_2m,apparent_temperature,rain,weather_code,surface_pressure,wind_gusts_10m"
data = await make_openmeteo_request(url)
if not data:
return "Unable to fetch current weather data for this location."
return data
3. Testing and running the MCP server
mcp dev server.py
- Open http://localhost:5173 in your browser
- Connect, list tools, and test with latitude/longitude
4. Extending the MCP server
- Add more tools (e.g., get_location)
- Use the Open-Meteo Geocoding API for location search
Contributing
Contributions are welcome! Please open an issue or submit a pull request for improvements, bug fixes, or new features.
License
MIT
Author
- ONE-FRONT tech by Michael Wybraniec
- MCP Hands-On by Morten Rand-Hendriksen