weather-mcp-demo
by shanzi-1
README.md
# Weather MCP Demo:基于 FastMCP 的天气查询工具
## 项目简介
本项目使用 Python + FastMCP + Open-Meteo API 实现一个本地 MCP Server,让大模型客户端可以调用天气查询工具。
项目通过 Open-Meteo 的 Geocoding API 查询城市经纬度,再通过 Forecast API 查询实时天气。整个过程不需要 API Key,适合本地开发、课程展示和实习面试讲解。
## 项目功能
- 根据城市名查询实时天气
- 根据经纬度查询实时天气
- 支持中文城市名和英文城市名
- 返回温度、体感温度、湿度、天气状态、风速、风向
- 支持本地 MCP Client 测试,无 Claude 额度也能验证
## 技术栈
- Python
- FastMCP
- MCP Python SDK
- Open-Meteo API
- requests
- stdio
## 项目结构
```text
weather-mcp-demo/
├── server.py
├── test_weather.py
├── test_mcp_client.py
├── requirements.txt
└── README.md
```
核心文件说明:
- `server.py`:MCP Server 主程序,使用 FastMCP 暴露天气查询工具
- `test_weather.py`:普通 Python 测试脚本,用来验证 Open-Meteo API 逻辑
- `test_mcp_client.py`:本地 MCP Client 测试脚本,用来模拟客户端调用 MCP 工具
- `requirements.txt`:项目依赖
- `README.md`:项目说明文档
## 运行步骤
进入项目目录:
```bash
cd weather-mcp-demo
```
安装依赖:
```bash
python -m pip install -r requirements.txt
```
先测试普通 API 逻辑:
```bash
python test_weather.py
```
再测试 MCP Client 调用工具:
```bash
python test_mcp_client.py
```
最后可以直接启动 MCP Server:
```bash
python server.py
```
## 重点解释
### test_weather.py 的作用
`test_weather.py` 用来测试普通 API 逻辑。
它不会启动 MCP Server,而是直接导入 `server.py` 中的天气查询函数,验证:
- 城市名能否正确转换为经纬度
- Open-Meteo Forecast API 是否能返回实时天气
- 天气结果是否能格式化成中文报告
这个脚本适合在开发阶段先确认核心业务逻辑是否正常。
### test_mcp_client.py 的作用
`test_mcp_client.py` 用来模拟 MCP 客户端调用工具。
它的意义是:即使没有 Claude 额度,也可以在本地验证 MCP Server 是否真的暴露了工具、工具是否能被客户端调用、返回结果是否正确。
这比只运行 `server.py` 更适合调试和面试演示。
### server.py 的 stdio 模式
`server.py` 使用 stdio 模式运行。
stdio 模式下,MCP Server 通过标准输入和标准输出与 MCP Client 通信。因此单独运行:
```bash
python server.py
```
终端没有普通输出是正常的。它不是卡死,而是在等待 MCP Client 发送协议消息。
## 面试讲解版流程
用户输入城市名 -> Geocoding API 获取经纬度 -> Forecast API 获取实时天气 -> MCP tool 封装结果 -> MCP Client/Claude 调用工具。
可以这样讲:
1. 用户输入城市名,例如“杭州”或 `Tokyo`。
2. MCP Client 或 Claude 调用 `get_weather` 工具。
3. `server.py` 先把中文城市名映射成英文城市名,例如“杭州”映射为 `Hangzhou`。
4. 程序调用 Open-Meteo Geocoding API,把城市名转换成经纬度。
5. 程序调用 Open-Meteo Forecast API,根据经纬度查询实时天气。
6. 程序把温度、体感温度、湿度、天气状态、风速、风向整理成中文报告。
7. MCP tool 把结果返回给 MCP Client 或 Claude。
这个项目展示了一个完整的 MCP 工具调用链路:用户需求、工具调用、外部 API 查询、结果封装、返回给大模型客户端。
## MCP 工具说明
### get_weather
根据城市名查询实时天气。
参数:
- `city`:城市名,例如 `杭州`、`上海`、`Tokyo`
- `country_code`:可选国家代码,例如 `CN`、`JP`
### get_weather_by_location
根据经纬度查询实时天气。
参数:
- `latitude`:纬度
- `longitude`:经度
## Claude Desktop 配置示例
如果要接入 Claude Desktop,可以在 Claude Desktop 的 MCP 配置中加入:
```json
{
"mcpServers": {
"weather-mcp-demo": {
"command": "你的conda环境python.exe绝对路径",
"args": [
"你的项目server.py绝对路径"
]
}
}
}
```
Windows 示例:
```json
{
"mcpServers": {
"weather-mcp-demo": {
"command": "C:\\Users\\你的用户名\\miniconda3\\envs\\weather-mcp-demo\\python.exe",
"args": [
"D:\\Proj\\mcp_weather\\weather-mcp-demo\\server.py"
]
}
}
}
```
注意:JSON 中的 Windows 路径反斜杠需要写成 `\\`。
## 常见问题
### 1. 为什么不用 API Key
因为项目使用的是 Open-Meteo API。
Open-Meteo 提供免费的 Geocoding API 和 Forecast API,基础天气查询不需要注册账号,也不需要 API Key。这样项目更容易本地运行,也更适合面试展示。
### 2. 为什么没有 Claude 额度也能测试
因为 MCP Server 本质上是一个本地工具服务。
除了 Claude Desktop,项目也可以使用本地 MCP Client 脚本调用工具。`test_mcp_client.py` 就是用来模拟 MCP Client 的,所以即使没有 Claude 额度,也可以验证 MCP 工具是否能正常工作。
### 3. 为什么 python server.py 看起来卡住
这是正常现象。
`server.py` 使用 stdio 模式运行,它启动后会等待 MCP Client 通过标准输入发送 MCP 协议消息。单独在终端运行时没有普通输出,看起来像卡住,其实是在等待客户端连接。
### 4. KeyboardInterrupt 是否是报错
如果你在终端运行 `python server.py` 后按下 `Ctrl + C`,可能会看到 `KeyboardInterrupt`。
这不是项目逻辑错误,而是你手动中断了正在等待客户端消息的 MCP Server。调试时可以直接关闭终端,或者按 `Ctrl + C` 停止服务。
## 面试时可以强调的点
- 项目没有使用需要 API Key 的服务,降低了运行门槛
- 支持中文和英文城市名,考虑了中文用户输入场景
- 拆分了普通 API 测试和 MCP Client 测试,方便定位问题
- 使用 FastMCP 暴露工具,代码结构简单,适合讲清楚 MCP 的工作方式
- `server.py` 不使用普通 `print` 输出,避免干扰 stdio 协议通信
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues