weather-mcp
Open-Meteo Weather MCP Server
A Model Context Protocol (MCP) server that provides weather data using the free Open-Meteo API. Built with FastMCP.
No API key required β Open-Meteo is free for non-commercial use.
Features
π Geocoding β Search for any city or location worldwide
π‘οΈ Current Weather β Temperature, humidity, wind, precipitation, pressure
π Daily Forecast β Up to 16 days with high/low temps, UV index, sunrise/sunset
β° Hourly Forecast β Detailed hour-by-hour predictions
ποΈ City Lookup β Convenience tool combining search + weather in one call
π Unit Options β Celsius/Fahrenheit, km/h/mph/knots, mm/inch
Installation
Prerequisites
Python 3.10+
Install from Source
# Clone the repository
git clone <repository-url>
cd weather-mcp
# Create virtual environment
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# or: .venv\Scripts\activate # Windows
# Install in development mode
pip install -e .
# Or install with dev dependencies
pip install -e ".[dev]"Install Dependencies Only
pip install fastmcp httpxQuick Start
Run with CLI Command
weather-mcpRun as Module
python -m weather_mcpRun with Options
weather-mcp --host 0.0.0.0 --port 8080
python -m weather_mcp --host 0.0.0.0 --port 8080Run Programmatically
from weather_mcp import WeatherMCPServer
server = WeatherMCPServer()
server.run()CLI Options
Option | Default | Description |
|
| Host to bind to |
|
| Port to listen on |
|
| Transport type ( |
|
| API request timeout in seconds |
MCP Tools
search_location
Find coordinates for a city or place name.
Parameters:
Name | Type | Default | Description |
| string | required | City name, postal code, or place name |
| int | 5 | Number of results (1-100) |
| string | "en" | Language for results |
Example Response:
{
"results": [
{
"name": "Berlin",
"latitude": 52.52437,
"longitude": 13.41053,
"country": "Germany",
"country_code": "DE",
"admin1": "Berlin",
"timezone": "Europe/Berlin",
"population": 3426354,
"elevation": 74.0
}
]
}get_current_weather
Get current weather conditions for a location.
Parameters:
Name | Type | Default | Description |
| float | required | Latitude coordinate |
| float | required | Longitude coordinate |
| string | "celsius" |
|
| string | "kmh" |
|
| string | "auto" | Timezone (e.g., |
Example Response:
{
"location": {
"latitude": 52.52,
"longitude": 13.41,
"elevation": 38.0,
"timezone": "Europe/Berlin"
},
"time": "2024-01-15T14:00",
"temperature": {
"value": 5.2,
"feels_like": 2.1,
"unit": "Β°C"
},
"humidity": {"value": 75, "unit": "%"},
"conditions": {
"code": 3,
"description": "Overcast",
"is_day": true
},
"precipitation": {
"total": 0.0,
"rain": 0.0,
"snowfall": 0.0,
"unit": "mm"
},
"wind": {
"speed": 15.5,
"direction": 270,
"gusts": 25.0,
"unit": "km/h"
},
"pressure": {
"sea_level": 1013.25,
"surface": 1010.0,
"unit": "hPa"
},
"cloud_cover": {"value": 100, "unit": "%"}
}get_weather_forecast
Get daily weather forecast for a location.
Parameters:
Name | Type | Default | Description |
| float | required | Latitude coordinate |
| float | required | Longitude coordinate |
| int | 7 | Number of days (1-16) |
| string | "celsius" |
|
| string | "kmh" |
|
| string | "mm" |
|
| string | "auto" | Timezone |
Example Response:
{
"location": {...},
"forecast_days": 7,
"daily": [
{
"date": "2024-01-15",
"conditions": {
"code": 3,
"description": "Overcast"
},
"temperature": {
"max": 8.5,
"min": 2.1,
"unit": "Β°C"
},
"sun": {
"sunrise": "2024-01-15T07:45",
"sunset": "2024-01-15T16:30",
"daylight_seconds": 31500,
"sunshine_seconds": 12000
},
"uv_index": 1.5,
"precipitation": {
"total": 2.5,
"probability": 60,
"unit": "mm"
},
"wind": {
"speed": 20.0,
"direction": 225,
"gusts": 35.0,
"unit": "km/h"
}
}
]
}get_hourly_forecast
Get detailed hourly weather forecast.
Parameters:
Name | Type | Default | Description |
| float | required | Latitude coordinate |
| float | required | Longitude coordinate |
| int | 2 | Number of days (1-16) |
| string | "celsius" |
|
| string | "kmh" |
|
| string | "mm" |
|
| string | "auto" | Timezone |
Example Response:
{
"location": {...},
"total_hours": 48,
"hourly": [
{
"time": "2024-01-15T00:00",
"conditions": {
"code": 0,
"description": "Clear sky",
"is_day": false
},
"temperature": {
"value": 3.5,
"feels_like": 1.2,
"unit": "Β°C"
},
"humidity": 85,
"precipitation": {
"total": 0.0,
"probability": 10
},
"cloud_cover": 0,
"visibility": 24000,
"wind": {
"speed": 8.5,
"direction": 180,
"gusts": 15.0
}
}
]
}get_weather_by_city
Convenience tool that combines location search + current weather + forecast in one call.
Parameters:
Name | Type | Default | Description |
| string | required | City name (e.g., "Paris", "New York, NY") |
| int | 7 | Number of days (1-16) |
| string | "celsius" |
|
| string | "kmh" |
|
Example Response:
{
"city": {
"name": "Paris",
"latitude": 48.8566,
"longitude": 2.3522,
"country": "France",
"admin1": "Γle-de-France",
"timezone": "Europe/Paris"
},
"current": {...},
"forecast": {...}
}MCP Host Configuration
To use this server with an MCP-compatible host, add it to your MCP configuration:
HTTP Transport (default)
{
"mcpServers": {
"weather": {
"url": "http://127.0.0.1:8001/mcp"
}
}
}stdio Transport
Using the CLI command (after pip install -e .):
{
"mcpServers": {
"weather": {
"command": "weather-mcp",
"args": ["--transport", "stdio"]
}
}
}Or using the module directly:
{
"mcpServers": {
"weather": {
"command": "python",
"args": ["-m", "weather_mcp", "--transport", "stdio"]
}
}
}Project Structure
weather-mcp/
βββ pyproject.toml # Project configuration and dependencies
βββ README.md
βββ src/
βββ weather_mcp/
βββ __init__.py # Package exports
βββ __main__.py # CLI entry point
βββ constants.py # API endpoints, enums, weather codes
βββ models.py # Data classes for weather data
βββ clients.py # HTTP clients for Open-Meteo APIs
βββ tools.py # MCP tool definitions
βββ server.py # Main server classUsing Components Directly
You can use the API clients independently of the MCP server:
import asyncio
from weather_mcp import GeocodingClient, WeatherClient
async def main():
# Search for a city
geocoding = GeocodingClient()
locations = await geocoding.search("Tokyo")
print(f"Found: {locations[0].name}, {locations[0].country}")
# Get weather
weather = WeatherClient()
current = await weather.get_current(
locations[0].latitude,
locations[0].longitude
)
print(f"Temperature: {current['temperature']['value']}Β°C")
asyncio.run(main())Data Source
All weather data is provided by Open-Meteo.
Free for non-commercial use
No API key required
Global coverage
Updates every 15 minutes
License
MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/idrabenia/weather-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server