#
tokens: 2124/50000 5/5 files
lines: on (toggle) GitHub
raw markdown copy reset
# Directory Structure

```
├── .gitignore
├── package-lock.json
├── package.json
├── README.md
├── src
│   └── server.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
 1 | .env
 2 | node_modules/
 3 | dist/
 4 | .vscode/
 5 | .idea/
 6 | *.log
 7 | npm-debug.log*
 8 | .DS_Store
 9 | Thumbs.db
10 | 
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # WeatherAPI MCP Server
 2 | 
 3 | An MCP server that provides current weather and air quality data using WeatherAPI.
 4 | 
 5 | ## Features
 6 | 
 7 | - Get current weather data for any city
 8 | - Air quality information (optional)
 9 | - Dynamic URI support for weather resources
10 | - Easy integration with n8n, Claude Desktop App, Windsurf IDE,Cursor IDE, and other MCP clients
11 | 
12 | ## Getting Started
13 | 
14 | ### Get WeatherAPI Key
15 | 
16 | 1. Go to [WeatherAPI.com](https://www.weatherapi.com)
17 | 2. Sign up for a free account
18 | 3. After signing in, go to your dashboard
19 | 4. Copy your API key from the "API Keys" section
20 | 
21 | ### MCP Configuration
22 | 
23 | Add the following configuration to your Windsurf MCP config file:
24 | 
25 | ```json
26 | {
27 |   "mcpServers": {
28 |     "weather": {
29 |       "command": "npx",
30 |       "args": ["-y", "@swonixs/weatherapi-mcp"],
31 |       "env": {
32 |         "WEATHER_API_KEY": "YOUR_API_KEY_HERE"
33 |       }
34 |     }
35 |   }
36 | }
37 | ```
38 | 
39 | Replace `YOUR_API_KEY_HERE` with the API key you obtained from WeatherAPI.com.
40 | 
41 | ### Tools
42 | 
43 | #### get_weather
44 | 
45 | Get current weather data for a specified city.
46 | 
47 | Parameters:
48 | - `location` (string): City name
49 | 
50 | Example response:
51 | ```json
52 | {
53 |   "location": "London",
54 |   "country": "United Kingdom",
55 |   "temp_c": 15.0,
56 |   "condition": "Partly cloudy",
57 |   "humidity": 71,
58 |   "wind_kph": 14.4,
59 |   "air_quality": {
60 |     "co": 230.3,
61 |     "no2": 13.5,
62 |     "o3": 52.9,
63 |     "pm2_5": 8.5,
64 |     "pm10": 12.1,
65 |     "us-epa-index": 1
66 |   }
67 | }
68 | ```
69 | 
70 | ### Repository
71 | 
72 | [WeatherAPI MCP Server](https://github.com/swonixs/weatherapi-mcp)
73 | 
74 | ## License
75 | 
76 | MIT
77 | 
```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "ES2022",
 4 |     "module": "ES2022",
 5 |     "moduleResolution": "node",
 6 |     "outDir": "./dist",
 7 |     "rootDir": "./src",
 8 |     "strict": true,
 9 |     "esModuleInterop": true,
