weather-learning-server
Weather MCP Learning
Ein progressives Lernprojekt, das den Weg von einer einfachen LLM-Anwendung zu Wetterfunktionen zeigt, die über das Model Context Protocol (MCP) bereitgestellt werden.
Lernfortschritt
Einfache LLM-Anwendung — Chat mit einem lokalen Open-Source-Modell über Ollama
Traditionelle Wetter-API-App — Open-Meteo-Client (Stufe 2A) + direkte LLM-Orchestrierung (Stufe 2B)
Weather MCP Server — Wetter als MCP-Tools über stdio bereitstellen (Stufe 3)
MCP-Client / Agent — Expliziter Tool-Client (Stufe 4A) + modellselektierte Tools (Stufe 4B)
Dieses Repository implementiert derzeit die Stufen 1 bis 4B.
Related MCP server: MCP Weather Server Demo
Voraussetzungen
Python 3.12 oder neuer
Ollama (oder ein beliebiger OpenAI-kompatibler lokaler Server)
Ein lokales Open-Source-Modell mit Tool-Aufruf (Standard:
qwen2.5:7b)
Es wird kein OpenAI- oder Gemini-Konto benötigt.
Einrichtung
1. Ollama installieren und starten
Installieren von https://ollama.com, dann ein Modell pullen:
ollama pull qwen2.5:7bOder verwenden Sie ein beliebiges Responses-API-toolfähiges Modell, das Sie bereits haben (ollama list), und setzen Sie dann LLM_MODEL in .env auf diesen Namen.
Stellen Sie sicher, dass Ollama läuft (normalerweise automatisch unter macOS nach der Installation):
ollama list2. Virtuelle Umgebung erstellen
python3 -m venv .venv
source .venv/bin/activateUnter Windows:
python -m venv .venv
.venv\Scripts\activate3. Abhängigkeiten installieren
pip install -e ".[dev]"4. Umgebungsvariablen konfigurieren
cp .env.example .envStandardeinstellungen in .env zielen auf lokales Ollama:
LLM_BASE_URL=http://localhost:11434/v1
LLM_API_KEY=ollama
LLM_MODEL=qwen2.5:7bLLM_BASE_URL— OpenAI-kompatible API-URL (Ollamas Standard ist oben gezeigt; wird von Chat Completions und Responses verwendet)LLM_API_KEY— von der Client-Bibliothek benötigt; Ollama ignoriert sie (jeder nicht-leere Wert funktioniert)LLM_MODEL— lokaler Modellname ausollama list(Stufe 4B Tool-Aufruf funktioniert gut mitqwen2.5:7b)
Andere Optionen: LM Studio, vLLM oder jeder Server, der die OpenAI-Chat-API spricht — ändern Sie einfach LLM_BASE_URL und LLM_MODEL.
Stufe 2A: Open-Meteo Wetter-Client
app/weather_client.py kommuniziert in zwei Schritten mit Open-Meteo (kein LLM, kein MCP):
Geokodierung —
GET https://geocoding-api.open-meteo.com/v1/searchwandelt einen Stadtnamen (plus optionalem Bundesstaat/Region und Land) in Breitengrad, Längengrad, kanonischen Namen, Verwaltungsregion, Land und Zeitzone um.Vorhersage —
GET https://api.open-meteo.com/v1/forecastverwendet diese Koordinaten, um das aktuelle Wetter abzurufen (Temperatur, Luftfeuchtigkeit, Wind, WMO-Wettercode).
Aufrufer erhalten typisierte Modelle (Location, CurrentWeather, WeatherResult), kein rohes Provider-JSON. Die WMO-Wettercode → Text-Übersetzung befindet sich an einer Stelle (WMO_WEATHER_CODES / weather_condition_from_code).
Beispiel (asynchron):
from app.weather_client import get_current_weather
result = await get_current_weather("Berlin")
print(result.location.name, result.current.temperature, result.current.condition)Stufe 2B: Direkte Wetter- + LLM-Anwendung
app/direct_weather_app.py ist eine traditionelle LLM-App: Ihr Code entscheidet, wann die Wetter-API aufgerufen wird, und übergibt dieses Ergebnis dann an das LLM für eine freundliche Zusammenfassung.
User
→ direct_weather_app
→ Open-Meteo (application-controlled)
→ LLM (summarize only the supplied payload)
→ ResponseSo führen Sie es aus
Mit aktivierter virtueller Umgebung, laufendem Ollama und Netzwerkzugriff für Open-Meteo:
python -m app.direct_weather_app "San Francisco"Optionale Disambiguierung:
python -m app.direct_weather_app "Springfield" --state Illinois --country USOder das Konsolenskript:
direct-weather "San Francisco"Auf stderr sehen Sie die Orchestrierungsschritte:
Anwendung hat Stadt empfangen
Anwendung hat Wetteranbieter aufgerufen
Anwendung hat strukturierte Wetterdaten empfangen
Anwendung hat Wetterkontext an das LLM gesendet
Stdout zeigt den strukturierten Wetterblock, dann die LLM-Zusammenfassung.
Wie es sich von der einfachen LLM-Anwendung unterscheidet
Stufe 1 | Stufe 2B | |
Wetterdaten | Keine — Modell hat kein Live-Wetter | Zuerst von Open-Meteo abgerufen |
Wer ruft Wetter auf? | Niemand | Anwendungscode (explizit) |
LLM-Rolle | Beantwortet eine freie Eingabeaufforderung | Fasst eine autoritative Nutzlast zusammen |
MCP / Tools | Nein | Nein |
Wichtiger Lernpunkt: Das LLM entdeckt oder ruft keine Wetter-Tools auf. Die Anwendung orchestriert Open-Meteo und bittet dann das LLM, das Ergebnis zu formulieren. Die Eingabeaufforderung teilt dem Modell mit, dass die Nutzlast autoritativ ist und keine fehlenden Fakten erfunden werden sollen.
Stufe 3: Weather MCP Server
app/mcp_server.py stellt den vorhandenen weather_client als MCP-Tool bereit. Der Server bietet nur Fähigkeiten — er kommuniziert nicht mit einem LLM oder verwaltet eine Konversation.
Offizielle SDK-Version und verwendete API
In dieser Projektumgebung überprüft:
Element | Wert |
Paket | offizielles |
Installierte Version | 2.0.0 |
Server-Klasse |
|
Nicht verwendet | Drittanbieterpaket |
from mcp.server import MCPServer
mcp = MCPServer("weather-learning-server")Server-Verantwortlichkeiten
Tools an MCP-Clients bewerben (Tool-Erkennung)
Einen
get_current_weather-Tool-Aufruf akzeptierenAn
app.weather_clientdelegieren (kein duplizierter Open-Meteo-Code)Eine strukturierte Wetter-Nutzlast zurückgeben (oder einen sicheren Tool-Fehler)
MCP über stdio für diesen lokalen Lern-POC sprechen
Bereitgestellter Tool-Vertrag: get_current_weather
Argumente
Name | Typ | Erforderlich | Beschreibung |
| string | ja | Stadt- oder Ortsname |
| string | nein | Bundesstaat / Verwaltungsregion zur Disambiguierung |
| string | nein | Ländername oder ISO-3166-1 Alpha-2-Code |
Strukturierte Ergebnisfelder
resolved_location, region, country, latitude, longitude, temperature, apparent_temperature (wenn verfügbar), condition, wind_speed, observation_time, timezone, units
So starten Sie den Server
python -m app.mcp_serverOder:
weather-mcp-serverMit stdio wartet der Prozess auf einen MCP-Host auf stdin/stdout. Wenn Sie ihn allein in einem Terminal ausführen, sieht es „hängend“ aus — das ist erwartet.
Wie stdio-Transport funktioniert (konzeptionell)
MCP host / Inspector
├── spawns: python -m app.mcp_server
├── writes JSON-RPC MCP messages → server stdin
└── reads JSON-RPC MCP messages ← server stdoutKein Port und kein HTTP für diesen POC
stdout ist der Protokolldraht (geben Sie dort keine normalen App-Ausgaben mit
print()aus)Logs gehören auf stderr
Unabhängiges Testen mit dem offiziellen MCP Inspector
Verifiziert gegen:
offizielles
mcp2.0.0 (MCPServer)offizielles Inspector-Paket
@modelcontextprotocol/inspectorNode.js 22.19+ (erforderlich durch aktuelle Inspector-Dokumentation)
Netzwerkzugriff auf Open-Meteo
Voraussetzungen
cd weather-mcp-learning
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]" # includes mcp[cli]Bestätigen Sie Node/npx:
node --version # need 22.19.0 or newer
npx --versionWenn Ihr System-node/npx defekt oder zu alt ist, verwenden Sie ein aktuelles Node über nvm (oder gleichwertig) und stellen Sie sicher, dass npx zuerst in Ihrem PATH ist.
Option A — Web-UI über mcp dev (offizielles SDK-Hilfsprogramm)
Vom Projektstamm aus mit aktivierter venv (benötigt auch uv, da mcp dev den Server über uv run startet):
mcp dev app/mcp_server.py --with-editable .Erwartet:
Terminal gibt etwas aus wie
MCP Inspector Web is up and running at: http://localhost:6274?MCP_INSPECTOR_API_TOKEN=...Browser öffnet den Inspector
Inspector startet/verbindet sich mit dem lokalen stdio-Server (
weather-learning-server)Sitzung initialisiert (Servername/Anweisungen erscheinen)
Öffnen Sie Tools → Liste zeigt
get_current_weatherWählen Sie das Tool → UI zeigt den Docstring/die Beschreibung und Eingabefelder aus dem Schema (
cityerforderlich;state_or_region/countryoptional)Setzen Sie
city=San Francisco→ Run ToolErgebnisbereich zeigt strukturierten Inhalt wie
resolved_location,region,temperature,condition,unitsusw.
--with-editable . installiert dieses Projekt in die temporäre Umgebung, die mcp dev erstellt, damit import app... funktioniert.
Option B — Web-UI über Inspector + Projektkonfiguration
mcp-inspector.json im Repository-Stammverzeichnis verweist den Inspector auf den lokalen stdio-Server:
npx -y @modelcontextprotocol/inspector --config ./mcp-inspector.json --server weather-learning-serverÖffnen Sie die gedruckte http://localhost:6274?...-URL, bestätigen Sie, dass die Sitzung verbunden ist, und verwenden Sie dann den Tools-Tab wie in Option A.
Option C — Skriptbare CLI-Prüfungen (kein Browser)
Diese sind nützlich, um dieselben Protokollschritte von einem Terminal aus zu beweisen. Führen Sie sie vom Projektstamm aus mit aktiver venv und einem funktionierenden Node 22.19+ npx im PATH aus:
# 1–2. Start/connect over stdio + initialize session
npx -y @modelcontextprotocol/inspector --cli \
--config ./mcp-inspector.json \
--server weather-learning-server \
--method initialize \
--format jsonErwartetes JSON enthält "name": "weather-learning-server" unter result.serverInfo.
# 3–4. List tools; confirm description + input schema
npx -y @modelcontextprotocol/inspector --cli \
--config ./mcp-inspector.json \
--server weather-learning-server \
--method tools/list \
--format jsonErwartet: ein Tool namens get_current_weather, mit inputSchema.required, das city enthält, und einer Live-/Aktuellwetter-Beschreibung.
# 5–6. Invoke with city = San Francisco; display structured result
npx -y @modelcontextprotocol/inspector --cli \
--config ./mcp-inspector.json \
--server weather-learning-server \
--method tools/call \
--tool-name get_current_weather \
--tool-arg 'city=San Francisco' \
--format jsonErwartet: "isError": false und structuredContent mit Feldern wie:
{
"resolved_location": "San Francisco",
"region": "California",
"country": "United States",
"latitude": 37.77493,
"longitude": -122.41942,
"temperature": 13.8,
"apparent_temperature": 12.1,
"condition": "Fog",
"wind_speed": 19.1,
"observation_time": "2026-08-12T22:45",
"timezone": "America/Los_Angeles",
"units": {
"temperature": "°C",
"wind_speed": "km/h",
"apparent_temperature": "°C"
}
}Numerische Wetterwerte ändern sich im Laufe der Zeit; die Feldnamen und "isError": false sind das, was zählt.
Offizielle Inspector-Dokumentation: MCP Inspector · SDK-Ausführungsdokumentation: Running your server
Stufe 4A: Einfacher MCP-Client (expliziter Tool-Aufruf)
app/basic_mcp_client.py ist ein Nicht-LLM-MCP-Client. Er startet den lokalen Wetter-MCP-Server über stdio, entdeckt Tools und ruft dann explizit get_current_weather auf.
basic_mcp_client
→ list_tools
→ get_current_weather (hardcoded by this app — not chosen by an LLM)
→ MCP server (app.mcp_server via stdio)
→ Open-MeteoWichtig: Dieser Client ruft das Wetter-Tool immer noch explizit auf. Das LLM hat das Tool noch nicht ausgewählt. Das kommt in einer späteren Stufe.
So führen Sie es aus
Mit aktivierter virtueller Umgebung (Sie müssen den MCP-Server nicht selbst starten — dieser Client erzeugt ihn):
python -m app.basic_mcp_client "San Francisco"Optionale Filter:
python -m app.basic_mcp_client "Springfield" --state Illinois --country USOder:
basic-mcp-client "San Francisco"Sie sollten sehen:
Verbindungs-/Protokollinformationen für
weather-learning-serverJedes entdeckte Tool mit Name, Beschreibung und Eingabeschema
Einen expliziten Aufruf von
get_current_weatherDas strukturierte MCP-Tool-Ergebnis-JSON
Das Beenden des Prozesses bereinigt die MCP-Sitzung und den untergeordneten Serverprozess.
Stufe 4B: OpenAI Responses Agent (modellselektierte MCP-Tools)
app/mcp_agent.py verbindet sich mit dem Wetter-MCP-Server, entdeckt Tools zur Laufzeit, gibt diese Definitionen an das Modell über die offizielle OpenAI Responses API, führt alle vom Modell angeforderten Tool-Aufrufe über MCP aus, gibt Tool-Ergebnisse an das Modell zurück und gibt die endgültige Antwort aus.
user question
→ mcp_agent
→ MCP list_tools (discovery)
→ OpenAI Responses API (question + tool schemas)
→ model may request tool(s)
→ MCP tools/call (only discovered names)
→ Responses function_call_output
→ final natural-language answerEs gibt kein if "weather" in question, keine Stadt-Regex und keinen hartcodierten get_current_weather-Aufruf. Das Modell entscheidet, ob es ein Tool verwendet.
Agenten-Schleife (Detail)
MCP-Sitzung starten —
python -m app.mcp_serverüber stdio erzeugen; Client initialisierenTool-Erkennung —
list_tools; jeden Tool-Namen/jede Beschreibung protokollierenSchema-Übersetzung — MCP-Tools → Responses
type: "function"-ToolsModell-Durchgang —
client.responses.create(..., tools=..., tool_choice="auto")Ausgabe prüfen — wenn
function_call-Elemente existieren:Tool-Namen gegen den entdeckten Satz validieren
JSON-Argumente parsen/validieren
MCP aufrufen; strukturierte Ergebnisse bewahren
function_call_outputmitprevious_response_ideinreichen
Wiederholen, bis das Modell eine endgültige Textnachricht zurückgibt (oder maximale Iterationen erreicht)
Endgültige Antwort ausgeben und die MCP-Sitzung/den untergeordneten Prozess schließen
So führen Sie es aus
ollama pull qwen2.5:7b # once, if needed
source .venv/bin/activate
python -m app.mcp_agent "What is the current weather in San Francisco?"
python -m app.mcp_agent "Explain what dependency injection is."Erwartet:
Wetterfrage → Logs zeigen
model_requested_tools/tool_callfürget_current_weather, dann eine WetterantwortDependency-Injection-Frage → Logs zeigen eine endgültige Antwort ohne Tool-Aufrufe
Beobachten Sie stderr auf [mcp-agent]-Zeilen: Erkennung, Modellausgabetypen, Tool-Name/Argumente/Dauer/Ergebnis. API-Schlüssel werden nie protokolliert.
Ausführen der einfachen Anwendung
Mit aktivierter virtueller Umgebung und laufendem Ollama:
python -m app.plain_llm_appOder mit einer benutzerdefinierten Eingabeaufforderung:
python -m app.plain_llm_app "What is the Model Context Protocol in one sentence?"Sie können auch das installierte Konsolenskript verwenden:
plain-llm "Hello!"Ausführen von Tests
pytestProjektstruktur
weather-mcp-learning/
README.md
.env.example
.gitignore
pyproject.toml
mcp-inspector.json
app/
__init__.py
config.py
llm_client.py
plain_llm_app.py
weather_client.py
direct_weather_app.py
mcp_server.py
basic_mcp_client.py
mcp_agent.py
tests/Hinweise
Das offizielle
openaiPython-Paket wird als OpenAI-kompatibler Client verwendet (zuvor Chat Completions; Responses API in Stage 4B). Anfragen gehen an Ihre konfigurierteLLM_BASE_URL(standardmäßig Ollama).Wetterabfragen verwenden Open-Meteo über
httpx(app/weather_client.py).Stage 2B (
direct_weather_app.py) orchestriert explizit Wetter → LLM; kein MCP und kein Tool-Aufruf.Stage 3 verwendet das offizielle
mcp2.0.0 SDK (MCPServerausmcp.server) über stdio. Verwenden Sie nicht das Drittanbieter-Paketfastmcp.Stage 4A (
basic_mcp_client.py) ruft das Wetter-Tool weiterhin explizit auf (keine LLM-Tool-Auswahl).Stage 4B (
mcp_agent.py) lässt das Modell nach der MCP-Erkennung über die Responses API Tools auswählen.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Tools
Related MCP Servers
- Flicense-qualityDmaintenanceProvides real-time weather information for any city worldwide using the Open-Meteo API, returning current temperature, wind speed, and geographic coordinates through a containerized MCP server.
- Alicense-qualityDmaintenanceFetches current weather information for any city using the Open-Meteo API through a simple MCP tool interface.1,299MIT
- Flicense-qualityCmaintenanceEnables AI agents to retrieve live weather updates for any city via OpenWeatherMap, wrapped in MCP format.1
- FlicenseBqualityDmaintenanceProvides real-time weather information for cities worldwide using the OpenWeatherMap API, accessible through natural language queries via the MCP protocol.1
Related MCP Connectors
OpenWeather MCP — wraps the OpenWeatherMap API (openweathermap.org)
Open-Meteo MCP — weather forecast + historical reanalysis + sister APIs
WeatherAPI.com MCP — wraps WeatherAPI.com (api.weatherapi.com)
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/HumairaShaista/Weather-MCP-Learning'
If you have feedback or need assistance with the MCP directory API, please join our Discord server