Weather MCP - Israel Edition
# Weather MCP - Israel Edition 🦚
MCP Server ישראלי לתחזית מזג אוויר, שבמקום להתבסס על API מובנה, פותח דפדפן
אמיתי באמצעות [Playwright](https://playwright.dev/python/) וניגש לאתר
[weather2day.co.il](https://www.weather2day.co.il/forecast) בדיוק כמו משתמש/ת
אנושי/ת: מזין שם עיר, בוחר אותה מתוך רשימת ההשלמה האוטומטית, וקורא את דף
התחזית שנטען.
## מטרת הפרויקט
הפרויקט נבנה כתרגול בפיתוח MCP Server עצמאי, ומדגים שתי יכולות מרכזיות:
1. **מימוש MCP Server** באמצעות ה-SDK הרשמי של Anthropic (`mcp[cli]` /
`FastMCP`), שחושף כלים (Tools) ל-LLM.
2. **שליטה בדפדפן ללא מגע יד אדם** באמצעות Playwright, כדי לשלוף מידע מאתר
שאין לו API ציבורי - על ידי אוטומציה של הפעולות שמשתמש/ת אנושי/ת היו
מבצעים בעצמם.
בפרויקט שני שרתי MCP:
| קובץ | תיאור |
|---------------------|---------------------------------------------------------------------|
| `weather_USA.py` | שרת "קלאסי" שמביא תחזית למדינות ארה"ב דרך ה-API הציבורי של NWS. |
| `weather_Israel.py` | **השרת המרכזי של הפרויקט** - תחזית לערים בישראל, דרך אוטומציית דפדפן. |
ושני קבצי תשתית גנריים שמחברים ביניהם:
| קובץ | תיאור |
|-------------|------------------------------------------------------------------------|
| `client.py` | MCP Client גנרי - עוטף חיבור יחיד לשרת MCP (stdio) וקריאה לכלים שלו. |
| `host.py` | צ'אט טרמינל שמתחבר לכל שרתי ה-MCP, מריץ שיחה עם Claude, ומנתב קריאות לכלים לשרת המתאים. |
## איך זה עובד - `weather_Israel.py`
השרת חושף 4 כלים, המיועדים לשימוש ברצף על ידי ה-LLM:
1. **`open_weather_forecast_israel`** - פותח דפדפן כרום חדש (Chromium) ומנווט
לדף `https://www.weather2day.co.il/forecast`.
2. **`enter_weather_forecast_city_israel(city)`** - מקליד את שם העיר בשדה
החיפוש שבדף, ומחכה שרשימת ההשלמה האוטומטית תיפתח.
3. **`select_weather_forecast_city_israel`** - בוחר את הפריט הראשון ברשימה
הנפתחת, וממתין לטעינת דף התחזית של אותה עיר.
4. **`get_weather_forecast_content_israel`** - שולף ומנקה את תוכן הטקסט של
דף התחזית שנטען (RAG פשוט), כדי שה-LLM יוכל לענות על שאלות לגבי התחזית
ישירות בתוך השיחה, בלי שהמשתמש/ת יצטרכו להסתכל בעצמם על הדפדפן.
מכיוון שמבנה ה-HTML של אתרים חיצוניים יכול להשתנות, שני הכלים הראשונים
(חיפוש ובחירת עיר) בנויים עם **רשימת סלקטורים לפי סדר עדיפות**: השרת מנסה
כמה אסטרטגיות סבירות למציאת שדה החיפוש ופריטי הרשימה הנפתחת, כדי לשרוד
שינויים קלים במבנה הדף.
> **הערה חשובה:** קוד ה-Playwright פותח ונבדק במלואו (פתיחה → הזנת עיר →
> בחירה → חילוץ תוכן) מול עמוד HTML סינתטי שמדמה את זרימת האתר האמיתי - שדה
> חיפוש ורשימת השלמה אוטומטית שנפתחת ולוחצים עליה. לא ניתן היה להריץ בדיקה
> חיה מול `weather2day.co.il` עצמו מתוך סביבת הפיתוח שבה נכתב הקוד, בשל
> חסימת רשת (sandbox ללא גישה כללית לאינטרנט). לכן, בהרצה ראשונה שלך מומלץ
> לוודא שהבחירה בעיר אכן מצליחה, ובמידת הצורך לעדכן את רשימות הסלקטורים
> (`SEARCH_INPUT_SELECTORS`, `SUGGESTION_ITEM_SELECTORS`) בראש הקובץ
> `weather_Israel.py` לפי המבנה בפועל (ניתן להיעזר בפקודה
> `uv run playwright codegen https://www.weather2day.co.il/forecast` כדי
> לזהות את הסלקטורים הנכונים תוך כדי אינטראקציה עם האתר).
## התקנה והרצה
### דרישות מקדימות
* Python 3.10+
* [uv](https://docs.astral.sh/uv/)
* מפתח API של Anthropic
### שלבים
```bash
# 1. התקנת תלויות
uv sync
# 2. התקנת דפדפן Chromium עבור Playwright
uv run playwright install chromium
# 3. הגדרת מפתח ה-API
cp .env.example .env
# ולערוך את .env ולהוסיף את ANTHROPIC_API_KEY
# 4. הרצה
uv run host.py
```
בהרצה, `host.py` מתחבר לשני שרתי ה-MCP (`weather_USA.py` ו-`weather_Israel.py`)
כתת-תהליכים, אוסף את הכלים שהם חושפים, ופותח צ'אט בטרמינל. הקלידו שאלה, ו-Claude
יבחר בעצמו איזה שרת ואילו כלים להפעיל (ובאיזה סדר) כדי לענות עליה.
## דוגמאות לשאלות
**תחזית בישראל (`weather_Israel.py`):**
* "מה התחזית להיום בתל אביב?"
* "איך מזג האוויר בחיפה מחר?"
* "תבדקי לי את התחזית בבאר שבע ותגידי לי אם צריך מטרייה"
**תחזית בארה"ב (`weather_USA.py`):**
* "What's the weather forecast for San Francisco (latitude 37.77, longitude -122.42)?"
* "Are there any weather alerts in Texas right now?"
בכל שאלה על עיר בישראל, Claude יפעיל את שרשרת הכלים
`open_weather_forecast_israel` → `enter_weather_forecast_city_israel` →
`select_weather_forecast_city_israel` → `get_weather_forecast_content_israel`,
ותוכלו לראות את הדפדפן נפתח, מקליד את שם העיר, ובוחר אותה מהרשימה - לפני
שהתשובה חוזרת בטרמינל.
### מצב headless
כברירת מחדל הדפדפן נפתח **גלוי** (`headless=False`) כדי לאפשר לצפות
בתהליך. כדי להריץ ללא חלון גלוי (למשל על שרת ללא מסך), הגדירו בקובץ `.env`:
```
PLAYWRIGHT_HEADLESS=true
```
## למה לא Google Search?
בכוונה נמנענו מלבנות כלי שמחפש בגוגל "מה התחזית היום ב-X":
* חיפוש בגוגל דרך דפדפן אוטומטי (Playwright) מוביל להקפצת אימות CAPTCHA.
* הדרך הנכונה לבצע Web Search בפרויקטי LLM היא באמצעות מנוע חיפוש ייעודי
(כגון Tavily), ולא על ידי פתיחת דפדפן.
* מטרת הפרויקט הייתה תרגול פיתוח MCP Server **ספציפי** למקור מידע נתון;
לצרכים גנריים של גלישה ואוטומציה קיים כבר [MCP Playwright הרשמי](https://github.com/microsoft/playwright-mcp).
## מבנה הפרויקט
```
.
├── client.py # MCP Client גנרי
├── host.py # צ'אט טרמינל שמחבר את כל שרתי ה-MCP
├── weather_USA.py # MCP Server לתחזית בארה"ב, דרך ה-API של NWS
├── weather_Israel.py # MCP Server לתחזית בישראל, דרך אוטומציית Playwright
├── pyproject.toml # תלויות הפרויקט (מנוהל על ידי uv)
├── .env.example # תבנית למשתני סביבה נדרשים
└── README.md
```
TDQS
Scored across 4 tools
Each tool has a discrete role in a linear workflow: opening the forecast page, entering a city, selecting an autocomplete result, and extracting content. The Hebrew descriptions clearly state required predecessors, so an agent should not confuse entering a city with selecting it.
All tool names follow a consistent snake_case convention with a verb, the weather_forecast domain, and the israel suffix. The shared prefix and country suffix make the set coherent, while the varying object nouns still align with each tool's distinct action.
Four tools is exactly right for the narrow browser automation workflow; each step is necessary and none is redundant. The count fits comfortably within the ideal 3–15 range for a focused MCP server.
The full workflow from opening the site to extracting forecast content is covered, including city search and selection. A close/reset tool or broader city-selection capabilities would be nice but are not essential for the stated purpose.