内容
# 天气MCP服务器
一个生产就绪的**模型上下文协议(MCP)服务器**,为任何MCP兼容的客户端(Claude Desktop、MCP Inspector或自定义客户端)提供与天气相关的**工具**、**资源**和**提示**,并由OpenWeatherMap API支持。
使用**Python 3.12+**、**FastMCP**、**HTTPX**、**Pydantic v2**、**python-dotenv**和**Loguru**构建,并具有完整的**Pytest**测试套件。
---
## 目录
- [项目概述](#项目概述)
- [什么是MCP?](#什么是mcp)
- [为什么MCP很重要?](#为什么mcp很重要)
- [架构](#架构)
- [文件夹结构](#文件夹结构)
- [功能](#功能)
- [工具](#工具)
- [资源](#资源)
- [提示](#提示)
- [安装指南](#安装指南)
- [1. 安装Python](#1-安装python)
- [2. Visual Studio Code设置](#2-visual-studio-code设置)
- [3. 克隆/打开项目](#3-克隆打开项目)
- [4. 创建虚拟环境](#4-创建虚拟环境)
- [5. 安装依赖项](#5-安装依赖项)
- [6. API密钥设置](#6-api密钥设置)
- [运行MCP服务器](#运行mcp服务器)
- [使用MCP客户端连接](#使用mcp客户端连接)
- [Claude Desktop](#claude-desktop)
- [MCP Inspector](#mcp-inspector)
- [测试](#测试)
- [故障排除](#故障排除)
- [未来改进](#未来改进)
- [许可证](#许可证)
---
## 项目概述
`weather-mcp-server`公开天气数据 - 当前条件、预报、多城市比较、空气质量和严重天气警报 - 作为标准化的**MCP工具、资源和提示**。它被设计为现实世界MCP服务器的参考质量示例:干净分层、完全类型化、结构化输出优先、彻底记录、优雅错误处理和完全单元/集成测试。
关键设计目标:
- **干净架构** - HTTP/API问题、业务逻辑和MCP胶水代码生活在单独的、单一责任模块中(参见[架构](#架构)和[`docs/architecture.md`](docs/architecture.md))。
- **结构化一切** - 每个工具都返回一个类型良好的、验证过的Pydantic模型(转储为JSON),包括失败时的*结构化错误形状* - 绝不出现原始异常或自由文本错误字符串。
- **生产卫生** - 基于环境的配置、通过Loguru旋转文件日志、重试逻辑用于瞬时HTTP故障和优雅降级(例如,当天气警报需要付费API计划时)。
- **完全测试** - `pytest` + `respx`模拟所有出站HTTP调用,因此整个套件离线运行、确定性运行,无需API密钥。
## 什么是MCP?
**模型上下文协议(MCP)**是一种开放的、基于JSON-RPC 2.0的标准,允许AI应用程序(“客户端”)连接到外部系统(“服务器”),以统一的方式公开数据和功能 - 模型可以调用的工具、模型可以读取的资源以及模型可以作为对话启动器的提示。有关此项目中实现的工具、资源和提示的更深入的解释,请参见[`docs/mcp-primer.md`](docs/mcp-primer.md)。
## 为什么MCP很重要?
没有共享协议,每个AI应用程序都需要与每个外部工具或数据源进行定制集成 - 经典的**MxN问题**(M个应用程序 x N个工具 = MxN集成)。MCP将此问题转化为**M+N问题**:为每个数据源构建一个MCP服务器,为每个应用程序构建一个MCP客户端,任何客户端都可以与任何服务器通信。这可以实现:
- **标准化**而不是为每个应用程序定制胶水代码。
- **可重用性** - 此服务器在未经修改的情况下与任何MCP客户端一起工作。
- **可发现性** - 客户端可以以编程方式枚举工具、资源和提示以及它们的JSON模式。
- **结构化、类型化交互**而不是模型必须自己解析临时API响应。
## 架构
```
MCP客户端(Claude Desktop / MCP Inspector / 自定义)
│ JSON-RPC via stdio
▼
server.py - 构建FastMCP应用程序,拥有生命周期,连接所有内容
│
┌────┼──────────────┬───────────────┐
▼ ▼ ▼
tools.py resources.py prompts.py
(5个MCP工具) (3个MCP资源) (3个MCP提示)
│
▼
weather_service.py - OpenWeatherMap周围的httpx.AsyncClient包装器
│
▼
schemas.py - Pydantic v2模型(输入、结构化输出、错误)
交叉剪裁:config.py(Pydantic设置)和logging_config.py(Loguru)
```
`weather_service.py`从不导入`fastmcp`,而`tools.py`直接不与`httpx`通信 - 这种分离保持业务逻辑独立可测试,MCP特定的胶水代码最小。有关错误处理策略和天气警报的优雅降级行为的完整详细信息,请参见[`docs/architecture.md`](docs/architecture.md)。
## 文件夹结构
```
weather-mcp-server/
├── README.md # 此文件
├── INSTRUCTION.md # 快速启动/操作说明
├── LICENSE # MIT许可证
├── .gitignore
├── requirements.txt # Python依赖项
├── .env.example # 记录的环境变量模板
├── pytest.ini # Pytest配置
├── server.py # MCP服务器入口点
├── config.py # Pydantic设置(基于环境的配置)
├── weather_service.py # OpenWeatherMap API客户端 + 业务逻辑
├── tools.py # MCP工具注册
├── resources.py # MCP资源注册
├── prompts.py # MCP提示注册
├── schemas.py # Pydantic v2模型(I/O + 错误)
├── logging_config.py # Loguru配置
├── tests/
│ ├── __init__.py
│ ├── conftest.py # 共享夹具(假API响应等)
│ ├── test_schemas.py # Pydantic模型验证测试
│ ├── test_weather_service.py # 服务层测试(respx模拟HTTP)
│ ├── test_tools.py # 端到端MCP工具测试
│ └── test_resources_and_prompts.py
├── docs/
│ ├── architecture.md # 深入架构文档
│ └── mcp-primer.md # MCP概念入门(工具/资源/提示)
└── .vscode/
├── settings.json # Python解释器、测试发现、 linting
├── launch.json # 运行/调试配置
└── extensions.json # 推荐的VS Code扩展
```
## 功能
### 工具
| 工具 | 描述 |
|--------------------------|-------------------------------------------------------------------------------|
| `get_current_weather` | 城市的当前温度、湿度、风、云量和天气状况。 |
| `get_weather_forecast` | 城市的1-5天/3小时分辨率预报。 |
| `compare_cities` | 2-10个城市的并排当前天气比较。 |
| `get_air_quality` | 空气质量指数(1-5)和污染物浓度(CO、NO2、O3、PM2.5等)。 |
| `get_weather_alerts` | 城市的活跃官方严重天气警报/警告。 |
每个工具:
- 通过类型提示验证输入(FastMCP自动生成JSON模式)。
- 成功时返回**结构化、JSON可序列化Pydantic模型**。
- 失败时返回**结构化`ToolError`**对象(`error`、`error_type`、`message`)- 绝不出现未处理的异常。
### 资源
| 资源URI | 描述 |
|--------------------------------|--------------------------------------------------------------------------|
| `weather://cities/supported` | 精选的热门、知名城市列表。 |
| `weather://units` | 支持的单位系统(`metric`、`imperial`、`standard`)及其含义。 |
| `weather://api/info` | 关于底层天气API的元数据:使用的端点、速率限制、密钥状态。 |
### 提示
| 提示 | 描述 |
|-------------------------------|-------------------------------------------------------------------------|
| `weather_summary` | 城市的友好、普通语言天气简报。 |
| `travel_recommendation` | 基于预报和警报的旅行规划建议。 |
| `clothing_recommendation` | 基于当前条件的实用穿衣建议。 |
---
## 安装指南
### 1. 安装Python
该项目需要**Python 3.12或更新版本**。
- **Windows**:从[python.org/downloads](https://www.python.org/downloads/)下载安装程序,并确保在安装过程中选中**"Add python.exe to PATH"**。
- **macOS**:`brew install python@3.12`(通过[Homebrew](https://brew.sh)),或从[python.org](https://www.python.org/downloads/)下载。
- **Linux**:使用您的发行版的包管理器,例如`sudo apt install python3.12 python3.12-venv`在Debian/Ubuntu上。
验证安装:
```bash
python3 --version
# Python 3.12.x(或更新版本)
```
### 2. Visual Studio Code设置
1. 安装[Visual Studio Code](https://code.visualstudio.com/)。
2. 安装以下扩展(也列在`.vscode/extensions.json`中,VS Code会自动提示您安装):
- **Python** (`ms-python.python`)
- **Pylance** (`ms-python.vscode-pylance`)
- **Python Debugger** (`ms-python.debugpy`)
- **Ruff** (`charliermarsh.ruff`) - 可选,用于linting/formatting
### 3. 克隆/打开项目
```bash
git clone https://github.com/your-username/weather-mcp-server.git
cd weather-mcp-server
code .
```
(或者简单地提取项目存档并在VS Code中通过**文件 -> 打开文件夹...**打开文件夹。)
### 4. 创建虚拟环境
从VS Code的集成终端(**终端 -> 新终端**):
**macOS / Linux:**
```bash
python3 -m venv .venv
source .venv/bin/activate
```
**Windows(PowerShell):**
```powershell
py -3.12 -m venv .venv
.venv\Scripts\Activate.ps1
```
激活后,VS Code应该自动检测`.venv`作为工作区解释器(配置在`.vscode/settings.json`中)。如果它没有检测到,请打开命令面板(`Ctrl+Shift+P` / `Cmd+Shift+P`),运行**Python:选择解释器**,并选择`.venv`。
### 5. 安装依赖项
```bash
pip install --upgrade pip
pip install -r requirements.txt
```
### 6. API密钥设置
1. 在[OpenWeatherMap](https://home.openweathermap.org/users/sign_up)创建一个免费账户。
2. 从您的[API密钥仪表盘](https://home.openweathermap.org/api_keys)生成API密钥。
> 新密钥可能需要几分钟到几个小时才能激活。
3. 复制环境模板并添加您的密钥:
```bash
cp .env.example .env
```
4. 打开`.env`并设置:
```dotenv
OPENWEATHER_API_KEY=您的实际API密钥
```
`.env`中的所有其他变量都有合理的默认值(参见`.env.example`中的完整记录列表),通常不需要更改。
---
## 运行MCP服务器
MCP服务器通过**stdio**通信,因此直接在终端中运行`server.py`将出现“挂起”的情况 - 这是预期的,它正在等待MCP客户端连接并通过stdin/stdout发出JSON-RPC请求。这对于检查服务器是否启动时没有错误仍然很有用:
```bash
python server.py
```
您应该在**stderr**(绝不会是stdout,它保留用于MCP协议)上看到Loguru启动日志,例如:
```
2026-07-15 12:00:00.000 | INFO | server:_run:70 - Starting 'weather-mcp-server' (API key configured: True)
```
按`Ctrl+C`停止它。
要实际与它交互,请使用MCP客户端 - 参见下一节 - 或通过**“运行天气MCP服务器”**配置已经在`.vscode/launch.json`中定义的配置启动它(在VS Code中按`F5`)。
## 使用MCP客户端连接
### Claude Desktop
将此服务器添加到Claude Desktop的MCP配置文件(`claude_desktop_config.json`;在macOS上为`~/Library/Application Support/Claude/claude_desktop_config.json`,在Windows上为`%APPDATA%\Claude\claude_desktop_config.json`):
```json
{
"mcpServers": {
"weather": {
"command": "/absolute/path/to/weather-mcp-server/.venv/bin/python",
"args": ["/absolute/path/to/weather-mcp-server/server.py"],
"env": {
"OPENWEATHER_API_KEY": "您的实际API密钥"
}
}
}
}
```
> 在Windows上,请使用`.venv\Scripts\python.exe`的路径。重启Claude Desktop后编辑配置。您应该在对话窗口的🔨(工具)菜单中看到此服务器的工具。
### MCP Inspector
[MCP Inspector](https://github.com/modelcontextprotocol/inspector)是MCP服务器的标准交互式调试工具。安装Node.js:
```bash
npx @modelcontextprotocol/inspector python server.py
```
这会打开一个浏览器UI,您可以在其中:
- 浏览和调用所有5个工具,并使用实时JSON模式驱动的表单。
- 读取所有3个资源。
- 渲染所有3个提示并带有示例参数。
- 检视原始JSON-RPC流量进行调试。
---
## 测试
完整的测试套件**离线运行** - 所有到OpenWeatherMap的HTTP调用都由[`respx`](https://lundberg.github.io/respx/)拦截,因此运行测试时不需要API密钥或网络访问。
运行所有测试:
```bash
pytest
```
运行特定文件,并带有详细输出:
```bash
pytest tests/test_weather_service.py -v
```
运行带有覆盖率报告的测试(需要`pip install pytest-cov`):
```bash
pytest --cov=. --cov-report=term-missing
```
测试套件布局:
| 文件 | 涵盖 |
|--------------------------------------------|------------------------------------------------------------------|
| `tests/test_schemas.py` | Pydantic模型验证规则(无I/O)。 |
| `tests/test_weather_service.py` | 服务层:成功路径+每个错误路径,HTTP模拟。 |
| `tests/test_tools.py` | 端到端MCP工具行为通过FastMCP的内存`Client`。 |
| `tests/test_resources_and_prompts.py` | 资源/提示注册和内容正确性。 |
您也可以直接从VS Code的**测试**侧边栏(测试图标)运行测试,得益于`.vscode/settings.json`中的pytest配置。
---
## 故障排除
**`ModuleNotFoundError: No module named 'fastmcp'`(或类似)**
您的虚拟环境未激活,或者依赖项未安装。运行`source .venv/bin/activate`(或Windows等效命令)并再次运行`pip install -r requirements.txt`。
**工具返回`{"error": true, "error_type": "missing_api_key", ...}`**
`.env`文件中未设置`OPENWEATHER_API_KEY`(或仍为占位符值)。双检查`.env`是否存在(从`.env.example`复制)并包含真实密钥。
**工具返回`{"error": true, "error_type": "upstream_api_error", ...}`,带有HTTP 401**
您的API密钥无效,或者尚未激活 - 新的OpenWeatherMap密钥可能需要多达几个小时才能激活。
**`get_weather_alerts`始终返回一个空列表,并附有关于“One Call API”的说明**
这是OpenWeatherMap免费层面上许多帐户的预期行为 - 警报数据来自“One Call API 3.0”端点,可能需要单独的(仍然免费,但需要明确订阅)计划。服务器优雅地降级而不是失败;参见[`docs/architecture.md`](docs/architecture.md#graceful-degradation-weather-alerts)。
**服务器进程在`python server.py`运行时似乎“挂起”**
这是预期的 - MCP服务器通过stdio通信并等待客户端连接并发出JSON-RPC请求。使用MCP Inspector或真实客户端与之交互(参见[连接到MCP客户端](#连接到mcp客户端))。
**Claude Desktop不显示天气工具**
双检查`claude_desktop_config.json`中的绝对路径(Python解释器路径和`server.py`路径),JSON是否有效,并完全重启Claude Desktop(不仅仅关闭窗口)后编辑配置。
**`pytest`失败并出现连接错误**
所有测试都应该通过`respx`模拟离线运行。如果您看到实际的网络错误,请确保运行测试原样(不要删除`@respx.mock`装饰器)并且`respx`已安装(`pip install -r requirements.txt`)。
---
## 未来改进
- **缓存层** - 为重复查询添加短TTL内存(或Redis)缓存以减少冗余API调用。
- **附加提供商** - 添加替代天气数据提供商(例如Open-Meteo,它不需要API密钥)作为弹性备用。
- **历史天气工具** - 暴露历史天气数据进行趋势分析,如果支持底层API计划。
- **基于地理位置的查询** - 除了城市名称外,还接受经纬度,用于当前不支持的工具。
- **速率限制感知回退** - 跟踪OpenWeatherMap的速率限制头并主动减速而不是仅反应性重试。
- **流/订阅资源** - 探索MCP资源订阅以将严重天气警报推送给客户端近实时而不是要求轮询资源)
---
## 许可证
在[MIT许可证](LICENSE)下发布。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器