10 |     "skipLibCheck": true,
11 |     "forceConsistentCasingInFileNames": true,
12 |     "declaration": true,
13 |     "allowJs": true
14 |   },
15 |   "include": ["src/**/*"],
16 |   "exclude": ["node_modules"]
17 | }
18 | 
```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "@swonixs/weatherapi-mcp",
 3 |   "version": "1.1.0",
 4 |   "description": "WeatherAPI MCP sunucusu - Hava durumu ve hava kalitesi verileri için MCP aracı",
 5 |   "type": "module",
 6 |   "main": "dist/server.js",
 7 |   "types": "dist/server.d.ts",
 8 |   "bin": {
 9 |     "weatherapi-mcp": "./dist/server.js"
10 |   },
11 |   "scripts": {
12 |     "build": "tsc",
13 |     "start": "node dist/server.js",
14 |     "dev": "ts-node --esm src/server.ts",
15 |     "prepare": "npm run build"
16 |   },
17 |   "keywords": [
18 |     "mcp",
19 |     "weather",
20 |     "weatherapi",
21 |     "hava-durumu",
22 |     "modelcontextprotocol",
23 |     "air-quality"
24 |   ],
25 |   "author": "swonixs",
26 |   "license": "MIT",
27 |   "dependencies": {
28 |     "@modelcontextprotocol/sdk": "^1.7.0",
29 |     "axios": "^1.6.7",
30 |     "dotenv": "^16.4.5",
31 |     "zod": "^3.22.4"
32 |   },
33 |   "devDependencies": {
34 |     "@types/node": "^20.11.25",
35 |     "ts-node": "^10.9.2",
36 |     "typescript": "^5.4.2"
37 |   },
38 |   "files": [
39 |     "dist",
40 |     "README.md"
41 |   ]
42 | }
43 | 
```

--------------------------------------------------------------------------------
/src/server.ts:
--------------------------------------------------------------------------------

```typescript
 1 | #!/usr/bin/env node
 2 | 
 3 | import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
 4 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
 5 | import { z } from "zod";
 6 | import axios from 'axios';
 7 | import dotenv from 'dotenv';
 8 | 
 9 | // .env dosyasını yükle
10 | dotenv.config();
11 | 
12 | // Weather API yapılandırması
13 | const API_KEY = process.env.WEATHER_API_KEY;
14 | if (!API_KEY) {
15 |   throw new Error('WEATHER_API_KEY çevre değişkeni tanımlanmamış!');
16 | }
17 | const BASE_URL = 'http://api.weatherapi.com/v1';
18 | 
19 | // MCP sunucusu oluştur
20 | const server = new McpServer({
21 |   name: "WeatherAPI",
22 |   version: "1.1.0"
23 | });
24 | 
25 | // Weather API tool tanımı
26 | type WeatherArgs = {
27 |   location: string;
28 | };
29 | 
30 | const getWeather = async (args: WeatherArgs) => {
31 |   try {
32 |     const response = await axios.get(`${BASE_URL}/current.json`, {
33 |       params: {
34 |         key: API_KEY,
35 |         q: args.location
36 |       }
37 |     });
38 | 
39 |     const data = response.data;
40 |     return {
41 |       content: [{
42 |         type: "text" as const,
43 |         text: JSON.stringify({
44 |           location: data.location.name,
45 |           country: data.location.country,
46 |           temp_c: data.current.temp_c,
47 |           condition: data.current.condition.text,
48 |           humidity: data.current.humidity,
49 |           wind_kph: data.current.wind_kph
50 |         }, null, 2)
51 |       }]
52 |     };
53 |   } catch (error) {
54 |     if (axios.isAxiosError(error)) {
55 |       throw new Error(`Hava durumu bilgisi alınamadı: ${error.response?.data?.error?.message || error.message}`);
56 |     }
57 |     throw error;
58 |   }
59 | };
60 | 
61 | // Tool'u kaydet
62 | server.tool(
63 |   "get_weather",
64 |   {
65 |     location: z.string().describe("Şehir adı")
66 |   },
67 |   async (args: WeatherArgs) => getWeather(args)
68 | );
69 | 
70 | // Weather resource tanımı
71 | server.resource(
72 |   "weather",
73 |   new ResourceTemplate("weather://{city}/current", { list: undefined }),
74 |   async (uri, variables) => {
75 |     const city = variables.city as string;
76 |     const result = await getWeather({ location: city });
77 |     return {
78 |       contents: [{
79 |         uri: uri.href,
80 |         text: result.content[0].text
81 |       }]
82 |     };
83 |   }
84 | );
85 | 
86 | // Sunucuyu başlat
87 | const transport = new StdioServerTransport();
88 | await server.connect(transport);
89 | 
```