hkopenai.hk-climate-mcp-server 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ """Hong Kong climate MCP Server package."""
2
+ from .app import main
3
+ from .tool_weather import (
4
+ get_current_weather,
5
+ get_9_day_weather_forecast,
6
+ get_local_weather_forecast,
7
+ get_weather_warning_summary,
8
+ get_weather_warning_info,
9
+ get_special_weather_tips
10
+ )
11
+
12
+ __version__ = "0.1.0"
13
+ __all__ = [
14
+ 'main',
15
+ 'get_current_weather',
16
+ 'get_9_day_weather_forecast',
17
+ 'get_local_weather_forecast',
18
+ 'get_weather_warning_summary',
19
+ 'get_weather_warning_info',
20
+ 'get_special_weather_tips'
21
+ ]
@@ -0,0 +1,4 @@
1
+ from hkopenai.hk_climate_mcp_server.app import main
2
+
3
+ if __name__ == "__main__":
4
+ main()
@@ -0,0 +1,65 @@
1
+ import argparse
2
+ from fastmcp import FastMCP
3
+ from hkopenai.hk_climate_mcp_server import tool_weather
4
+ from typing import Dict, Annotated, Optional
5
+ from pydantic import Field
6
+
7
+ def create_mcp_server():
8
+ """Create and configure the HKO MCP server"""
9
+ mcp = FastMCP(name="HKOServer")
10
+
11
+ @mcp.tool(
12
+ description="Get current weather observations, warnings, temperature, humidity and rainfall in Hong Kong from Hong Kong Observatory, with optional region or place in Hong Kong",
13
+ )
14
+ def get_current_weather(region: str = "Hong Kong Observatory") -> Dict:
15
+ return tool_weather.get_current_weather(region)
16
+
17
+ @mcp.tool(
18
+ description="Get the 9-day weather forecast for Hong Kong including general situation, daily forecasts, sea and soil temperatures",
19
+ )
20
+ def get_9_day_weather_forecast(lang: str = "en") -> Dict:
21
+ return tool_weather.get_9_day_weather_forecast(lang)
22
+
23
+ @mcp.tool(
24
+ description="Get local weather forecast for Hong Kong including forecast description, outlook and update time",
25
+ )
26
+ def get_local_weather_forecast(lang: str = "en") -> Dict:
27
+ return tool_weather.get_local_weather_forecast(lang)
28
+
29
+ @mcp.tool(
30
+ description="Get weather warning summary for Hong Kong including warning messages and update time",
31
+ )
32
+ def get_weather_warning_summary(lang: str = "en") -> Dict:
33
+ return tool_weather.get_weather_warning_summary(lang)
34
+
35
+ @mcp.tool(
36
+ description="Get detailed weather warning information for Hong Kong including warning statement and update time",
37
+ )
38
+ def get_weather_warning_info(lang: str = "en") -> Dict:
39
+ return tool_weather.get_weather_warning_info(lang)
40
+
41
+ @mcp.tool(
42
+ description="Get special weather tips for Hong Kong including tips list and update time",
43
+ )
44
+ def get_special_weather_tips(lang: str = "en") -> Dict:
45
+ return tool_weather.get_special_weather_tips(lang)
46
+
47
+ return mcp
48
+
49
+ def main():
50
+ parser = argparse.ArgumentParser(description='HKO MCP Server')
51
+ parser.add_argument('-s', '--sse', action='store_true',
52
+ help='Run in SSE mode instead of stdio')
53
+ args = parser.parse_args()
54
+
55
+ server = create_mcp_server()
56
+
57
+ if args.sse:
58
+ server.run(transport="streamable-http")
59
+ print("HKO MCP Server running in SSE mode on port 8000")
60
+ else:
61
+ server.run()
62
+ print("HKO MCP Server running in stdio mode")
63
+
64
+ if __name__ == "__main__":
65
+ main()
@@ -0,0 +1,241 @@
1
+ import requests
2
+ from typing import Dict, List, Any
3
+
4
+ def get_current_weather(region: str = "Hong Kong Observatory", lang: str = "en") -> Dict:
5
+ """
6
+ Get current weather observations for a specific region in Hong Kong
7
+
8
+ Args:
9
+ region: The region to get weather for (default: "Hong Kong Observatory")
10
+ lang: Language code (en/tc/sc, default: en)
11
+
12
+ Returns:
13
+ Dict containing:
14
+ - warning: Current weather warnings
15
+ - temperature: Current temperature in Celsius
16
+ - humidity: Current humidity percentage
17
+ - rainfall: Current rainfall in mm
18
+ """
19
+ response = requests.get(
20
+ f"https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=rhrread&lang={lang}"
21
+ )
22
+ data = response.json()
23
+
24
+ # Handle warnings
25
+ warning = "No warning in force"
26
+ if "warningMessage" in data:
27
+ if isinstance(data["warningMessage"], list) and data["warningMessage"]:
28
+ warning = data["warningMessage"][0]
29
+ elif data["warningMessage"]: # Handle string case
30
+ warning = data["warningMessage"]
31
+
32
+ # Get default values from HKO data
33
+ default_temp = next(
34
+ (
35
+ t
36
+ for t in data.get("temperature", {}).get("data", [])
37
+ if t.get("place") == "Hong Kong Observatory"
38
+ ),
39
+ {"value": 25, "unit": "C", "recordTime": ""},
40
+ )
41
+ default_humidity = next(
42
+ (
43
+ h
44
+ for h in data.get("humidity", {}).get("data", [])
45
+ if h.get("place") == "Hong Kong Observatory"
46
+ ),
47
+ {"value": 60, "unit": "percent", "recordTime": ""},
48
+ )
49
+ # Find matching region temperature
50
+ temp_data = data.get("temperature", {}).get("data", [])
51
+ matched_temp = next(
52
+ (t for t in temp_data if t["place"].lower() == region.lower()),
53
+ {
54
+ "place": "Hong Kong Observatory",
55
+ "value": default_temp["value"],
56
+ "unit": default_temp["unit"],
57
+ },
58
+ )
59
+ matched_temp["recordTime"] = data["temperature"]["recordTime"]
60
+
61
+ # Get humidity
62
+ humidity = next(
63
+ (
64
+ h
65
+ for h in data.get("humidity", {}).get("data", [])
66
+ if h.get("place") == matched_temp["place"]
67
+ ),
68
+ default_humidity,
69
+ )
70
+ humidity["recordTime"] = data["humidity"]["recordTime"]
71
+
72
+ # Get rainfall (0 if no rain)
73
+ rainfall = 0
74
+ if "rainfall" in data:
75
+ rainfall = max(float(r.get("max", 0)) for r in data["rainfall"]["data"])
76
+ rainfall_start = data["rainfall"]["startTime"]
77
+ rainfall_end = data["rainfall"]["endTime"]
78
+
79
+ return {
80
+ "generalSituation": warning,
81
+ "weatherObservation": {
82
+ "temperature": {
83
+ "value": matched_temp["value"],
84
+ "unit": matched_temp["unit"],
85
+ "recordTime": matched_temp["recordTime"],
86
+ "place": matched_temp["place"]
87
+ },
88
+ "humidity": {
89
+ "value": humidity["value"],
90
+ "unit": humidity["unit"],
91
+ "recordTime": humidity["recordTime"],
92
+ "place": matched_temp["place"]
93
+ },
94
+ "rainfall": {
95
+ "value": rainfall,
96
+ "min": min(float(r.get("min", 0)) for r in data["rainfall"]["data"]),
97
+ "unit": "mm",
98
+ "startTime": rainfall_start,
99
+ "endTime": rainfall_end
100
+ },
101
+ "uvindex": data.get("uvindex", {})
102
+ },
103
+ "updateTime": data["updateTime"],
104
+ "icon": data.get("icon", []),
105
+ "iconUpdateTime": data.get("iconUpdateTime", "")
106
+ }
107
+
108
+ def get_9_day_weather_forecast(lang: str = "en") -> Dict[str, Any]:
109
+ """
110
+ Get the 9-day weather forecast for Hong Kong.
111
+
112
+ Args:
113
+ lang: Language code (en/tc/sc, default: en)
114
+
115
+ Returns:
116
+ Dict containing:
117
+ - generalSituation: General weather situation
118
+ - weatherForecast: List of daily forecast dicts (date, week, wind, weather, temp/humidity, etc.)
119
+ - updateTime: Last update time
120
+ - seaTemp: Sea temperature info
121
+ - soilTemp: List of soil temperature info
122
+ """
123
+ url = f"https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=fnd&lang={lang}"
124
+ response = requests.get(url)
125
+ data = response.json()
126
+
127
+ # Structure the output
128
+ forecast = {
129
+ "generalSituation": data.get("generalSituation", ""),
130
+ "weatherForecast": [],
131
+ "updateTime": data.get("updateTime", ""),
132
+ "seaTemp": data.get("seaTemp", {}),
133
+ "soilTemp": data.get("soilTemp", []),
134
+ }
135
+
136
+ # Extract 9-day forecast
137
+ for day in data.get("weatherForecast", []):
138
+ forecast["weatherForecast"].append({
139
+ "forecastDate": day.get("forecastDate", ""),
140
+ "week": day.get("week", ""),
141
+ "forecastWind": day.get("forecastWind", ""),
142
+ "forecastWeather": day.get("forecastWeather", ""),
143
+ "forecastMaxtemp": day.get("forecastMaxtemp", {}),
144
+ "forecastMintemp": day.get("forecastMintemp", {}),
145
+ "forecastMaxrh": day.get("forecastMaxrh", {}),
146
+ "forecastMinrh": day.get("forecastMinrh", {}),
147
+ "ForecastIcon": day.get("ForecastIcon", ""),
148
+ "PSR": day.get("PSR", ""),
149
+ })
150
+ return forecast
151
+
152
+ def get_local_weather_forecast(lang: str = "en") -> Dict[str, Any]:
153
+ """
154
+ Get local weather forecast for Hong Kong.
155
+
156
+ Args:
157
+ lang: Language code (en/tc/sc, default: en)
158
+
159
+ Returns:
160
+ Dict containing:
161
+ - forecastDesc: Forecast description
162
+ - outlook: Outlook forecast
163
+ - updateTime: Last update time
164
+ - forecastPeriod: Forecast period
165
+ - forecastDate: Forecast date
166
+ """
167
+ url = f"https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=flw&lang={lang}"
168
+ response = requests.get(url)
169
+ data = response.json()
170
+
171
+ return {
172
+ "generalSituation": data.get("generalSituation", ""),
173
+ "forecastDesc": data.get("forecastDesc", ""),
174
+ "outlook": data.get("outlook", ""),
175
+ "updateTime": data.get("updateTime", ""),
176
+ "forecastPeriod": data.get("forecastPeriod", ""),
177
+ "forecastDate": data.get("forecastDate", ""),
178
+ }
179
+
180
+ def get_weather_warning_summary(lang: str = "en") -> Dict[str, Any]:
181
+ """
182
+ Get weather warning summary for Hong Kong.
183
+
184
+ Args:
185
+ lang: Language code (en/tc/sc, default: en)
186
+
187
+ Returns:
188
+ Dict containing:
189
+ - warningMessage: List of warning messages
190
+ - updateTime: Last update time
191
+ """
192
+ url = f"https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=warnsum&lang={lang}"
193
+ response = requests.get(url)
194
+ data = response.json()
195
+
196
+ return {
197
+ "warningMessage": data.get("warningMessage", []),
198
+ "updateTime": data.get("updateTime", ""),
199
+ }
200
+
201
+ def get_weather_warning_info(lang: str = "en") -> Dict[str, Any]:
202
+ """
203
+ Get detailed weather warning information for Hong Kong.
204
+
205
+ Args:
206
+ lang: Language code (en/tc/sc, default: en)
207
+
208
+ Returns:
209
+ Dict containing:
210
+ - warningStatement: Warning statement
211
+ - updateTime: Last update time
212
+ """
213
+ url = f"https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=warningInfo&lang={lang}"
214
+ response = requests.get(url)
215
+ data = response.json()
216
+
217
+ return {
218
+ "warningStatement": data.get("warningStatement", ""),
219
+ "updateTime": data.get("updateTime", ""),
220
+ }
221
+
222
+ def get_special_weather_tips(lang: str = "en") -> Dict[str, Any]:
223
+ """
224
+ Get special weather tips for Hong Kong.
225
+
226
+ Args:
227
+ lang: Language code (en/tc/sc, default: en)
228
+
229
+ Returns:
230
+ Dict containing:
231
+ - specialWeatherTips: List of special weather tips
232
+ - updateTime: Last update time
233
+ """
234
+ url = f"https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=swt&lang={lang}"
235
+ response = requests.get(url)
236
+ data = response.json()
237
+
238
+ return {
239
+ "specialWeatherTips": data.get("specialWeatherTips", []),
240
+ "updateTime": data.get("updateTime", ""),
241
+ }
@@ -0,0 +1,149 @@
1
+ Metadata-Version: 2.4
2
+ Name: hkopenai.hk_climate_mcp_server
3
+ Version: 0.2.0
4
+ Summary: Hong Kong Weather MCP Server providing climate and weather data tools
5
+ Author-email: Neo Chow <neo@01man.com>
6
+ License-Expression: MIT
7
+ Project-URL: repository, https://github.com/hkopenai/hk-climate-mcp-server.git
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Requires-Python: >=3.10
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: fastmcp>=0.1.0
14
+ Requires-Dist: requests>=2.31.0
15
+ Requires-Dist: pytest>=8.2.0
16
+ Requires-Dist: pytest-cov>=6.1.1
17
+ Dynamic: license-file
18
+
19
+ # HKO MCP Server
20
+
21
+ [![GitHub Repository](https://img.shields.io/badge/GitHub-Repository-blue.svg)](https://github.com/hkopenai/hk-climate-mcp-server)
22
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
23
+
24
+
25
+ This is an MCP server that provides access to climate and weather data through a FastMCP interface.
26
+
27
+ ## Data Source
28
+
29
+ * Hong Kong Observatory
30
+
31
+ ## Features
32
+
33
+ - Current weather: Get current weather observations from HKO (supports optional region parameter)
34
+ - 9-day forecast: Get extended weather forecast including general situation, daily forecasts, sea and soil temperatures
35
+ - Local weather forecast: Get short-term weather forecast with outlook
36
+ - Weather warnings: Get summary and detailed information about active weather warnings
37
+ - Special weather tips: Get important weather-related safety tips
38
+
39
+ ## API Reference
40
+
41
+ ### Current Weather
42
+ `get_current_weather(region: str = "Hong Kong Observatory") -> Dict`
43
+ - Get current weather observations for a specific region in Hong Kong
44
+ - Parameters:
45
+ - region: The region to get weather for (default: "Hong Kong Observatory")
46
+ - Returns:
47
+ - Dict containing:
48
+ - warning: Current weather warnings
49
+ - temperature: Current temperature in Celsius
50
+ - humidity: Current humidity percentage
51
+ - rainfall: Current rainfall in mm
52
+
53
+ ### 9-Day Weather Forecast
54
+ `get_9_day_weather_forecast(lang: str = "en") -> Dict`
55
+ - Get the 9-day weather forecast for Hong Kong
56
+ - Parameters:
57
+ - lang: Language code (en/tc/sc, default: en)
58
+ - Returns:
59
+ - Dict containing:
60
+ - generalSituation: General weather situation
61
+ - weatherForecast: List of daily forecast dicts
62
+ - updateTime: Last update time
63
+ - seaTemp: Sea temperature info
64
+ - soilTemp: List of soil temperature info
65
+
66
+ ### Local Weather Forecast
67
+ `get_local_weather_forecast(lang: str = "en") -> Dict`
68
+ - Get local weather forecast for Hong Kong
69
+ - Parameters:
70
+ - lang: Language code (en/tc/sc, default: en)
71
+ - Returns:
72
+ - Dict containing:
73
+ - forecastDesc: Forecast description
74
+ - outlook: Outlook forecast
75
+ - updateTime: Last update time
76
+ - forecastPeriod: Forecast period
77
+ - forecastDate: Forecast date
78
+
79
+ ### Weather Warning Summary
80
+ `get_weather_warning_summary(lang: str = "en") -> Dict`
81
+ - Get weather warning summary for Hong Kong
82
+ - Parameters:
83
+ - lang: Language code (en/tc/sc, default: en)
84
+ - Returns:
85
+ - Dict containing:
86
+ - warningMessage: List of warning messages
87
+ - updateTime: Last update time
88
+
89
+ ### Weather Warning Information
90
+ `get_weather_warning_info(lang: str = "en") -> Dict`
91
+ - Get detailed weather warning information
92
+ - Parameters:
93
+ - lang: Language code (en/tc/sc, default: en)
94
+ - Returns:
95
+ - Dict containing:
96
+ - warningStatement: Warning statement
97
+ - updateTime: Last update time
98
+
99
+ ### Special Weather Tips
100
+ `get_special_weather_tips(lang: str = "en") -> Dict`
101
+ - Get special weather tips for Hong Kong
102
+ - Parameters:
103
+ - lang: Language code (en/tc/sc, default: en)
104
+ - Returns:
105
+ - Dict containing:
106
+ - specialWeatherTips: List of special weather tips
107
+ - updateTime: Last update time
108
+
109
+ ## Setup
110
+
111
+ 1. Clone this repository
112
+ 2. Install Python dependencies:
113
+ ```bash
114
+ pip install -r requirements.txt
115
+ ```
116
+ 3. Run the server:
117
+ ```bash
118
+ python app.py
119
+ ```
120
+
121
+ ### Running Options
122
+
123
+ - Default stdio mode: `python app.py`
124
+ - SSE mode (port 8000): `python app.py --sse`
125
+
126
+ ## Cline Integration
127
+
128
+ To connect this MCP server to Cline using stdio:
129
+
130
+ 1. Add this configuration to your Cline MCP settings (cline_mcp_settings.json):
131
+ ```json
132
+ {
133
+ "hko-server": {
134
+ "disabled": false,
135
+ "timeout": 3,
136
+ "type": "stdio",
137
+ "command": "python",
138
+ "args": [
139
+ "c:/Projects/hkopenai/hk-climate-mcp-server/app.py"
140
+ ]
141
+ }
142
+ }
143
+ ```
144
+
145
+ ## Testing
146
+
147
+ Tests are available in `tests`. Run with:
148
+ ```bash
149
+ pytest
@@ -0,0 +1,10 @@
1
+ hkopenai/hk_climate_mcp_server/__init__.py,sha256=QgSoOyNq_fnuED4FMOV9aj2ZDyEmezGRy2GCP427G5g,519
2
+ hkopenai/hk_climate_mcp_server/__main__.py,sha256=2rpUSwIvU59qepKyDNMz6AtDrbsRVVIZZP0hL5LoZbs,91
3
+ hkopenai/hk_climate_mcp_server/app.py,sha256=sTJS-eEBwyZz4KiGSEJ5QVzhiBNAGvUPAukhYNlkiEk,2479
4
+ hkopenai/hk_climate_mcp_server/tool_weather.py,sha256=MitwPrgdE08zszoIqezY-Cxo5Z5fN5HHiZ6T-IpP3N0,8180
5
+ hkopenai_hk_climate_mcp_server-0.2.0.dist-info/licenses/LICENSE,sha256=RzryYGol65qd1yszjiy-hSUsX9EJJkpwEpNXnIs_Bv8,1070
6
+ hkopenai_hk_climate_mcp_server-0.2.0.dist-info/METADATA,sha256=CQb8Er_uk1Ms9ZQEKfS7l7ytdBo_K06yWrV9d6t-7zI,4415
7
+ hkopenai_hk_climate_mcp_server-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
+ hkopenai_hk_climate_mcp_server-0.2.0.dist-info/entry_points.txt,sha256=2pPEyDw5KdrNNZIGQsSrY-5IRMgWaWvEQT_BQJhKPMQ,82
9
+ hkopenai_hk_climate_mcp_server-0.2.0.dist-info/top_level.txt,sha256=6PRVKRM9BiU5vzKKGnsq2t0-Bi0TrJvSY35llo4nLFA,9
10
+ hkopenai_hk_climate_mcp_server-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ hk_climate_mcp_server = hkopenai.hk_climate_mcp_server.app:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 neo@01man.com
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.