# 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 |
```