天气数据服务

OpenWeatherMap MCP Server是一个提供实时天气、预报、空气质量数据和地理编码服务的综合模型上下文协议服务器。

  • by dennisonbertram
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 dennisonbertram/mcp-weather

使用说明

OpenWeatherMap MCP服务器

用于访问OpenWeatherMap天气数据的综合模型上下文协议(MCP)服务器。该服务器通过15个专用工具和4个资源端点提供当前天气、预报、空气质量数据和地理编码服务。

🌦️ 特性

天气工具(共15个)

  • 当前天气:通过位置名称或坐标获取实时天气
  • 预测:5天预报、每小时数据和天气摘要
  • 空气质量:当前污染数据、预测和历史分析
  • 地理编码:在位置名称和坐标之间转换
  • 一次调用API:综合天气数据和政府警报

资源(共4个)

  • 天气参数:温度、风、压力单位的参考数据
  • 条件代码:完整绘制OpenWeatherMap天气条件图
  • API状态:服务可用性的动态监控
  • 语言:国际查询支持的语言代码

生产特点

  • ✅ 速率限制:60个呼叫/分钟,带队列管理
  • ✅ 错误处理:全面的重试逻辑和用户友好的消息
  • ✅ 输入验证:对所有输入进行Zod模式验证
  • ✅ 结构化日志记录:具有可配置级别的JSON格式日志
  • ✅ 类型安全:完整的TypeScript实现
  • ✅ 测试覆盖率:174项具有真实夹具的综合测试
  • ✅ 多个传输:STDIO、HTTP和SSE传输支持

📋 先决条件

  • Node.js 18或更高版本
  • OpenWeatherMap API密钥(提供免费层)

🚀 安装

1.获取OpenWeatherMap API密钥

  1. 注册地址: OpenWeatherMap
  2. 验证您的电子邮件地址
  3. 从仪表板生成一个免费的API密钥
  4. 等待1-2小时激活密钥(如果是新创建的)

2.设置环境

# Clone and install
git clone <repository-url>
cd mcp-weather
npm install

# Create environment file
cp .env.example .env

3.配置API密钥

编辑 .env 文件:

# OpenWeatherMap API Configuration
OPENWEATHER_API_KEY=your_api_key_here
OPENWEATHER_BASE_URL=https://api.openweathermap.org/data/2.5

4.构建和测试

# Build the server
npm run build

# Run tests to verify setup
npm test

# Start the server
npm start

🔧 用法

OpenWeatherMap MCP服务器支持用于不同部署场景的多种传输协议:

🚀 运输选项

1. STDIO传输 (默认值-MCP客户端)

非常适合MCP客户端集成(Claude Code等)

# Default STDIO mode
npm start

# Explicit STDIO mode
npm start -- --stdio

Claude代码配置:

{
  "mcp": {
    "servers": {
      "openweathermap": {
        "command": "node",
        "args": ["/path/to/mcp-weather/dist/index.js"],
        "env": {
          "OPENWEATHER_API_KEY": "your_api_key_here"
        }
      }
    }
  }
}

2. HTTP传输 (REST API+流式处理)

非常适合web应用程序和直接访问API

# Start HTTP server on port 3000
npm run start:http

# Custom port and host
npm start -- --http --port 8080 --host localhost

API终点:

  • POST /mcp -MCP JSON-RPC请求
  • GET /mcp -服务器发送流媒体事件
  • DELETE /mcp -会话终止
  • GET /health -健康检查

HTTP请求示例:

curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
      "name": "get_current_weather",
      "arguments": {
        "location": "London"
      }
    },
    "id": 1
  }'

3. SSE 运输 (服务器发送的事件)

最适合需要推送通知的实时web应用程序

# Start SSE server on port 3001
npm run start:sse

# Custom configuration
npm start -- --sse --port 3002 --host 0.0.0.0

SSE连接:

const eventSource = new EventSource('http://localhost:3001/sse');
eventSource.onmessage = (event) => {
  const response = JSON.parse(event.data);
  console.log('Weather update:', response);
};

