Skip to main content
Glama

weather-mcp

weather-mcp 是一个独立的 Capability Service(能力服务),对外提供“天气查询”这一 MCP 能力。

为什么要拆成 weather-mcp

在已有后台系统中:

  • admin:唯一的用户与认证来源(登录、签发 Token、/api/v1/auth/me

  • weather-mcp:只负责能力提供,不做用户系统

拆分的目标:

  • 清晰边界:避免多套用户体系

  • 能力可复用:MCP 层独立于 HTTP,可被编排/复用

  • 可演进:未来接入更多 MCP(空气质量/预报/第三方数据源)

与 admin 的关系(文字关系图)

  • Client -> weather-mcp:携带 Authorization: Bearer <JWT>

  • weather-mcp:验证 Token 是否可信(第一版为本地 HS256 验签)

  • admin:身份真实性与用户语义的权威来源

鉴权设计

第一版采用 方案 A:本地 HS256 验签(与 admin 使用同一套 SECRET_KEY)。

  • Header 读取:Authorization: Bearer <token>

  • 解析规则:

    • 算法:HS256

    • subuser_id

    • 不依赖 roles/scopes

工程化要求:

  • 鉴权逻辑在 app/core/auth/app/auth_client/

  • API 层通过 Depends(get_auth_context) 获取 AuthContext

  • handler 不直接处理 token、不写鉴权逻辑

可替换性:

  • 通过 WEATHER_MCP_AUTH_MODE 切换

    • local_jwt:本地验签

    • admin_introspect:调用 admin 的 GET /api/v1/auth/me(已预留实现)

MCP 设计理念

MCP 是独立于 HTTP 的“能力协议层”:

  • 输入输出是结构化 DTO(Pydantic Model)

  • 不依赖 FastAPI Request

  • 易于单测与复用

目录:

  • app/mcp/:MCP 抽象与实现(例如 WeatherMCP

  • app/schemas/:MCP 输入输出结构(与 HTTP 无关)

  • app/api/:HTTP API 层(校验/鉴权/调用 MCP)

运行

依赖

使用 uv 管理依赖:

  • uv sync

环境变量

  • WEATHER_MCP_SECRET_KEY:与 admin 一致的 HS256 对称密钥

  • WEATHER_MCP_AUTH_MODE:默认 local_jwt

和风天气(QWeather)Web API:

  • WEATHER_MCP_QWEATHER_API_HOST:你的 QWeather API Host(在 QWeather Console -> Setting 查看)

  • WEATHER_MCP_QWEATHER_API_KEY:你的 QWeather API Key(务必只放在环境变量/密钥管理中)

  • WEATHER_MCP_QWEATHER_TIMEOUT_SECONDS:HTTP 超时(秒)

启动

  • uv run uvicorn app.main:app --reload --port 9001

API

  • GET /health

MCP 能力:实时天气(Current Weather)

本服务通过 QWeather GET /v7/weather/now 提供实时天气能力,并将返回结构映射成统一的 MCP 输出。

1) MCP 直连路由(兼容/调试)

  • GET /mcp/weather?location=...&lang=...&unit=m|i

说明:

  • location 支持多种输入形式(统一为一个字符串参数):

    • 城市名称(例如 北京 / Beijing

    • 经纬度(格式 longitude,latitude,例如 116.41,39.92

    • Location ID(和风天气城市码,例如 101010100

  • lang:天气描述语言(默认 zh,例如返回 多云

  • unit:单位(m=metric,i=imperial;默认 m

城市名解析策略:

  • location 不是纯数字(LocationID)且不是 lon,lat 时,会先调用 QWeather GeoAPI GET /geo/v2/city/lookup 做解析,取 Top-1 结果。

  • 解析时会使用英文 geo_lang=en 获取标准化地点名称(例如输出 Beijing),而天气接口仍使用 lang=zh 以保证天气状态中文显示。

2) Tool 路由(推荐对外使用)

  • POST /tools/weather.current

请求示例:

POST /tools/weather.current Authorization: Bearer <jwt> Content-Type: application/json { "location": "北京" }

返回示例:

{ "location": "Beijing", "observed_at": "2025-12-13T15:00:00+08:00", "temperature": 12, "condition": "多云", "humidity": 55, "wind_speed": 5.4, "wind_dir": "西北风", "raw": { "code": "200", "now": { "...": "..." } } }

字段映射说明(QWeather -> MCP):

  • now.obsTime -> observed_at

  • now.temp -> temperature

  • now.text -> condition

  • now.humidity -> humidity

  • now.windSpeed -> wind_speed

  • now.windDir -> wind_dir

  • 完整原始响应 -> raw

错误处理(HTTP 层):

  • 401:缺少/无效 JWT(由 get_auth_context 处理)

  • 500:服务端缺少 QWeather 配置(host/key)

  • 400:无效地点(上游返回 400/404)

  • 429:上游限流

  • 502:上游网络或权限问题(QWeather 返回 401/403 等)

MCP 能力:每日天气预报(Daily Forecast)

本服务通过 QWeather GET /v7/weather/{days} 提供每日天气预报能力,并将返回结构映射成统一的 MCP 输出。

Tool 路由

  • POST /tools/weather.forecast.daily

请求示例:

POST /tools/weather.forecast.daily Authorization: Bearer <jwt> Content-Type: application/json { "location": "北京", "days": 3, "lang": "zh", "unit": "m" }

参数说明:

  • location:城市名称 / lon,lat / LocationID

  • days:仅支持 3|7|10|15(对应上游 3d/7d/10d/15d

  • lang:天气描述语言(默认 zh

  • unit:单位(m=metric,i=imperial;默认 m

返回示例:

{ "location": "Beijing", "forecasts": [ { "date": "2025-12-14", "temp_max": 8, "temp_min": -2, "condition_day": "多云", "condition_night": "晴", "humidity": 35, "wind_speed": 10, "wind_dir": "西北风" } ], "raw": { "code": "200", "daily": [{ "...": "..." }] } }

字段映射说明(QWeather -> MCP):

  • daily.fxDate -> forecasts[].date

  • daily.tempMax -> forecasts[].temp_max

  • daily.tempMin -> forecasts[].temp_min

  • daily.textDay -> forecasts[].condition_day

  • daily.textNight -> forecasts[].condition_night

  • daily.humidity -> forecasts[].humidity

  • daily.windSpeedDay -> forecasts[].wind_speed

  • daily.windDirDay -> forecasts[].wind_dir

  • 完整原始响应 -> raw

MCP 能力:每小时天气预报(Hourly Forecast)

本服务通过 QWeather GET /v7/weather/{hours} 提供每小时天气预报能力,并将返回结构映射成统一的 MCP 输出。

Tool 路由

  • POST /tools/weather.forecast.hourly

请求示例:

POST /tools/weather.forecast.hourly Authorization: Bearer <jwt> Content-Type: application/json { "location": "北京", "hours": 24, "lang": "zh", "unit": "m" }

参数说明:

  • location:城市名称 / lon,lat / LocationID

  • hours:仅支持 24|72|168(对应上游 24h/72h/168h

  • lang:天气描述语言(默认 zh

  • unit:单位(m=metric,i=imperial;默认 m

返回示例:

{ "location": "Beijing", "hourly": [ { "time": "2025-12-13T18:00:00+08:00", "temperature": 2, "condition": "多云", "wind_speed": 12, "wind_dir": "北风", "humidity": 40 } ], "raw": { "code": "200", "hourly": [{ "...": "..." }] } }

字段映射说明(QWeather -> MCP):

  • hourly.fxTime -> hourly[].time

  • hourly.temp -> hourly[].temperature

  • hourly.text -> hourly[].condition

  • hourly.windSpeed -> hourly[].wind_speed

  • hourly.windDir -> hourly[].wind_dir

  • hourly.humidity -> hourly[].humidity

  • 完整原始响应 -> raw

MCP 能力:空气质量(Current Air Quality)

本服务通过 QWeather Air Quality v1 GET /airquality/v1/current/{latitude}/{longitude} 提供空气质量能力。

说明:

  • 该能力需要经纬度。若传入的是城市名或 LocationID,会先调用 GeoAPI 获取 lat/lon

Tool 路由

  • POST /tools/air_quality.current

请求示例:

POST /tools/air_quality.current Authorization: Bearer <jwt> Content-Type: application/json { "location": "北京" }

返回示例:

{ "location": "Beijing", "aqi": 46, "category": "Good", "primary_pollutant": "PM 2.5", "pm2p5": 11.0, "pm10": 12.0, "o3": 0.02, "no2": 6.77, "so2": 1.0, "co": 0.25, "raw": { "indexes": [{ "...": "..." }], "pollutants": [{ "...": "..." }] } }

字段映射说明(QWeather -> MCP):

  • indexes[0].aqi -> aqi(优先选择 code=us-epa

  • indexes[0].category -> category

  • indexes[0].primaryPollutant.name(或 .code)-> primary_pollutant

  • pollutants[].concentration.value(按 code 匹配)-> pm2p5/pm10/o3/no2/so2/co

  • 完整原始响应 -> raw

MCP 能力:极端天气预警(Weather Alerts)

本服务通过 QWeather GET /v7/warning/now 提供天气预警能力。

说明:

  • QWeather 文档中标注该接口为“弃用”,但目前仍可按现有返回结构使用。

  • 当查询地区当前没有预警信息时,上游返回 warning=[],本服务返回 alerts=[]

Tool 路由

  • POST /tools/weather.alerts

请求示例:

POST /tools/weather.alerts Authorization: Bearer <jwt> Content-Type: application/json { "location": "北京", "lang": "zh" }

返回示例:

{ "location": "Beijing", "alerts": [ { "type": "大风", "level": "Blue", "title": "发布大风蓝色预警", "description": "预计将出现大风", "start": "2025-12-13T10:30:00+08:00", "end": "2025-12-14T10:30:00+08:00" } ], "raw": { "code": "200", "warning": [{ "...": "..." }] } }

字段映射说明(QWeather -> MCP):

  • warning.typeName(或 warning.type)-> alerts[].type

  • warning.severityColor(或 warning.severity)-> alerts[].level

  • warning.title -> alerts[].title

  • warning.text -> alerts[].description

  • warning.startTime -> alerts[].start

  • warning.endTime -> alerts[].end

  • 完整原始响应 -> raw

测试

依赖由 uv 管理,推荐直接运行:

  • uv run pytest -q

后续演进方向

  • 多 MCP:AirQualityMCPForecastMCP

  • MCP 编排:一个请求触发多个 MCP,或链式执行

  • 内部 RPC / Agent 化:HTTP 之外的复用入口

  • 可观测性:日志/trace、限流、缓存与熔断

-
security - not tested
F
license - not found
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Jayleonc/weather-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server