关于 open-meteo-mcp-server
open-meteo-mcp-server 是用于获取全球天气与环境数据的 MCP 服务,面向需要预报、历史记录和地点查询的客户端,也支持对暂存结果运行只读 SQL。
主要功能
- 01地名地理编码
- 02天气预报与历史气候
- 03海洋和空气质量数据
- 04海拔、集合预报、洪水与气候数据
- 05对暂存结果运行只读 SQL
适用场景
- 01按地点名称获取天气预报
- 02查看 1940 年以来的历史天气
- 03检查海洋状况或空气质量
- 04用 SQL 查询暂存天气结果
MCP 相关
向 MCP 客户端提供 12 种天气、地理编码、海拔和数据帧工具。支持 STDIO 与 Streamable HTTP,并提供公开托管服务。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://open-meteo.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-open-meteo https://open-meteo.caseyjhand.com/mcp{"mcpServers":{"cyanheads-open-meteo":{"type":"http","url":"https://open-meteo.caseyjhand.com/mcp"}}}在 Cursor 中打开{"servers":{"cyanheads-open-meteo":{"type":"http","url":"https://open-meteo.caseyjhand.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"cyanheads-open-meteo":{"type":"http","url":"https://open-meteo.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-open-meteo":{"serverUrl":"https://open-meteo.caseyjhand.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
11| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 要搜索的地点名称——不带限定词的城市、区域或地标("Seattle"、"Mount Rainier")。不要加入区域或国家/地区限定词("Baoding",而非 "Baoding Hebei");请使用 country 输入消除歧义。对于一个或两个字符的本地文字名称("서울"、"大阪"),请使用完整行政区名称("서울특별시"、"大阪市")或罗马化名称("Seoul"、"Osaka")——参见 language 字段。天气工具需要坐标——请使用此结果中的 lat/lon。 |
| count | integer | 否 | 要返回的最大结果数(1–10)。默认值为 5。对于 "Springfield" 或 "Portland" 等常见名称,可返回更多结果以消除歧义。 |
| country | string | 否 | 用于区分同名地点的 ISO 3166-1 alpha-2 国家/地区代码(例如 "US"、"FR")。全球搜索时省略。 |
| language | string | 否 | 用于匹配和返回地点名称的语言(ISO 639-1,例如 "en"、"de"、"zh")。API 会根据此语言的本地化索引匹配 name,因此请将其设置为与 name 的文字系统一致的语言——例如,"上海"使用语言 "zh","Москва"使用 "ru"。这可解析三个或更多字符的原生文字名称,并通过规范化前缀进行匹配;一个或两个字符的名称必须与索引条目完全一致,因此仅设置语言无法找到 "서울" 或 "大阪"——请改用完整行政区名称("서울특별시"、"大阪市")或罗马化名称("Seoul"、"Osaka")重试。默认值为 "en";如果以可识别的非拉丁文字(中日韩文字、谚文、西里尔文、阿拉伯文、希腊文、希伯来文、泰文、天城文)输入的查询在 "en" 下未找到结果,则会根据其文字系统推断语言并重试一次;如果重试返回了结果,响应中的 effective_language 会标明该语言。 |
详细介绍
@cyanheads/open-meteo-mcp-server
通过 MCP 对地点进行地理编码,获取全球天气预报、历史气候、海洋状况、空气质量和地形海拔。支持 STDIO 或 Streamable HTTP。
概览
来自 Open-Meteo 的全球天气信息:天气预报、可追溯至 1940 年的历史数据、海洋状况、空气质量、概率集合预报、河流流量和气候预测。按名称查询任何地点,获取逐小时和逐日变量,并对大型结果运行 SQL。无需 API 密钥。
工具
| 工具 | 描述 |
|---|---|
openmeteo_search_locations | 将地点名称解析为按排名排列的坐标,并提供国家、地区、时区和人口信息 |
openmeteo_get_forecast | 提供当前状况和最长 16 天的逐小时/逐日预报,以及最长 92 天的历史数据;可查看最佳匹配模型或并排比较所选模型 |
openmeteo_get_historical | 提供再分析存档中的逐小时/逐日历史数据,范围从 1940 年至今 |
openmeteo_get_marine | 提供波浪、涌浪和海表状况:当前数据、最长 8 天的预报或存档日期范围;支持公制或英制单位 |
openmeteo_get_air_quality | 提供 CAMS 模拟的污染物、花粉和 AQI:当前数据、最长 7 天的预报或存档日期范围 |
openmeteo_get_elevation | 提供 Copernicus DEM 地形海拔数据:最多 1,000 对坐标;每次调用采样前 100 对,并报告其余坐标以供重新提交 |
openmeteo_get_ensemble | 提供逐成员集合预报(最多 64 个成员,最长 35 天),用于分析超标情况和不确定性 |
openmeteo_get_flood | 提供 GloFAS 河流流量:约 6 个月的预报,或从 1984 年开始的日期范围;可使用无缝模型或所选 v4 模型 |
openmeteo_get_climate | 提供经过偏差校正的逐日 CMIP6 预测,覆盖 1950–2050 年,最多涉及 7 个模型 |
openmeteo_dataframe_describe | 列出 DataCanvas 上暂存的表和列 |
openmeteo_dataframe_query | 对暂存表执行只读 SQL SELECT 查询 |
openmeteo_dataframe_drop | 从 DataCanvas 中移除一个暂存表或视图(需主动启用) |
功能参考
openmeteo_search_locations 工具
- 输入不带限定信息的地点
name(“Paris”,而非 “Paris, France”),可选country(ISO 3166-1 alpha-2)和language(默认值为en);count范围为 1–10,默认值为 5 - 每个结果均包含坐标、IANA
timezone、country/country_code、admin1/admin2、population和feature_code;无匹配项时返回no_results错误 - 如果排名最高的匹配项人口为 null 或少于 100,000,系统会发出
notice提示;这通常表示匹配到的是历史外名(“Bangalore”“Calcutta”) - 在
en下未匹配到的原生文字查询,会根据文字所使用的字母系统所对应的语言重试一次;重试成功时,effective_language会标明该语言(上海→zh),并返回本地化结果
openmeteo_get_forecast 工具
- 必须至少提供
current_variables、hourly_variables或daily_variables之一(各最多 50 项);forecast_days为 1–16(默认值为 7),past_days为 0–92(默认值为 0) - 按时间戳返回
hourly/daily记录,并附带hourly_units/daily_units;current_variables会添加一个基于 15 分钟数据的current对象(interval为 900),以及current_units - 省略
models时会读取 Open-Meteo 的best_match;models用于比较确定性模型(例如ncep_gfs_seamless、ecmwf_ifs025、dwd_icon_seamless;仍可解析gfs_seamless等旧名称)。使用 2 个或更多模型时,每个逐小时和逐日数据列都会附加模型名称后缀,并回显models。current_variables最多接受一个模型(current_multi_model) - 如果某个区域模型在指定地点没有数据,则会从多模型响应中剔除:
notice会标明该模型;如果只剩一个模型且数据列没有后缀,则会说明无法确定数据对应的模型;如果所有请求的模型都没有数据,调用将返回coverage_gap错误 - 对于最近约 5 天的数据,优先使用
past_days,而非openmeteo_get_historical,因为存档中的 ERA5 组件更新存在延迟
openmeteo_get_historical 工具
- 必须提供
start_date和end_date(YYYY-MM-DD,日期不早于 1940-01-01),并且至少提供一个hourly_variables/daily_variables,名称与预报工具中的一致 - 不提供
models时会读取 Best Match(IFS HRES + ERA5 + ERA5-Land,数据来源因日期而异);最多可指定 8 个models来固定数据来源。ERA5 系列数据约延迟 5 天,ecmwf_ifs没有延迟,cerra仅覆盖欧洲 - 输出会回显
models和返回的date_range;使用 2 个或更多模型时,每列都会附加模型名称后缀。如果某模型在该地点没有数据(例如欧洲以外的cerra),则会从多模型响应中移除;notice会指出该模型,或者在只剩一个模型且列名没有后缀(era5,cerra)时说明无法确定这些值对应哪个模型
openmeteo_get_marine 工具
- 每次调用只能指定一个时间窗口:
forecast_days为 1–8(上游默认值为 7),并搭配past_days0–92;或者指定回溯至至少 2022 年的start_date/end_date存档范围。混用会导致forecast_window_conflict错误;只提供一个日期会导致date_range_incomplete错误 - 至少提供一个
current_variables、hourly_variables或daily_variables(波高、周期和方向、涌浪、海表温度);受遮蔽水域返回接近零的波浪数据,陆地点返回 null(notice会指出该情况),而开阔海域以外的ocean_current_velocity为 null current_variables使用小时级名称,并添加一个来自 15 分钟数据的current对象(interval为 900)以及current_units,可与任一时间窗口搭配;在此处使用日级名称会导致variable_wrong_cadence错误length_unit(metric/imperial)设置所有高度的单位,包括sea_level_height_msl,单位为 m 或 ft;wind_speed_unit(kmh、mph、ms、kn)设置ocean_current_velocity的单位;temperature_unit(celsius/fahrenheit)设置sea_surface_temperature的单位。Open-Meteo 会转换数值,并在*_units映射中标注单位(mph显示为mp/h)
openmeteo_get_air_quality 工具
- 每次调用只能指定一个时间窗口:
forecast_days为 1–7(上游默认值为 5),并搭配past_days0–92;或者指定从 2022 年 8 月开始的start_date/end_date存档范围(us_aqi的起始日期晚一天)。与海洋工具相同,超出范围会导致forecast_window_conflict和date_range_incomplete错误 - 至少提供一个
current_variables(返回interval为 3600 的current对象)或hourly_variables:PM2.5、PM10、NO2、SO2、O3、CO、粉尘、花粉、欧洲和美国 AQI。花粉仅针对欧洲且仅在花粉季建模;其他地区会返回 null,notice会指出该情况 data_source: "CAMS"表示所有响应均为网格建模数据,而非站点测量数据
openmeteo_get_elevation 工具
- 提供并行的
latitudes[]/longitudes[]数组,最多包含 1,000 对坐标;数组长度不一致时会因coordinate_count_mismatch失败,比较的是完整数组 - 在一次上游请求中处理前 100 对坐标(Elevation API 的单次请求上限);
unprocessed_count表示剩余数量,next_offset表示继续处理的位置——重复提交latitudes.slice(next_offset)和longitudes.slice(next_offset),直到next_offset为null。调用数量不超过 100 时会返回0/null。每对采样坐标都会计入 Open-Meteo 的每 IP 限额(每分钟 600 次),因此在一分钟内提交第七批 100 对坐标会返回rate_limited elevations[]按输入顺序排列,每项为来自 Copernicus DEM(约 90 m)的{ latitude, longitude, elevation_m };DEM 没有值时(纬度为 90),elevation_m为null,但调用的其他部分不会失败
openmeteo_get_ensemble 工具
hourly_variables/daily_variables至少提供一个;forecast_days为 1–35(默认值为 7),past_days为 0–92。大多数模型的预报时效不超过 16 天(ncep_gefs05可运行到约第 34 天);超过时效后,列值为 null,notice会说明数据截止位置models接受一个集合名称(例如ecmwf_ifs025_ensemble,包含 51 个成员;gem_global_ensemble,包含 21 个);省略或留空时会选择ecmwf_ifs025_ensemble,并在model中回显- 每个变量都会返回各成员对应的列(
temperature_2m_member01,…),最多包含 64 个成员;member_count不计控制运行。若在区域模型的覆盖范围之外查询,该查询会作为不可重试的输入错误失败;请改用全球模型
openmeteo_get_flood 工具
- 必须提供
daily_variables(最多 20 个),单位均为 m³/s:river_discharge,以及统计值river_discharge_mean/_median/_min/_max/_p25/_p75。在预报运行日,这些统计值包含集合离散度;在再分析日,则重复river_discharge的值 - 每次调用只能使用一种模式:
forecast_days为 1–210(当前 GloFAS 运行可达约 6 个月;更晚日期的值为 null),或者提供从 1984-01-01 起的start_date/end_date范围。混用会以forecast_days_conflict失败;只提供一个日期会以date_range_incomplete失败 - 省略
models时会读取seamless_v4:2023-08-05 之前使用consolidated_v4再分析,此后使用forecast_v4运行。models: ["consolidated_v4"]会读取截至 2025-05-31 的再分析(之后以及forecast_days上的值为 null);forecast_v4从 2023-06-01 开始。输出会回显models;使用 2 个或更多模型时,每列都会附加模型名称后缀,notice会标明值为 null 的时间段 - 流量数据来自 5 km 范围内建模河流中最大的河流,并不总是最近的河流;若数值看起来不对,可将坐标调整约 0.1°。超出 GloFAS 覆盖范围时,值为 null
openmeteo_get_climate 工具
start_date/end_date必须在 1950-01-01 至 2050-12-31 范围内,且必须提供daily_variables(API 仅支持每日数据);最多可指定 7 个 CMIP6models,例如CMCC_CM2_VHR4、MRI_AGCM3_2_S- 使用 2 个或更多模型时,每个变量名称都会附加模型名称后缀;仅使用一个模型或省略模型时,返回不带后缀的名称。模型不包含的变量会返回 null
openmeteo_dataframe_describe 工具
- 接受天气工具溢出时返回的
canvas_id;会列出每个表的name、kind、row_count和各列信息(名称、类型、是否可为 null),以及画布的expires_at - 画布关闭时会以
canvas_not_enabled失败;ID 未知或超过 24 小时的滑动 TTL 时会以canvas_not_found失败
openmeteo_dataframe_query 工具
- 提供
canvas_id,以及针对暂存table_name的只读SELECT查询;rows最多包含 100 行;如果宽行会超过 80,000 个字符的内联上限,则返回行数会更少(不会截断值)。row_count是精确总数;使用ORDER BY,并通过OFFSET <rows.length>翻页 - 如果计数失败或耗时超过 5 秒,仍会返回行;
row_count是下限,count_error会说明原因(例如count_timeout) - 可能以
canvas_not_enabled、canvas_not_found、missing_table、system_catalog_access(禁止访问系统目录)或row_too_large失败(仅第一行就超过上限:请减少查询列,或使用left()、substr()或list_slice()缩短值)
openmeteo_dataframe_drop 工具
- 默认关闭:在设置
OPENMETEO_DATAFRAME_DROP_ENABLED=true之前会列为禁用 - 提供
canvas_id,以及从openmeteo_dataframe_describe获取的准确table_name;删除该表或视图,并返回dropped和remaining_tables。名称不在暂存区中时会返回dropped: false,因此重复删除也安全 - 可能以
canvas_not_enabled、canvas_not_found或invalid_table_name失败(不是普通 SQL 标识符,或是保留关键字)
功能
基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none / jwt / oauth)、可切换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及支持可选 OpenTelemetry 跟踪的结构化日志记录。
Open-Meteo 专属功能:
- 非商业用途无需 API 密钥;商业用途需要 Open-Meteo 的付费 API 套餐
- 将按列排列的 API 响应重整为按时间戳排列的记录,并附带
*_units映射;预报数据和历史数据使用相同的变量名称 - 七个天气工具支持 DataCanvas 溢出处理:当
CANVAS_PROVIDER_TYPE=duckdb(默认值)时,超出预算的结果会暂存为 DuckDB 表(响应包含canvas_id、table_name、truncated: true);当值为none时,返回有界预览并设置truncated: true - 预报、历史、集合预报、气候和洪水工具中的
models不是允许列表,因此 Open-Meteo 日后新增模型时,无需更新服务即可使用
适合 Agent 使用的输出:
- 以位置为先的工作流:
openmeteo_search_locations会在返回坐标的同时提供 IANAtimezone,可直接用作任意天气工具的timezone输入(默认值为auto) - 采用类型化拒绝:
variable_wrong_cadence(指出正确的字段)、request_too_large(指出需要缩小范围的输入)、coverage_gap(坐标位于数据集网格或模型范围之外)和rate_limited;只有Too many concurrent requests会首先触发重试。若中断持续超过三次尝试,则会以upstream_unavailable失败;若最后一次尝试超时,则以upstream_timeout失败 - 请求 URL 不会出现在错误数据或客户端可见的日志中
- 每个响应只包含一条
notice,说明数据本身无法显示的信息:未提供服务的变量名称、超出数据集覆盖范围的空值,以及溢出行的存放位置
开始使用
公共托管实例
可使用公共实例 https://open-meteo.caseyjhand.com/mcp,无需安装。通过 Streamable HTTP 将任意 MCP 客户端指向该实例:
{
"mcpServers": {
"open-meteo-mcp-server": {
"type": "streamable-http",
"url": "https://open-meteo.caseyjhand.com/mcp"
}
}
}
自托管 / 本地运行
将以下内容添加到 MCP 客户端配置文件中。
{
"mcpServers": {
"open-meteo-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/open-meteo-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
或使用 npx(无需 Bun):
{
"mcpServers": {
"open-meteo-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/open-meteo-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
或使用 Docker:
{
"mcpServers": {
"open-meteo-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/open-meteo-mcp-server:latest"]
}
}
}
对于 Streamable HTTP,请设置传输方式并启动服务:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
前置条件
- Bun v1.4.0 或更高版本(或 Node.js v24+)。
- 无需 API 密钥。非商业用途免费且无需密钥。
- 商业用途需要 Open-Meteo 的付费 API 套餐。
安装
- 克隆仓库:
git clone https://github.com/cyanheads/open-meteo-mcp-server.git
- 进入目录:
cd open-meteo-mcp-server
- 安装依赖:
bun install
配置
所有变量均为可选项。
| 变量 | 描述 | 默认值 |
|---|---|---|
OPEN_METEO_API_BASE_URL | 预报和海拔 API 基础 URL。 | https://api.open-meteo.com |
OPEN_METEO_ARCHIVE_BASE_URL | 历史档案 API 基础 URL。 | https://archive-api.open-meteo.com |
OPEN_METEO_MARINE_BASE_URL | 海洋 API 基础 URL。 | https://marine-api.open-meteo.com |
OPEN_METEO_AIR_QUALITY_BASE_URL | CAMS 空气质量 API 基础 URL。 | https://air-quality-api.open-meteo.com |
OPEN_METEO_GEOCODING_BASE_URL | 地理编码 API 基础 URL。 | https://geocoding-api.open-meteo.com |
OPEN_METEO_ENSEMBLE_BASE_URL | 集合预报 API 基础 URL。 | https://ensemble-api.open-meteo.com |
OPEN_METEO_FLOOD_BASE_URL | GloFAS 洪水 API 基础 URL。 | https://flood-api.open-meteo.com |
OPEN_METEO_CLIMATE_BASE_URL | CMIP6 气候 API 基础 URL。 | https://climate-api.open-meteo.com |
CANVAS_PROVIDER_TYPE | duckdb 会将超出预算的天气结果暂存到 DataCanvas,并启用数据帧工具;none 则返回有限预览。 | duckdb |
OPENMETEO_DATAFRAME_DROP_ENABLED | 设为 true 后,openmeteo_dataframe_drop 可供调用;否则会列为已禁用。 | false |
MCP_TRANSPORT_TYPE | 传输方式:stdio 或 http。 | stdio |
MCP_HTTP_PORT | HTTP 服务端口。 | 3010 |
MCP_SESSION_MODE | HTTP 会话模式:stateless、stateful 或 auto。 | stateless |
MCP_AUTH_MODE | 身份验证方式:none、jwt 或 oauth。 | none |
MCP_LOG_LEVEL | 日志级别(debug、info、notice、warning、error)。 | info |
LOGS_DIR | 日志文件目录(仅 Node.js)。 | <project-root>/logs |
STORAGE_PROVIDER_TYPE | 存储后端:in-memory、filesystem、supabase、cloudflare-kv/r2/d1。 | in-memory |
OTEL_ENABLED | 启用 OpenTelemetry。 | false |
完整的可选覆盖项列表请参见 .env.example。
运行服务
本地开发
-
构建并运行生产版本:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdio -
运行检查和测试:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite
Docker
docker build -t open-meteo-mcp-server .
docker run --rm -p 3010:3010 open-meteo-mcp-server
Dockerfile 默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/open-meteo-mcp-server。默认会安装 OpenTelemetry 对等依赖项;构建时使用 --build-arg OTEL_ENABLED=false 可省略这些依赖项。
项目结构
| 目录 | 用途 |
|---|---|
src/index.ts | createApp() 入口点——注册工具、初始化 Open-Meteo 服务和 DataCanvas。 |
src/config | 使用 Zod 解析和验证服务专用环境变量。 |
src/mcp-server/tools/definitions | 工具定义(*.tool.ts),每个工具对应一个文件。 |
src/mcp-server/tools | 共享工具辅助模块——模型目录、时间频率验证、列式重塑、溢出处理、响应提示。 |
src/services/open-meteo | Open-Meteo API 的 HTTP 客户端——重试、错误分类、覆盖范围缺口拒绝。 |
src/services/canvas-accessor.ts | 溢出能力工具共享的 DataCanvas 访问器。 |
tests/ | 单元、集成、模糊和冒烟测试。 |
开发指南
开发指南和架构规则请参见 CLAUDE.md。简要说明如下:
- 处理程序抛出异常,框架负责捕获——工具逻辑中不要使用
try/catch - 使用
ctx.log记录请求范围内的日志,使用ctx.state存储租户范围内的数据 - 在
src/index.ts的tools[]数组中注册新工具 - 封装外部 API 调用:验证原始数据 → 规范化为领域类型 → 返回输出模式;绝不伪造缺失字段
署名
天气数据由 Open-Meteo.com 提供,采用 CC BY 4.0 许可。
贡献
欢迎提交问题。提交前请运行检查和测试:
bun run devcheck
bun run test
许可证
Apache-2.0——详情请参见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。