4. 开发与测试

# Development with auto-reload
npm run dev

# Test different transports
npm run test:transport

# MCP protocol testing
npm run test:mcp

🌐 Web集成示例

JavaScript/TypeScript客户端

// HTTP Transport Client
async function getWeather(location: string) {
  const response = await fetch('http://localhost:3000/mcp', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'mcp-session-id': 'my-session-123'
    },
    body: JSON.stringify({
      jsonrpc: '2.0',
      method: 'tools/call',
      params: {
        name: 'get_current_weather',
        arguments: { location }
      },
      id: Date.now()
    })
  });
  
  return response.json();
}

// SSE Transport Client
function subscribeToWeatherUpdates() {
  const eventSource = new EventSource('http://localhost:3001/sse');
  
  eventSource.addEventListener('weather-update', (event) => {
    const data = JSON.parse(event.data);
    updateWeatherDisplay(data);
  });
  
  return eventSource;
}

Python客户端

import requests
import json

# HTTP Transport
def get_weather(location):
    url = "http://localhost:3000/mcp"
    payload = {
        "jsonrpc": "2.0",
        "method": "tools/call",
        "params": {
            "name": "get_current_weather",
            "arguments": {
                "location": location
            }
        },
        "id": 1
    }
    
    response = requests.post(url, json=payload)
    return response.json()

# Usage
weather = get_weather("Tokyo")
print(json.dumps(weather, indent=2))

🔒 安全配置

HTTP传输安全

# Enable CORS restrictions
npm start -- --http --cors-origins="https://myapp.com,https://admin.myapp.com"

# Enable security headers
npm start -- --http --enable-security

# Custom session timeout (1 hour = 3600000ms)
npm start -- --http --session-timeout=3600000

环境变量

# Security settings
CORS_ORIGINS=https://myapp.com,https://localhost:3000
ENABLE_COMPRESSION=true
ENABLE_SECURITY=true
SESSION_TIMEOUT=3600000
MAX_SESSIONS=100

# OpenWeatherMap API
OPENWEATHER_API_KEY=your_api_key_here
OPENWEATHER_BASE_URL=https://api.openweathermap.org/data/2.5

🐳 Docker部署

Docker编写HTTP传输

version: '3.8'

services:
  mcp-weather-http:
    build: .
    ports:
      - "3000:3000"
    environment:
      - OPENWEATHER_API_KEY=your_api_key_here
      - NODE_ENV=production
    command: ["npm", "start", "--", "--http", "--host", "0.0.0.0"]
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  mcp-weather-sse:
    build: .
    ports:
      - "3001:3001"
    environment:
      - OPENWEATHER_API_KEY=your_api_key_here
      - NODE_ENV=production
    command: ["npm", "start", "--", "--sse", "--host", "0.0.0.0"]

🛠️ 可用工具

当前天气

  • get_current_weather(location) -获取任何位置的当前天气
  • get_weather_by_coordinates(lat, lon) -精确坐标天气

预测

  • get_5day_forecast(location) -5天预报,间隔3小时
  • get_hourly_forecast(location) -详细的小时预测
  • get_forecast_summary(location) -人类可读的天气摘要

地理编码

  • geocode_location(location) -将位置名称转换为坐标
  • reverse_geocode(lat, lon) -将坐标转换为位置名称
  • search_cities(query) -查找与搜索词匹配的城市

空气质量

  • get_air_pollution(lat, lon) -当前空气质量和污染物水平
  • get_air_pollution_forecast(lat, lon) -5天空气质量预报
  • get_air_pollution_history(lat, lon, start, end) -历史污染数据

一次调用API

  • get_onecall_weather(lat, lon) -综合天气数据
  • get_weather_timemachine(lat, lon, date) -历史天气数据
  • get_weather_day_summary(lat, lon, date) -每日天气汇总

📊 示例响应

当前天气

