Skip to main content
Glama
HumairaShaista

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

  1. Einfache LLM-Anwendung — Chat mit einem lokalen Open-Source-Modell über Ollama

  2. Traditionelle Wetter-API-App — Open-Meteo-Client (Stufe 2A) + direkte LLM-Orchestrierung (Stufe 2B)

  3. Weather MCP Server — Wetter als MCP-Tools über stdio bereitstellen (Stufe 3)

  4. 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:7b

Oder 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 list

2. Virtuelle Umgebung erstellen

python3 -m venv .venv
source .venv/bin/activate

Unter Windows:

python -m venv .venv
.venv\Scripts\activate

3. Abhängigkeiten installieren

pip install -e ".[dev]"

4. Umgebungsvariablen konfigurieren

cp .env.example .env

Standardeinstellungen in .env zielen auf lokales Ollama:

LLM_BASE_URL=http://localhost:11434/v1
LLM_API_KEY=ollama
LLM_MODEL=qwen2.5:7b
  • LLM_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 aus ollama list (Stufe 4B Tool-Aufruf funktioniert gut mit qwen2.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):

  1. GeokodierungGET https://geocoding-api.open-meteo.com/v1/search wandelt einen Stadtnamen (plus optionalem Bundesstaat/Region und Land) in Breitengrad, Längengrad, kanonischen Namen, Verwaltungsregion, Land und Zeitzone um.

  2. VorhersageGET https://api.open-meteo.com/v1/forecast verwendet 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)
  → Response

So 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 US

Oder das Konsolenskript:

direct-weather "San Francisco"

Auf stderr sehen Sie die Orchestrierungsschritte:

  1. Anwendung hat Stadt empfangen

  2. Anwendung hat Wetteranbieter aufgerufen

  3. Anwendung hat strukturierte Wetterdaten empfangen

  4. 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 plain_llm_app

Stufe 2B direct_weather_app

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 mcp auf PyPI (modelcontextprotocol/python-sdk)

Installierte Version

2.0.0

Server-Klasse

MCPServer aus mcp.server

Nicht verwendet

Drittanbieterpaket fastmcp; älterer v1 FastMCP-Importpfad

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 akzeptieren

  • An app.weather_client delegieren (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

city

string

ja

Stadt- oder Ortsname

state_or_region

string

nein

Bundesstaat / Verwaltungsregion zur Disambiguierung

country

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_server

Oder:

weather-mcp-server

Mit 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 stdout
  • Kein 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 mcp 2.0.0 (MCPServer)

  • offizielles Inspector-Paket @modelcontextprotocol/inspector

  • Node.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 --version

Wenn 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:

  1. Terminal gibt etwas aus wie MCP Inspector Web is up and running at: http://localhost:6274?MCP_INSPECTOR_API_TOKEN=...

  2. Browser öffnet den Inspector

  3. Inspector startet/verbindet sich mit dem lokalen stdio-Server (weather-learning-server)

  4. Sitzung initialisiert (Servername/Anweisungen erscheinen)

  5. Öffnen Sie Tools → Liste zeigt get_current_weather

  6. Wählen Sie das Tool → UI zeigt den Docstring/die Beschreibung und Eingabefelder aus dem Schema (city erforderlich; state_or_region / country optional)

  7. Setzen Sie city = San FranciscoRun Tool

  8. Ergebnisbereich zeigt strukturierten Inhalt wie resolved_location, region, temperature, condition, units usw.

--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 json

Erwartetes 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 json

Erwartet: 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 json

Erwartet: "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-Meteo

Wichtig: 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 US

Oder:

basic-mcp-client "San Francisco"

Sie sollten sehen:

  1. Verbindungs-/Protokollinformationen für weather-learning-server

  2. Jedes entdeckte Tool mit Name, Beschreibung und Eingabeschema

  3. Einen expliziten Aufruf von get_current_weather

  4. Das 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 answer

Es 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)

  1. MCP-Sitzung startenpython -m app.mcp_server über stdio erzeugen; Client initialisieren

  2. Tool-Erkennunglist_tools; jeden Tool-Namen/jede Beschreibung protokollieren

  3. Schema-Übersetzung — MCP-Tools → Responses type: "function"-Tools

  4. Modell-Durchgangclient.responses.create(..., tools=..., tool_choice="auto")

  5. 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_output mit previous_response_id einreichen

  6. Wiederholen, bis das Modell eine endgültige Textnachricht zurückgibt (oder maximale Iterationen erreicht)

  7. 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_call für get_current_weather, dann eine Wetterantwort

  • Dependency-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_app

Oder 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

pytest

Projektstruktur

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 openai Python-Paket wird als OpenAI-kompatibler Client verwendet (zuvor Chat Completions; Responses API in Stage 4B). Anfragen gehen an Ihre konfigurierte LLM_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 mcp 2.0.0 SDK (MCPServer aus mcp.server) über stdio. Verwenden Sie nicht das Drittanbieter-Paket fastmcp.

  • 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.

Install Server
F
license - not found
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

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)

View all MCP Connectors

Latest Blog Posts

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