weatherapi-mcp 1.0.0
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.
- package/README.md +115 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +332 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
- package/src/index.ts +378 -0
- package/tsconfig.json +18 -0
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# weatherapi-mcp
|
|
2
|
+
|
|
3
|
+
Official MCP (Model Context Protocol) server for [WeatherAPI.com](https://www.weatherapi.com). Gives AI agents like Claude direct access to real-time weather, forecasts, historical data, astronomy, marine weather, air quality, and more.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Run directly with npx (no install needed)
|
|
9
|
+
WEATHERAPI_KEY=your_api_key npx weatherapi-mcp
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Get a free API key at [weatherapi.com/signup.aspx](https://www.weatherapi.com/signup.aspx)
|
|
13
|
+
|
|
14
|
+
## Setup in Claude Desktop
|
|
15
|
+
|
|
16
|
+
Add to your `claude_desktop_config.json`:
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"mcpServers": {
|
|
21
|
+
"weatherapi": {
|
|
22
|
+
"command": "npx",
|
|
23
|
+
"args": ["-y", "weatherapi-mcp"],
|
|
24
|
+
"env": {
|
|
25
|
+
"WEATHERAPI_KEY": "your_api_key_here"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Config file locations:
|
|
33
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
34
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
35
|
+
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
36
|
+
|
|
37
|
+
Restart Claude Desktop after editing.
|
|
38
|
+
|
|
39
|
+
## Setup in Cursor
|
|
40
|
+
|
|
41
|
+
Add to `.cursor/mcp.json` in your project root:
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"mcpServers": {
|
|
46
|
+
"weatherapi": {
|
|
47
|
+
"command": "npx",
|
|
48
|
+
"args": ["-y", "weatherapi-mcp"],
|
|
49
|
+
"env": {
|
|
50
|
+
"WEATHERAPI_KEY": "your_api_key_here"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Available Tools
|
|
58
|
+
|
|
59
|
+
| Tool | Description |
|
|
60
|
+
|------|-------------|
|
|
61
|
+
| `get_current_weather` | Real-time conditions — temp, wind, humidity, UV, pressure, AQI |
|
|
62
|
+
| `get_forecast` | Up to 14-day forecast with hourly breakdown and alerts |
|
|
63
|
+
| `get_history` | Historical weather from 1 Jan 2010 onwards |
|
|
64
|
+
| `get_future_weather` | Long-range forecast 14–300 days ahead (Pro+ plan) |
|
|
65
|
+
| `get_marine_weather` | Wave height, swell, tide data for coastal/ocean points |
|
|
66
|
+
| `get_astronomy` | Sunrise, sunset, moonrise, moon phase, illumination |
|
|
67
|
+
| `get_timezone` | IANA timezone and local time for any location |
|
|
68
|
+
| `search_locations` | Autocomplete city/town search with coordinates |
|
|
69
|
+
| `ip_lookup` | Geolocate an IP address or auto-detect caller's location |
|
|
70
|
+
| `get_alerts` | Government weather warnings (USA, UK, Europe, worldwide) |
|
|
71
|
+
| `get_sports` | Upcoming football, cricket, and golf events |
|
|
72
|
+
|
|
73
|
+
## Location Formats
|
|
74
|
+
|
|
75
|
+
The `q` parameter accepts:
|
|
76
|
+
- City name: `London`, `New York`, `Tokyo`
|
|
77
|
+
- Coordinates: `51.5,-0.1`
|
|
78
|
+
- US zip: `10001`
|
|
79
|
+
- UK postcode: `SW1A 1AA`
|
|
80
|
+
- IATA airport: `iata:LHR`
|
|
81
|
+
- IP address: `100.0.0.1`
|
|
82
|
+
- Auto-detect: `auto:ip`
|
|
83
|
+
|
|
84
|
+
## Example Prompts
|
|
85
|
+
|
|
86
|
+
Once connected, ask Claude:
|
|
87
|
+
- *"What's the weather like in Glasgow right now?"*
|
|
88
|
+
- *"Will it rain in London this weekend? Show me hourly."*
|
|
89
|
+
- *"What was the weather in Paris on 15 June 2024?"*
|
|
90
|
+
- *"What time does the sun rise in Tokyo tomorrow?"*
|
|
91
|
+
- *"Are there any weather warnings active for New York?"*
|
|
92
|
+
- *"What's the wave height off the coast of Cornwall today?"*
|
|
93
|
+
- *"What timezone is Sydney in and what time is it there now?"*
|
|
94
|
+
|
|
95
|
+
## Plans
|
|
96
|
+
|
|
97
|
+
| Plan | Price | Calls/month |
|
|
98
|
+
|------|-------|-------------|
|
|
99
|
+
| Free | $0 | 100,000 |
|
|
100
|
+
| Starter | $7/mo | 3,000,000 |
|
|
101
|
+
| Pro+ | $25/mo | 5,000,000 |
|
|
102
|
+
| Business | $65/mo | 10,000,000 |
|
|
103
|
+
| Enterprise | Custom | Custom |
|
|
104
|
+
|
|
105
|
+
## Links
|
|
106
|
+
|
|
107
|
+
- [Documentation](https://www.weatherapi.com/docs/)
|
|
108
|
+
- [API Explorer](https://www.weatherapi.com/api-explorer.aspx)
|
|
109
|
+
- [Sign Up Free](https://www.weatherapi.com/signup.aspx)
|
|
110
|
+
- [OpenAPI Spec](https://www.weatherapi.com/openapi.json)
|
|
111
|
+
- [Pricing](https://www.weatherapi.com/pricing.aspx)
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
5
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
7
|
+
const API_KEY = process.env.WEATHERAPI_KEY;
|
|
8
|
+
const BASE_URL = "https://api.weatherapi.com/v1";
|
|
9
|
+
if (!API_KEY) {
|
|
10
|
+
console.error("Error: WEATHERAPI_KEY environment variable is required.");
|
|
11
|
+
console.error("Get a free key at https://www.weatherapi.com/signup.aspx");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
// Helper: make a GET request to WeatherAPI
|
|
15
|
+
async function weatherRequest(endpoint, params) {
|
|
16
|
+
const searchParams = new URLSearchParams({ key: API_KEY });
|
|
17
|
+
for (const [k, v] of Object.entries(params)) {
|
|
18
|
+
searchParams.set(k, String(v));
|
|
19
|
+
}
|
|
20
|
+
const url = `${BASE_URL}${endpoint}?${searchParams.toString()}`;
|
|
21
|
+
const res = await fetch(url);
|
|
22
|
+
const data = await res.json();
|
|
23
|
+
if (!res.ok) {
|
|
24
|
+
const err = data;
|
|
25
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `WeatherAPI error ${err.error?.code}: ${err.error?.message ?? res.statusText}`);
|
|
26
|
+
}
|
|
27
|
+
return data;
|
|
28
|
+
}
|
|
29
|
+
const server = new index_js_1.Server({
|
|
30
|
+
name: "weatherapi-mcp",
|
|
31
|
+
version: "1.0.0",
|
|
32
|
+
}, {
|
|
33
|
+
capabilities: {
|
|
34
|
+
tools: {},
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
// LIST TOOLS
|
|
38
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
39
|
+
tools: [
|
|
40
|
+
{
|
|
41
|
+
name: "get_current_weather",
|
|
42
|
+
description: "Get real-time current weather for any location. Returns temperature, wind speed and direction, humidity, pressure, UV index, visibility, feels-like temperature, and weather condition. Optionally includes air quality (AQI) data.",
|
|
43
|
+
inputSchema: {
|
|
44
|
+
type: "object",
|
|
45
|
+
properties: {
|
|
46
|
+
q: {
|
|
47
|
+
type: "string",
|
|
48
|
+
description: "Location query. Accepts: city name (London), lat/lon (51.5,-0.1), US zip (10001), UK postcode (SW1), IATA airport code (iata:LHR), IP address, or auto:ip for caller's location.",
|
|
49
|
+
},
|
|
50
|
+
aqi: {
|
|
51
|
+
type: "string",
|
|
52
|
+
enum: ["yes", "no"],
|
|
53
|
+
description: "Include air quality data (CO, NO2, O3, SO2, PM2.5, PM10). Default: no.",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
required: ["q"],
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "get_forecast",
|
|
61
|
+
description: "Get weather forecast for 1 to 14 days. Returns daily summaries (max/min/avg temp, rain chance, UV, wind) and hourly breakdowns. Also returns current conditions, astronomy data (sunrise/sunset/moon phase), and optionally weather alerts and air quality.",
|
|
62
|
+
inputSchema: {
|
|
63
|
+
type: "object",
|
|
64
|
+
properties: {
|
|
65
|
+
q: {
|
|
66
|
+
type: "string",
|
|
67
|
+
description: "Location query — city name, lat/lon, zip, postcode, IATA, or IP.",
|
|
68
|
+
},
|
|
69
|
+
days: {
|
|
70
|
+
type: "number",
|
|
71
|
+
description: "Number of forecast days (1–14). Default: 3.",
|
|
72
|
+
},
|
|
73
|
+
alerts: {
|
|
74
|
+
type: "string",
|
|
75
|
+
enum: ["yes", "no"],
|
|
76
|
+
description: "Include government weather alerts. Default: no.",
|
|
77
|
+
},
|
|
78
|
+
aqi: {
|
|
79
|
+
type: "string",
|
|
80
|
+
enum: ["yes", "no"],
|
|
81
|
+
description: "Include air quality data. Default: no.",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
required: ["q"],
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "get_history",
|
|
89
|
+
description: "Get historical weather data for a specific date from 1 January 2010 onwards. Returns daily summary and full hourly breakdown. Useful for past weather lookups, analytics, and backtesting.",
|
|
90
|
+
inputSchema: {
|
|
91
|
+
type: "object",
|
|
92
|
+
properties: {
|
|
93
|
+
q: {
|
|
94
|
+
type: "string",
|
|
95
|
+
description: "Location query — city name, lat/lon, zip, postcode, IATA, or IP.",
|
|
96
|
+
},
|
|
97
|
+
dt: {
|
|
98
|
+
type: "string",
|
|
99
|
+
description: "Date in yyyy-MM-dd format. Must be on or after 2010-01-01.",
|
|
100
|
+
},
|
|
101
|
+
end_dt: {
|
|
102
|
+
type: "string",
|
|
103
|
+
description: "Optional end date for a date range (Pro+ plan only). Max 30 days range. yyyy-MM-dd.",
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
required: ["q", "dt"],
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: "get_future_weather",
|
|
111
|
+
description: "Get future weather forecast for a date between 14 and 300 days from today. Returns 3-hourly data. Available on Pro+ plan and above.",
|
|
112
|
+
inputSchema: {
|
|
113
|
+
type: "object",
|
|
114
|
+
properties: {
|
|
115
|
+
q: {
|
|
116
|
+
type: "string",
|
|
117
|
+
description: "Location query — city name, lat/lon, zip, postcode, IATA, or IP.",
|
|
118
|
+
},
|
|
119
|
+
dt: {
|
|
120
|
+
type: "string",
|
|
121
|
+
description: "Future date in yyyy-MM-dd format. Must be between 14 and 300 days from today.",
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
required: ["q", "dt"],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: "get_marine_weather",
|
|
129
|
+
description: "Get marine and sailing weather forecast including significant wave height, swell height, swell direction, swell period, and optionally tide data. Useful for nautical and coastal planning.",
|
|
130
|
+
inputSchema: {
|
|
131
|
+
type: "object",
|
|
132
|
+
properties: {
|
|
133
|
+
q: {
|
|
134
|
+
type: "string",
|
|
135
|
+
description: "Coastal or ocean coordinates as lat,lon (e.g. 51.5,-1.8).",
|
|
136
|
+
},
|
|
137
|
+
days: {
|
|
138
|
+
type: "number",
|
|
139
|
+
description: "Forecast days (1–7 depending on plan). Default: 1.",
|
|
140
|
+
},
|
|
141
|
+
tides: {
|
|
142
|
+
type: "string",
|
|
143
|
+
enum: ["yes", "no"],
|
|
144
|
+
description: "Include tide data (Pro+ plan and above). Default: no.",
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
required: ["q"],
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
name: "get_astronomy",
|
|
152
|
+
description: "Get astronomy data for a location and date: sunrise, sunset, moonrise, moonset, moon phase, and moon illumination percentage.",
|
|
153
|
+
inputSchema: {
|
|
154
|
+
type: "object",
|
|
155
|
+
properties: {
|
|
156
|
+
q: {
|
|
157
|
+
type: "string",
|
|
158
|
+
description: "Location query — city name, lat/lon, zip, postcode, IATA, or IP.",
|
|
159
|
+
},
|
|
160
|
+
dt: {
|
|
161
|
+
type: "string",
|
|
162
|
+
description: "Date in yyyy-MM-dd format.",
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
required: ["q", "dt"],
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: "get_timezone",
|
|
170
|
+
description: "Get timezone and current local time for any location. Returns IANA timezone ID (e.g. Europe/London), local time string, and unix epoch.",
|
|
171
|
+
inputSchema: {
|
|
172
|
+
type: "object",
|
|
173
|
+
properties: {
|
|
174
|
+
q: {
|
|
175
|
+
type: "string",
|
|
176
|
+
description: "Location query — city name, lat/lon, zip, postcode, IATA, or IP.",
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
required: ["q"],
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: "search_locations",
|
|
184
|
+
description: "Search for cities and towns by partial name or postcode. Returns an array of matching locations with their coordinates, region, country, and URL slug. Useful for building location pickers or resolving ambiguous place names.",
|
|
185
|
+
inputSchema: {
|
|
186
|
+
type: "object",
|
|
187
|
+
properties: {
|
|
188
|
+
q: {
|
|
189
|
+
type: "string",
|
|
190
|
+
description: "Partial city name, postcode, or coordinates to search. E.g. 'lond', 'SW1', 'paris'.",
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
required: ["q"],
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: "ip_lookup",
|
|
198
|
+
description: "Look up geolocation data for an IP address: city, region, country, coordinates, timezone, and whether it's in the EU. Pass 'auto:ip' to geolocate the caller's own IP address.",
|
|
199
|
+
inputSchema: {
|
|
200
|
+
type: "object",
|
|
201
|
+
properties: {
|
|
202
|
+
q: {
|
|
203
|
+
type: "string",
|
|
204
|
+
description: "IPv4 address, IPv6 address, or 'auto:ip' for caller's IP.",
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
required: ["q"],
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "get_alerts",
|
|
212
|
+
description: "Get active government weather alerts and warnings for a location. Covers USA, UK, Europe, and rest of world. Returns headline, severity, urgency, affected areas, and full description.",
|
|
213
|
+
inputSchema: {
|
|
214
|
+
type: "object",
|
|
215
|
+
properties: {
|
|
216
|
+
q: {
|
|
217
|
+
type: "string",
|
|
218
|
+
description: "Location query — city name, lat/lon, zip, postcode, IATA, or IP.",
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
required: ["q"],
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
name: "get_sports",
|
|
226
|
+
description: "Get upcoming sports events (football/soccer, cricket, golf) for a location, with stadium, country, tournament name, and start time.",
|
|
227
|
+
inputSchema: {
|
|
228
|
+
type: "object",
|
|
229
|
+
properties: {
|
|
230
|
+
q: {
|
|
231
|
+
type: "string",
|
|
232
|
+
description: "Location query — city name, lat/lon, zip, postcode, or IATA.",
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
required: ["q"],
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
],
|
|
239
|
+
}));
|
|
240
|
+
// CALL TOOL
|
|
241
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
242
|
+
const { name, arguments: args } = request.params;
|
|
243
|
+
try {
|
|
244
|
+
let result;
|
|
245
|
+
switch (name) {
|
|
246
|
+
case "get_current_weather": {
|
|
247
|
+
const { q, aqi = "no" } = args;
|
|
248
|
+
result = await weatherRequest("/current.json", { q, aqi });
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
case "get_forecast": {
|
|
252
|
+
const { q, days = 3, alerts = "no", aqi = "no" } = args;
|
|
253
|
+
result = await weatherRequest("/forecast.json", { q, days, alerts, aqi });
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
case "get_history": {
|
|
257
|
+
const { q, dt, end_dt } = args;
|
|
258
|
+
const params = { q, dt };
|
|
259
|
+
if (end_dt)
|
|
260
|
+
params.end_dt = end_dt;
|
|
261
|
+
result = await weatherRequest("/history.json", params);
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
case "get_future_weather": {
|
|
265
|
+
const { q, dt } = args;
|
|
266
|
+
result = await weatherRequest("/future.json", { q, dt });
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
case "get_marine_weather": {
|
|
270
|
+
const { q, days = 1, tides = "no" } = args;
|
|
271
|
+
result = await weatherRequest("/marine.json", { q, days, tides });
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
case "get_astronomy": {
|
|
275
|
+
const { q, dt } = args;
|
|
276
|
+
result = await weatherRequest("/astronomy.json", { q, dt });
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
case "get_timezone": {
|
|
280
|
+
const { q } = args;
|
|
281
|
+
result = await weatherRequest("/timezone.json", { q });
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
case "search_locations": {
|
|
285
|
+
const { q } = args;
|
|
286
|
+
result = await weatherRequest("/search.json", { q });
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
case "ip_lookup": {
|
|
290
|
+
const { q } = args;
|
|
291
|
+
result = await weatherRequest("/ip.json", { q });
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
case "get_alerts": {
|
|
295
|
+
const { q } = args;
|
|
296
|
+
result = await weatherRequest("/alerts.json", { q });
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
case "get_sports": {
|
|
300
|
+
const { q } = args;
|
|
301
|
+
result = await weatherRequest("/sports.json", { q });
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
default:
|
|
305
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
306
|
+
}
|
|
307
|
+
return {
|
|
308
|
+
content: [
|
|
309
|
+
{
|
|
310
|
+
type: "text",
|
|
311
|
+
text: JSON.stringify(result, null, 2),
|
|
312
|
+
},
|
|
313
|
+
],
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
if (error instanceof types_js_1.McpError)
|
|
318
|
+
throw error;
|
|
319
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Unexpected error: ${error instanceof Error ? error.message : String(error)}`);
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
// START
|
|
323
|
+
async function main() {
|
|
324
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
325
|
+
await server.connect(transport);
|
|
326
|
+
console.error("WeatherAPI MCP server running. Set WEATHERAPI_KEY env var to authenticate.");
|
|
327
|
+
}
|
|
328
|
+
main().catch((err) => {
|
|
329
|
+
console.error("Fatal error:", err);
|
|
330
|
+
process.exit(1);
|
|
331
|
+
});
|
|
332
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "weatherapi-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for WeatherAPI.com — real-time weather, forecasts, history, marine, astronomy, air quality and more for AI agents",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"weatherapi-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "ts-node src/index.ts",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mcp",
|
|
18
|
+
"weather",
|
|
19
|
+
"weatherapi",
|
|
20
|
+
"forecast",
|
|
21
|
+
"ai",
|
|
22
|
+
"claude",
|
|
23
|
+
"model-context-protocol",
|
|
24
|
+
"agent",
|
|
25
|
+
"geolocation",
|
|
26
|
+
"astronomy"
|
|
27
|
+
],
|
|
28
|
+
"author": "WeatherAPI.com",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^20.0.0",
|
|
35
|
+
"ts-node": "^10.9.0",
|
|
36
|
+
"typescript": "^5.0.0"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.0.0"
|
|
40
|
+
},
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "https://github.com/weatherapicom/weatherapi-mcp"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://www.weatherapi.com",
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://www.weatherapi.com/contact.aspx"
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import {
|
|
6
|
+
CallToolRequestSchema,
|
|
7
|
+
ErrorCode,
|
|
8
|
+
ListToolsRequestSchema,
|
|
9
|
+
McpError,
|
|
10
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
11
|
+
|
|
12
|
+
const API_KEY = process.env.WEATHERAPI_KEY;
|
|
13
|
+
const BASE_URL = "https://api.weatherapi.com/v1";
|
|
14
|
+
|
|
15
|
+
if (!API_KEY) {
|
|
16
|
+
console.error("Error: WEATHERAPI_KEY environment variable is required.");
|
|
17
|
+
console.error("Get a free key at https://www.weatherapi.com/signup.aspx");
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Helper: make a GET request to WeatherAPI
|
|
22
|
+
async function weatherRequest(
|
|
23
|
+
endpoint: string,
|
|
24
|
+
params: Record<string, string | number>
|
|
25
|
+
): Promise<unknown> {
|
|
26
|
+
const searchParams = new URLSearchParams({ key: API_KEY! });
|
|
27
|
+
for (const [k, v] of Object.entries(params)) {
|
|
28
|
+
searchParams.set(k, String(v));
|
|
29
|
+
}
|
|
30
|
+
const url = `${BASE_URL}${endpoint}?${searchParams.toString()}`;
|
|
31
|
+
const res = await fetch(url);
|
|
32
|
+
const data = await res.json();
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
const err = data as { error?: { code: number; message: string } };
|
|
35
|
+
throw new McpError(
|
|
36
|
+
ErrorCode.InternalError,
|
|
37
|
+
`WeatherAPI error ${err.error?.code}: ${err.error?.message ?? res.statusText}`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
return data;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const server = new Server(
|
|
44
|
+
{
|
|
45
|
+
name: "weatherapi-mcp",
|
|
46
|
+
version: "1.0.0",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
capabilities: {
|
|
50
|
+
tools: {},
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
// LIST TOOLS
|
|
56
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
57
|
+
tools: [
|
|
58
|
+
{
|
|
59
|
+
name: "get_current_weather",
|
|
60
|
+
description:
|
|
61
|
+
"Get real-time current weather for any location. Returns temperature, wind speed and direction, humidity, pressure, UV index, visibility, feels-like temperature, and weather condition. Optionally includes air quality (AQI) data.",
|
|
62
|
+
inputSchema: {
|
|
63
|
+
type: "object",
|
|
64
|
+
properties: {
|
|
65
|
+
q: {
|
|
66
|
+
type: "string",
|
|
67
|
+
description:
|
|
68
|
+
"Location query. Accepts: city name (London), lat/lon (51.5,-0.1), US zip (10001), UK postcode (SW1), IATA airport code (iata:LHR), IP address, or auto:ip for caller's location.",
|
|
69
|
+
},
|
|
70
|
+
aqi: {
|
|
71
|
+
type: "string",
|
|
72
|
+
enum: ["yes", "no"],
|
|
73
|
+
description: "Include air quality data (CO, NO2, O3, SO2, PM2.5, PM10). Default: no.",
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
required: ["q"],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: "get_forecast",
|
|
81
|
+
description:
|
|
82
|
+
"Get weather forecast for 1 to 14 days. Returns daily summaries (max/min/avg temp, rain chance, UV, wind) and hourly breakdowns. Also returns current conditions, astronomy data (sunrise/sunset/moon phase), and optionally weather alerts and air quality.",
|
|
83
|
+
inputSchema: {
|
|
84
|
+
type: "object",
|
|
85
|
+
properties: {
|
|
86
|
+
q: {
|
|
87
|
+
type: "string",
|
|
88
|
+
description: "Location query — city name, lat/lon, zip, postcode, IATA, or IP.",
|
|
89
|
+
},
|
|
90
|
+
days: {
|
|
91
|
+
type: "number",
|
|
92
|
+
description: "Number of forecast days (1–14). Default: 3.",
|
|
93
|
+
},
|
|
94
|
+
alerts: {
|
|
95
|
+
type: "string",
|
|
96
|
+
enum: ["yes", "no"],
|
|
97
|
+
description: "Include government weather alerts. Default: no.",
|
|
98
|
+
},
|
|
99
|
+
aqi: {
|
|
100
|
+
type: "string",
|
|
101
|
+
enum: ["yes", "no"],
|
|
102
|
+
description: "Include air quality data. Default: no.",
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
required: ["q"],
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: "get_history",
|
|
110
|
+
description:
|
|
111
|
+
"Get historical weather data for a specific date from 1 January 2010 onwards. Returns daily summary and full hourly breakdown. Useful for past weather lookups, analytics, and backtesting.",
|
|
112
|
+
inputSchema: {
|
|
113
|
+
type: "object",
|
|
114
|
+
properties: {
|
|
115
|
+
q: {
|
|
116
|
+
type: "string",
|
|
117
|
+
description: "Location query — city name, lat/lon, zip, postcode, IATA, or IP.",
|
|
118
|
+
},
|
|
119
|
+
dt: {
|
|
120
|
+
type: "string",
|
|
121
|
+
description: "Date in yyyy-MM-dd format. Must be on or after 2010-01-01.",
|
|
122
|
+
},
|
|
123
|
+
end_dt: {
|
|
124
|
+
type: "string",
|
|
125
|
+
description:
|
|
126
|
+
"Optional end date for a date range (Pro+ plan only). Max 30 days range. yyyy-MM-dd.",
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
required: ["q", "dt"],
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: "get_future_weather",
|
|
134
|
+
description:
|
|
135
|
+
"Get future weather forecast for a date between 14 and 300 days from today. Returns 3-hourly data. Available on Pro+ plan and above.",
|
|
136
|
+
inputSchema: {
|
|
137
|
+
type: "object",
|
|
138
|
+
properties: {
|
|
139
|
+
q: {
|
|
140
|
+
type: "string",
|
|
141
|
+
description: "Location query — city name, lat/lon, zip, postcode, IATA, or IP.",
|
|
142
|
+
},
|
|
143
|
+
dt: {
|
|
144
|
+
type: "string",
|
|
145
|
+
description:
|
|
146
|
+
"Future date in yyyy-MM-dd format. Must be between 14 and 300 days from today.",
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
required: ["q", "dt"],
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: "get_marine_weather",
|
|
154
|
+
description:
|
|
155
|
+
"Get marine and sailing weather forecast including significant wave height, swell height, swell direction, swell period, and optionally tide data. Useful for nautical and coastal planning.",
|
|
156
|
+
inputSchema: {
|
|
157
|
+
type: "object",
|
|
158
|
+
properties: {
|
|
159
|
+
q: {
|
|
160
|
+
type: "string",
|
|
161
|
+
description: "Coastal or ocean coordinates as lat,lon (e.g. 51.5,-1.8).",
|
|
162
|
+
},
|
|
163
|
+
days: {
|
|
164
|
+
type: "number",
|
|
165
|
+
description: "Forecast days (1–7 depending on plan). Default: 1.",
|
|
166
|
+
},
|
|
167
|
+
tides: {
|
|
168
|
+
type: "string",
|
|
169
|
+
enum: ["yes", "no"],
|
|
170
|
+
description: "Include tide data (Pro+ plan and above). Default: no.",
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
required: ["q"],
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: "get_astronomy",
|
|
178
|
+
description:
|
|
179
|
+
"Get astronomy data for a location and date: sunrise, sunset, moonrise, moonset, moon phase, and moon illumination percentage.",
|
|
180
|
+
inputSchema: {
|
|
181
|
+
type: "object",
|
|
182
|
+
properties: {
|
|
183
|
+
q: {
|
|
184
|
+
type: "string",
|
|
185
|
+
description: "Location query — city name, lat/lon, zip, postcode, IATA, or IP.",
|
|
186
|
+
},
|
|
187
|
+
dt: {
|
|
188
|
+
type: "string",
|
|
189
|
+
description: "Date in yyyy-MM-dd format.",
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
required: ["q", "dt"],
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: "get_timezone",
|
|
197
|
+
description:
|
|
198
|
+
"Get timezone and current local time for any location. Returns IANA timezone ID (e.g. Europe/London), local time string, and unix epoch.",
|
|
199
|
+
inputSchema: {
|
|
200
|
+
type: "object",
|
|
201
|
+
properties: {
|
|
202
|
+
q: {
|
|
203
|
+
type: "string",
|
|
204
|
+
description: "Location query — city name, lat/lon, zip, postcode, IATA, or IP.",
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
required: ["q"],
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "search_locations",
|
|
212
|
+
description:
|
|
213
|
+
"Search for cities and towns by partial name or postcode. Returns an array of matching locations with their coordinates, region, country, and URL slug. Useful for building location pickers or resolving ambiguous place names.",
|
|
214
|
+
inputSchema: {
|
|
215
|
+
type: "object",
|
|
216
|
+
properties: {
|
|
217
|
+
q: {
|
|
218
|
+
type: "string",
|
|
219
|
+
description: "Partial city name, postcode, or coordinates to search. E.g. 'lond', 'SW1', 'paris'.",
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
required: ["q"],
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
name: "ip_lookup",
|
|
227
|
+
description:
|
|
228
|
+
"Look up geolocation data for an IP address: city, region, country, coordinates, timezone, and whether it's in the EU. Pass 'auto:ip' to geolocate the caller's own IP address.",
|
|
229
|
+
inputSchema: {
|
|
230
|
+
type: "object",
|
|
231
|
+
properties: {
|
|
232
|
+
q: {
|
|
233
|
+
type: "string",
|
|
234
|
+
description: "IPv4 address, IPv6 address, or 'auto:ip' for caller's IP.",
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
required: ["q"],
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
name: "get_alerts",
|
|
242
|
+
description:
|
|
243
|
+
"Get active government weather alerts and warnings for a location. Covers USA, UK, Europe, and rest of world. Returns headline, severity, urgency, affected areas, and full description.",
|
|
244
|
+
inputSchema: {
|
|
245
|
+
type: "object",
|
|
246
|
+
properties: {
|
|
247
|
+
q: {
|
|
248
|
+
type: "string",
|
|
249
|
+
description: "Location query — city name, lat/lon, zip, postcode, IATA, or IP.",
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
required: ["q"],
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: "get_sports",
|
|
257
|
+
description:
|
|
258
|
+
"Get upcoming sports events (football/soccer, cricket, golf) for a location, with stadium, country, tournament name, and start time.",
|
|
259
|
+
inputSchema: {
|
|
260
|
+
type: "object",
|
|
261
|
+
properties: {
|
|
262
|
+
q: {
|
|
263
|
+
type: "string",
|
|
264
|
+
description: "Location query — city name, lat/lon, zip, postcode, or IATA.",
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
required: ["q"],
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
],
|
|
271
|
+
}));
|
|
272
|
+
|
|
273
|
+
// CALL TOOL
|
|
274
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
275
|
+
const { name, arguments: args } = request.params;
|
|
276
|
+
|
|
277
|
+
try {
|
|
278
|
+
let result: unknown;
|
|
279
|
+
|
|
280
|
+
switch (name) {
|
|
281
|
+
case "get_current_weather": {
|
|
282
|
+
const { q, aqi = "no" } = args as { q: string; aqi?: string };
|
|
283
|
+
result = await weatherRequest("/current.json", { q, aqi });
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
case "get_forecast": {
|
|
287
|
+
const { q, days = 3, alerts = "no", aqi = "no" } = args as {
|
|
288
|
+
q: string;
|
|
289
|
+
days?: number;
|
|
290
|
+
alerts?: string;
|
|
291
|
+
aqi?: string;
|
|
292
|
+
};
|
|
293
|
+
result = await weatherRequest("/forecast.json", { q, days, alerts, aqi });
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
case "get_history": {
|
|
297
|
+
const { q, dt, end_dt } = args as { q: string; dt: string; end_dt?: string };
|
|
298
|
+
const params: Record<string, string | number> = { q, dt };
|
|
299
|
+
if (end_dt) params.end_dt = end_dt;
|
|
300
|
+
result = await weatherRequest("/history.json", params);
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
case "get_future_weather": {
|
|
304
|
+
const { q, dt } = args as { q: string; dt: string };
|
|
305
|
+
result = await weatherRequest("/future.json", { q, dt });
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
case "get_marine_weather": {
|
|
309
|
+
const { q, days = 1, tides = "no" } = args as {
|
|
310
|
+
q: string;
|
|
311
|
+
days?: number;
|
|
312
|
+
tides?: string;
|
|
313
|
+
};
|
|
314
|
+
result = await weatherRequest("/marine.json", { q, days, tides });
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
case "get_astronomy": {
|
|
318
|
+
const { q, dt } = args as { q: string; dt: string };
|
|
319
|
+
result = await weatherRequest("/astronomy.json", { q, dt });
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
case "get_timezone": {
|
|
323
|
+
const { q } = args as { q: string };
|
|
324
|
+
result = await weatherRequest("/timezone.json", { q });
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
case "search_locations": {
|
|
328
|
+
const { q } = args as { q: string };
|
|
329
|
+
result = await weatherRequest("/search.json", { q });
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
case "ip_lookup": {
|
|
333
|
+
const { q } = args as { q: string };
|
|
334
|
+
result = await weatherRequest("/ip.json", { q });
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
case "get_alerts": {
|
|
338
|
+
const { q } = args as { q: string };
|
|
339
|
+
result = await weatherRequest("/alerts.json", { q });
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
case "get_sports": {
|
|
343
|
+
const { q } = args as { q: string };
|
|
344
|
+
result = await weatherRequest("/sports.json", { q });
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
default:
|
|
348
|
+
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return {
|
|
352
|
+
content: [
|
|
353
|
+
{
|
|
354
|
+
type: "text",
|
|
355
|
+
text: JSON.stringify(result, null, 2),
|
|
356
|
+
},
|
|
357
|
+
],
|
|
358
|
+
};
|
|
359
|
+
} catch (error) {
|
|
360
|
+
if (error instanceof McpError) throw error;
|
|
361
|
+
throw new McpError(
|
|
362
|
+
ErrorCode.InternalError,
|
|
363
|
+
`Unexpected error: ${error instanceof Error ? error.message : String(error)}`
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
// START
|
|
369
|
+
async function main() {
|
|
370
|
+
const transport = new StdioServerTransport();
|
|
371
|
+
await server.connect(transport);
|
|
372
|
+
console.error("WeatherAPI MCP server running. Set WEATHERAPI_KEY env var to authenticate.");
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
main().catch((err) => {
|
|
376
|
+
console.error("Fatal error:", err);
|
|
377
|
+
process.exit(1);
|
|
378
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": ["ES2020"],
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationMap": true,
|
|
14
|
+
"sourceMap": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|