{
  "location": "London, GB",
  "temperature": {
    "current": 20.1,
    "feels_like": 19.8,
    "min": 18.2,
    "max": 22.4,
    "unit": "celsius"
  },
  "condition": {
    "main": "Rain", 
    "description": "light rain",
    "icon": "10d"
  },
  "wind": {
    "speed": 7.72,
    "direction": 230,
    "unit": "meter/sec"
  },
  "humidity": 68,
  "pressure": 1001
}

空气质量

{
  "location": "Tokyo, JP",
  "coordinates": [35.68, 139.76],
  "air_quality_index": 2,
  "status": "Good",
  "pollutants": {
    "pm2_5": 9.91,
    "pm10": 19.97,
    "o3": 76.95,
    "no2": 6.29,
    "so2": 8.71,
    "co": 131.88
  },
  "health_recommendations": [
    "Air quality is satisfactory for most people",
    "Enjoy outdoor activities"
  ]
}

🧪 测试

# Run all tests
npm test

# Run specific test suites
npm run test:unit
npm run test:integration

# Test with coverage
npm run test:coverage

# Test specific transport
npm run test:http
npm run test:sse

🔒 安全

  • ✅ 没有硬编码的秘密 -所有凭据都通过环境变量
  • ✅ 输入净化 -Zod验证可防止恶意输入
  • ✅ 速率限制 -防止API滥用
  • ✅ 错误边界 -错误消息中没有敏感数据
  • ✅ 安全日志记录 -从未记录API密钥
  • ✅ CORS保护 -可配置的原产地限制
  • ✅ 安全标头 -用于HTTP传输的Helmet.js集成
  • ✅ 会话管理 -可配置的超时和限制

📈 速率限制

免费等级(默认):

  • 每分钟60次通话
  • 每月100万次通话

内置管理:

  • 接近限制时自动排队
  • 速率限制错误的指数回退
  • 超出限制时清除错误消息

🐛 故障排除

API关键问题

# Test your API key directly
curl "https://api.openweathermap.org/data/2.5/weather?q=London&appid=YOUR_KEY"

# Should return weather data, not 401 error

常见解决方案:

  • 等待1-2小时以激活新密钥
  • 验证OpenWeatherMap帐户中的电子邮件地址
  • 检查密钥未过期或挂起
  • 复制密钥时确保没有多余的空格

运输问题

STDIO传输

# Enable debug logging
DEBUG=true npm start

# Check server health
echo '{"jsonrpc":"2.0","method":"ping","id":1}' | node dist/index.js

HTTP传输

# Test HTTP health endpoint
curl http://localhost:3000/health

# Test MCP endpoint
curl -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'

SSE 运输

# Test SSE connection
curl -N http://localhost:3001/sse

# Test with browser console
const es = new EventSource('http://localhost:3001/sse');
es.onmessage = console.log;

测试模式

# Run with test fixtures (no API calls)
NODE_ENV=test npm start
NODE_ENV=test npm start -- --http
NODE_ENV=test npm start -- --sse

🤝 贡献

  1. 分叉存储库
  2. 创建要素分支
  3. 添加综合测试
  4. 遵循TypeScript和ESLint指南
  5. 提交拉取请求

📄 许可证

MIT许可证-有关详细信息,请参阅许可证文件。

🔗 链接

📋 API覆盖范围

此MCP服务器实现了以下OpenWeatherMap API:

API 端点 状态 自由层
当前天气 /weather ✅ 是的
5天预测 /forecast ✅ 是的
地理编码 /geo/1.0/direct, /geo/1.0/reverse ✅ 是的
空气污染 /air_pollution/* ✅ 是的
One Call 3.0 /onecall ✅ 高级*

*One Call API 3.0需要订阅,但在免费层上会适度降级。

🚀 运输比较

运输 用例 优点 缺点
标准输入输出 MCP客户端 本机MCP支持,安全 仅限CLI/桌面
超文本传输协议 Web API 类似REST,广泛支持 无状态,无需推送
SSE 实时应用程序 服务器推送、实时更新 特定于浏览器

内置于❤️ 对于MCP生态系统