mcpField
S
swiss-environment-mcp

swiss-environment-mcp

本地服务
github.com科研与教育15 周前更新

关于 swiss-environment-mcp

swiss-environment-mcp 将瑞士联邦环境数据通过 MCP 提供给 AI 助手,涵盖空气、水文、自然灾害及 BAFU 数据目录等领域。无需 API 密钥,可查询实时监测数据、警报和公开数据集。

主要功能

  1. 01查询 NABEL 空气质量及限值
  2. 02查看水位、流量和水温
  3. 03查询洪水与野火警报
  4. 04获取雪况和雪崩危险等级
  5. 05检索 BAFU 环境数据集
  6. 06查询飞机噪声与限值

适用场景

  1. 01检查苏黎世 NABEL 站的当前空气质量
  2. 02查询瑞士的活动洪水警报
  3. 03查看瓦莱州的野火危险等级
  4. 04搜索 BAFU 生物多样性数据集

MCP 相关

该 MCP 服务向客户端提供瑞士环境数据工具,覆盖空气质量、水文、灾害、雪况、狩猎统计、数据目录和飞机噪声。支持 stdio 与 Streamable HTTP/SSE 传输。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"malkreide-swiss-environment": {
"command": "uvx",
"args": [
"swiss-environment-mcp"
]
}
}
}
启动命令uvx swiss-environment-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypiswiss-environment-mcp0.7.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

🇨🇭 属于 Swiss Public Data MCP Portfolio

🌿 swiss-environment-mcp

Version License: MIT Python 3.11+ MCP CI Data Source

MCP 服务将 AI 模型连接到来自 BAFU 的瑞士环境数据,包括空气质量、水文、自然灾害、野火风险和开放环境数据集。

🇩🇪 德语版本

演示:Claude 通过 swiss-environment-mcp 工具调用查询 NABEL 空气质量,并获得 WHO 2021 合规性检查结果


概述

swiss-environment-mcp 让 Claude 等 AI 助手能够直接访问瑞士联邦机构的实时环境数据,无需 API 密钥。通过单一标准化 MCP 接口,即可访问国家 NABEL 监测网络的空气质量读数、水文测量站数据、自然灾害公告以及完整的 BAFU 数据集目录。

该服务涵盖四个主题类别:空气质量(NABEL)、水文、自然灾害和 BAFU 开放数据目录。每个类别对应一组专用工具,可将机构原始数据转换为清晰的 JSON 响应。

演示查询: “Zürich-Kaserne 的 NABEL 测站当前空气质量如何?是否符合 WHO 2021 指南?” → 按受众分类的更多用例 →


功能

  • 🌬️ 空气质量监测 – 16 个 NABEL 测站,NO₂/O₃/PM10/PM2.5/SO₂/CO,瑞士 LRV 和 WHO 2021 限值检查
  • 💧 水文 – 瑞士各测站的水位、流速和温度
  • 🚨 洪水预警 – 按危险等级和州筛选的有效警报
  • 🏔️ 自然灾害公告 – SLF/BAFU 提供的 DE/FR/IT/EN 公告及地区特定预警
  • 🔥 野火风险 – 州和地区级别的火灾风险指数
  • ❄️ 积雪与雪崩(SLF) – 各 IMIS 测站的雪深和新增积雪;雪崩危险等级(EAWS)
  • 🦌 狩猎统计 – 按物种、州和年份统计的猎获与野生动物损失数据(联邦狩猎统计)
  • 📦 BAFU 开放数据目录 – 通过 CKAN 搜索和检索环境数据集
  • 🔑 无需身份验证 – 所有数据源均可公开访问
  • ☁️ 双传输方式 – 适用于 Claude Desktop 的 stdio,以及适用于云部署的 Streamable HTTP/SSE

先决条件

  • Python 3.11+
  • 无需 API 密钥 – 所有端点均可在未经身份验证的情况下公开访问

安装

# Clone the repository
git clone https://github.com/malkreide/swiss-environment-mcp.git
cd swiss-environment-mcp

# Install
pip install -e .

或使用 uvx(无需永久安装):

uvx swiss-environment-mcp

或通过 pip 安装:

pip install swiss-environment-mcp

快速开始

# Start the server (stdio mode for Claude Desktop)
swiss-environment-mcp

立即在 Claude Desktop 中试用:

“NABEL Zürich-Kaserne 测站当前空气质量如何?” “瑞士目前是否有任何有效的洪水预警?” “瓦莱州的野火风险等级是多少?”


配置

Claude Desktop

最简配置(推荐):

{
  "mcpServers": {
    "swiss-environment": {
      "command": "uvx",
      "args": ["swiss-environment-mcp"],
      "env": {}
    }
  }
}

配置文件位置:

  • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows:%APPDATA%\Claude\claude_desktop_config.json

保存后,请完全重启 Claude Desktop。

云端部署(用于浏览器访问的 SSE)

用于通过浏览器中的 claude.ai 使用(例如,在无法安装本地软件的受管工作站上):

Render.com(推荐):

  1. 将仓库推送到 GitHub,或在 GitHub 上复刻仓库
  2. 在 render.com 上:New Web Service → 连接 GitHub 仓库
  3. Render 会自动检测 render.yaml
  4. 在 claude.ai 的 Settings → MCP Servers 下,添加:https://your-app.onrender.com/sse

Docker:

docker build -t swiss-environment-mcp .
docker run -p 8000:8000 swiss-environment-mcp

💡 “开发者笔记本电脑用 stdio,浏览器用 SSE。”


可用工具

所有工具都使用稳定的 env_ 名称前缀——这是经过深思熟虑的命名空间选择,便于识别服务的工具,并降低同时挂载多个 MCP 服务时发生名称冲突的可能性。工具定义(名称、描述、输入架构)由 tool-snapshot.json 固定;任何更改都必须添加 CHANGELOG 条目(参见 CONTRIBUTING)。

工具预算(21 个工具,7 个集群)——已用尽。 每个工具都对应一个独立的用户问题,而非某个 REST 端点——这里没有 CRUD/端点镜像,每个核心查询都可以通过一次调用回答。工具数量超过了 ≤12 的经验规则,是因为该服务有意覆盖七个环境领域(空气、水、灾害、积雪、狩猎、目录、飞机噪声),每个领域都需要列表/详情工具对或特定领域的操作。我们曾考虑进一步整合,但最终否决了:*_stations/*_current 工具对(NABEL、水文、积雪)分别满足真正不同的需求(发现站点与读取已知站点数据),将其合并会让单个工具的参数负担过重。

这是上限。 随着飞机噪声集群的加入,服务的工具预算已用尽:任何新增数据源都应归入单独的 *-mcp 服务,而不是此处。下一次新增工具时,应转而评估是否要将某些列表迁移为 MCP 资源,而非工具。

🌬️ 空气质量 / NABEL(3 个工具)
工具描述数据来源
env_nabel_stations列出全部 16 个 NABEL 监测站及其位置类型和州NABEL / BAFU
env_nabel_current某个站点的当前空气质量数据(NO₂、O₃、PM10、PM2.5、SO₂、CO)NABEL / BAFU
env_air_limits_check将测量值与瑞士 LRV 限值和 WHO 2021 指南进行比较内置
💧 水文(5 个工具)
工具描述数据来源
env_hydro_stations按水体筛选水文测量站(无法按州筛选——参见说明)LINDAS SPARQL
env_hydro_current某个站点当前的水位、流量和温度LINDAS SPARQL
env_hydro_historyLINDAS 的最新数值,以及获取实时序列数据的路径 ⚠️LINDAS SPARQL
env_flood_warnings按危险等级筛选当前有效的洪水警报(覆盖全国——未应用州筛选)LINDAS SPARQL
env_bathing_water各沐浴地点的沐浴水质(E.coli、肠球菌)——多年时间序列LINDAS SPARQL(数据立方体 ubd0104)
🏔️ 自然灾害(3 个工具)
工具描述数据来源
env_hazard_overview路由器:指向专用实时灾害工具和官方门户(不进行网络调用——汇总型 naturgefahren.ch API 已停用)本地
env_hazard_regions路由器:将灾害类型(洪水/雪崩/野火/积雪)映射到相应的实时工具和门户(不进行网络调用)本地
env_wildfire_danger按州和地区划分的野火危险指数waldbrandgefahr.ch
❄️ 积雪与雪崩 / SLF(3 个工具)
工具描述数据来源
env_snow_stations列出自动 SLF/IMIS 积雪测量站(按州)measurement-api.slf.ch
env_snow_current各站点当前雪深(HS)和 24 h 新雪量(HN_1D),单位为 cmmeasurement-api.slf.ch
env_avalanche_bulletin各警报区域的雪崩危险等级(EAWS 1–5),按季节划分aws.slf.ch
🦌 狩猎与野生动物(2 个工具)
工具描述数据来源
env_hunting_species列出联邦狩猎统计中跟踪的 36 个物种(含代码)jagdstatistik.ch(内置)
env_hunting_stats按物种、州和年份(2015–2024)统计的捕杀量、野生动物损失和种群数量jagdstatistik.ch
📊 环境数据目录(2 个工具)
工具描述数据来源
env_bafu_datasets在 opendata.swiss 上搜索 BAFU 数据集(CKAN API)opendata.swiss
env_bafu_dataset_detail特定数据集的完整元数据和下载 URLopendata.swiss
✈️ 飞机噪声 / BAZL 噪声地籍(3 个工具)
工具描述数据来源
env_noise_aircraft_at查询 LV95 点的飞机噪声暴露情况——解析重叠的噪声等值线,并返回一个以最高值为上限的 dB 范围api3.geo.admin.ch(BAZL)
env_noise_aircraft_registers哪些机场已发布噪声地籍,包括有效日期、dB 范围和官方规划图(PDF)——用于追溯数据来源的工具api3.geo.admin.ch(BAZL)
env_noise_limits_check按敏感度等级 ES I–IV,将评定级与 LSV 暴露限值(规划值 / 影响限值 / 警报值)进行比较内置(SR 814.41,附录 5)

⚖️ 法律声明——每个工具的所有响应中均包含此声明。 噪声地籍仅是参考工具。建设项目的法律约束性信息由主管州级部门或 FOCA(BAZL)提供。这些工具不能替代建筑许可审查。

坐标必须使用 LV95(EPSG:2056,单位为米:E ≈ 2'480'000–2'840'000,N ≈ 1'070'000–1'300'000)。WGS84 度数(例如 8.54 / 47.37)会被拒绝,并立即报错提示如何转换——这是大模型处理瑞士地理数据时最常见的错误。请通过 swisstopo REFRAME 或 swisstopo-mcp 中的 convert_coordinates 进行转换。

等值线是线,而非区域。 噪声地籍发布的是 MultiLineString 等值线,因此 identify 会在搜索半径内执行邻近查询,而非点在多边形内测试。因此,env_noise_aircraft_at 返回的是一个范围(“该点位于 61 dB 和 62 dB 等值线之间”),并将最高值明确标为上限,绝不会返回插值得出的点值。每个响应都会报告搜索半径;扩大半径会使结果范围变宽(在 Kloten 的一个点位,100 m → 61–62 dB,而 500 m → 58–75 dB,因为 75 dB 的跑道等值线距离该点 1.5 km)。

演示核心查询

“计划中的学校选址是否位于有建筑限制的飞机噪声区域内?噪声级别是多少 dB?”

跨服务流程:通过 swiss-housing-mcp 解析地址或 EGID → 转换为 LV95 坐标 → env_noise_aircraft_at(east=…, north=…, period="day") → 将返回的 level_db 传入 env_noise_limits_check(level_db=…, sensitivity_level="II", period="day") 进行法律分类。

swiss-housing-mcp  →  address / EGID  →  LV95 E/N
                                          ↓
                          env_noise_aircraft_at   → 62 dB (upper bound, LBK Zürich, valid from 03.07.2015)
                                          ↓
                          env_noise_limits_check  → immission limit ES II (60 dB) exceeded by 2 dB
示例用例
查询工具
“苏黎世 Kaserne 当前的空气质量如何?”env_nabel_current
“45 µg/m³ 的 NO₂ 是否超过瑞士限值?”env_air_limits_check
“苏黎世利马特河当前水位是多少?”env_hydro_current
“Küsnacht 海滨浴场的水质适合游泳吗?”env_bathing_water
“瑞士有哪些正在生效的洪水警报?”env_flood_warnings
“格劳宾登州的自然灾害公告是什么?”env_hazard_overview
“瓦莱州的野火危险程度如何?”env_wildfire_danger
“opendata.swiss 上有哪些 BAFU 生物多样性数据集?”env_bafu_datasets
“计划中的学校选址是否位于飞机噪声区?噪声级是多少 dB?”env_noise_aircraft_at
“日内瓦机场的噪声地籍数据有多久了?”env_noise_aircraft_registers
“ES II 住宅区夜间 62 dB 是否超过 LSV 限值?”env_noise_limits_check

🛡️ 安全与限制

方面详情
访问权限只读(readOnlyHint: true)——服务无法修改或删除任何数据
个人数据不涉及个人数据——所有来源均为汇总后的公开环境测量数据
速率限制内置单次查询上限(例如,水文历史数据最多 30 天,数据集搜索结果最多 50 条)
超时每次 API 调用 30 秒
身份验证无需 API 密钥——所有 BAFU 端点均可公开访问
许可证BAFU 开放政府数据(OGD)——可免费复用,但必须注明出处
服务条款须遵守相应数据源的服务条款:BAFU / opendata.swiss、hydrodaten.admin.ch、naturgefahren.ch、waldbrandgefahr.ch

架构

┌─────────────────┐     ┌───────────────────────────┐     ┌──────────────────────────┐
│   Claude / AI   │────▶│   Swiss Environment MCP   │────▶│  Upstreams (contacted)   │
│   (MCP Host)    │◀────│   (MCP Server)            │◀────│                          │
└─────────────────┘     │                           │     │  lindas.admin.ch (SPARQL)│
                        │  21 Tools · 3 Resources   │     │  measurement-api.slf.ch  │
                        │  Stdio | SSE              │     │  aws.slf.ch              │
                        │                           │     │  waldbrandgefahr.ch      │
                        │  api_client.py            │     │  jagdstatistik.ch        │
                        │  server.py (FastMCP)      │     │  api3.geo.admin.ch       │
                        └───────────────────────────┘     │  opendata.swiss (CKAN)   │
                                                          └──────────────────────────┘
架构说明 — 可提取的 lindas/ 模块

所有 LINDAS SPARQL 访问都通过专门设计为可提取的 src/swiss_environment_mcp/lindas/ 模块进行,该模块由三个严格分层的部分构成: client.py 仅处理 SPARQL 和 HTTP(GET/POST、客户端侧超时 45 s、 携带服务器 MALFORMED 消息的 QueryError、2 s/4 s/8 s 重试); cube.py 处理 cube.link 词汇表(强制使用 observationSet 进行两阶段访问,通过 schema:expires 去重版本,将代码解析为标签, 查询许可证);工具只会调用 cube.py。一旦第二个服务使用 LINDAS(候选项目:wsl-envidat-mcp),该模块就会被提取为共享的 lindas-mcp。

架构决策 —— 飞机噪声地籍采用实时 API

本服务器的其余部分遵循项目组合的 优先使用数据转储 标准。飞机噪声数据集有意采用不同做法:env_noise_aircraft_at 和 env_noise_aircraft_registers 每次调用时都会实时查询 api3.geo.admin.ch。

这不是因为数据量。根据 2026-07-28 的测量,整个地籍在全部 8 个子图层中共包含 747 个对象(约 3 MB GeoJSON),轻松就能镜像。另有两个原因决定了这一做法:

  1. 镜像会让新鲜度声明失实。 各机场的地籍会单独修订,且没有公告(有效期为 2009–2024 年)。如果从数据转储读取,source_freshness 报告的 validfrom 就会是镜像日期;该工具会声称拥有实际上已不再具备的来源凭据。对于这样一个第三个工具恰恰是为了回答“依据有多旧”而存在的数据集,这会是最糟糕的故障模式。
  2. 空间查询才是价值所在,而非属性。 在本地评估意味着要对每个图层超过 26,000 个顶点计算点到线的距离。这需要使用 shapely/GEOS——这会成为特意保持不含二进制依赖的 pyproject.toml 中第一个编译依赖(Docker 镜像、wheel 矩阵和安全面都会随之改变)——或者手写距离计算。后者可行,因为 LV95 是度量投影,欧几里得距离是精确的;但那样一来,负责官方噪声地籍声明准确性的就会变成本服务器,而不是联邦办公室。

完整的测量数据和推理过程:docs/probe-fluglaerm.md。

数据来源
来源数据许可证
lindas.admin.ch通过 SPARQL 获取当前水文数据(水位、流量、水温)和沐浴水质BAFU Open-Use / OGD(按图谱/数据集声明——每个响应都包含许可证字段)
hydrodaten.admin.ch自 v0.6.0 起不再通过 HTTP 联系——/lhg/az/* 端点已停用,数据来自 LINDAS。仅作为工具输出中的链接出现,并已从出口允许列表中移除(SEC-021)。BAFU OGD
naturgefahren.ch自然灾害公告(SLF/BAFU)BAFU/SLF
waldbrandgefahr.ch野火危险指数BAFU
SLF data service雪深、新雪(IMIS);雪崩公告SLF (WSL) CC BY 4.0
jagdstatistik.ch联邦狩猎统计(捕获量、野生动物损失、种群数量)BAFU——必须注明来源(未发布明确许可证)
api3.geo.admin.chBAZL 飞机噪声地籍(identify、LV95)swisstopo / BAZL——可免费复用,但必须注明来源
opendata.swissBAFU 数据目录(CKAN API)OGD

所有数据均可公开访问,无需身份验证。
必须注明来源: 使用 BAFU / SLF (WSL) 的数据时,必须将其列为来源。


项目结构

swiss-environment-mcp/
├── src/swiss_environment_mcp/
│   ├── __init__.py          # Package
│   ├── server.py            # FastMCP server: 21 tools, 3 resources
│   ├── api_client.py        # HTTP client + egress allow-list (SSRF guard)
│   └── logging_setup.py     # structlog -> stderr
├── tests/
│   ├── test_unit.py         # Mocked unit tests (no network) — CI default
│   ├── test_integration.py  # Live API tests (marker: live)
│   └── test_20_scenarios.py # Live scenario coverage
├── scripts/tool_snapshot.py # Tool-definition hash snapshot (rug-pull guard)
├── docs/                    # security.md, scaling.md, roadmap.md
├── .github/
│   ├── dependabot.yml       # Monthly dependency/action updates
│   └── workflows/           # ci.yml, security.yml (gitleaks), live-tests.yml, publish.yml
├── Dockerfile               # Multi-stage, non-root container
├── render.yaml / Procfile   # Cloud deployment
├── tool-snapshot.json       # Committed tool-definition snapshot
├── .env.example             # Non-secret config template
└── pyproject.toml           # Build configuration (hatchling)

单模块布局(理由,审计 ARCH-011): 21 个工具集中在一个 server.py 中,而非放入 tools/ 包。它们是对 api_client.py 的轻量、统一封装,共享相同的输入/响应模式,因此将它们放在一个结构清晰的模块中,比拆分为 4 个几乎相同的文件更便于浏览。这是有意为之并已记录的偏离;如果工具逻辑不再统一,将重新评估是否拆分。


MCP 协议版本与维护

此服务通过同一端点支持两个协议时代。客户端在连接上的首个请求决定使用哪种协议;之后若声明另一个时代,则会被拒绝。

时代修订版本如何接入
initialize 握手2024-11-05 … 2025-11-25当前客户端使用的协议。服务会以请求中指定的修订版本响应;如果请求要求更新版本,则使用 2025-11-25 这一上限。
逐请求封装2026-07-28携带 2026-07-28 _meta 封装的请求会建立现代连接。

两个修订版本都固定在 tests/test_protocol_version.py 中,并与已安装的 SDK 进行断言比对,因此 Dependabot 升级 mcp 时,不会悄然改变任一版本。

不过,这项固定检查测量的是 SDK,而不是本服务:即使服务完全没有响应现代协议时代,检查也仍会通过。实际测量的部分位于 tests/test_modern_protocol.py 中——通过生产应用(build_cors_app(),即运行时由 uvicorn 启动的同一应用)发送两个时代的真实请求,并包含负向测试:缺少 _meta 封装、路由标头不匹配,以及在现代连接上发送 initialize。

2026-07-28 对本服务的实际含义
  • 没有会话,也没有 initialize——因此握手结果中没有 serverInfo。服务通过 server/discover 和每个响应携带的 io.modelcontextprotocol/serverInfo _meta 标记来介绍自身。名称、标题、描述、网站和版本均来自 MCPServer 构造函数;版本取自软件包元数据,绝不使用字面值。缺少该版本时,服务会报告 version: "",无状态客户端便无法区分不同发行版。
  • 路由标头。 Mcp-Method、Mcp-Name 和 MCP-Protocol-Version 必须与请求正文一致,否则请求会以 -32020 被拒绝。因此这些标头会出现在 CORS_ALLOW_HEADERS 中——浏览器可能不会发送它们;遇到这种情况时,请求会被拒绝,而不是获得响应。
  • 日志记录需要逐请求主动选择(SEP-2577)。能力声明已移除;没有保留的 io.modelcontextprotocol/logLevel _meta 键时,服务不会发送任何内容。使用 logLevel: "warning" 时,响应会切换为 text/event-stream 并携带日志条目。两个方向都会进行测量。
  • 新鲜度提示(SEP-2549):列表方法会携带 ttlMs 和 cacheScope——见 CACHE_HINTS。

请注意,SDK 的 LATEST_PROTOCOL_VERSION 是现代协议时代的别名,而非握手协议时代的别名——仅依据它进行固定,会让当前客户端实际协商使用的协议时代处于不受约束的状态。

更新策略。 门禁检查失败时,不要盲目修改常量:应阅读两个修订版本之间的规范变更日志,确认服务行为仍然正常,然后一并更新常量、本节、README.de.md 和 CHANGELOG.md。

  • 工具定义稳定性(审计 SEC-022): 任何对工具名称、描述或参数的更改都会改变 tool-snapshot.json;CI 会失败,直到重新生成快照,并添加 CHANGELOG 条目和版本升级。
  • 更新策略: 每月审查 Dependabot PR;任何工具定义或行为变更都要升级版本(semver)。

生命周期阶段

此服务处于阶段 1(只读)——所有工具均为只读,不进行身份验证,也没有副作用。阶段模型以及阶段 2(写入/身份验证)的前置条件见 docs/roadmap.md。安全架构(SSRF/出站流量、密钥管理、致命三角评估):docs/security.md。 扩缩容/会话策略:docs/scaling.md。


已知限制

  • 通过 LINDAS 获取水文数据:env_hydro_current、env_hydro_stations 和 env_flood_warnings 会查询 BAFU LINDAS SPARQL 端点(带类型的实时值:水位、流量、水温、危险等级)。LINDAS 仅保存当前值(每个站点一条观测记录),不是历史时间序列。参见 docs/probe-lindas-hydro.md。
  • 历史水文数据 / env_hydro_history(BUG-01 已解决):旧版 hydrodaten.admin.ch/lhg/az/* REST 端点(每小时 CSV、warnings.json、站点 JSON)已停用(404)。env_flood_warnings 现在改用 LINDAS 的 dangerLevel。真实的历史时间序列(每日数据 / 长期平均值,例如2024 年夏季与长期平均值的对比)无法通过 API 免费获取;必须向 BAFU 水文咨询服务订购([email protected])。env_hydro_history 会返回最新的 LINDAS 值以及获取这些数据的途径。
  • 洪水警报:env_flood_warnings 会读取 LINDAS 的 dangerLevel。LINDAS 不提供州代码,因此不支持按州筛选,响应始终覆盖全国;如果请求中提供了 canton 值,响应会原样返回并标记该筛选未应用——JSON 信封中会通过 match_type: "fuzzy" 和说明标记,Markdown 中则会在表格上方显示警告行。完全没有警报时尤其需要注意:若请求中包含某个州的信息,“当前无有效警报”可能会被误解为该州已解除警报。
  • 水文测站 / 按州筛选:env_hydro_stations 不再支持 canton。唯一提供州代码的数据源——hydrodaten.admin.ch/lhg/az/json/mobile_stations.json——已停用(404),而 LINDAS 没有州属性。设置了 canton 的请求会返回说明,而非测站列表;请使用 water_body,或不加筛选地获取完整列表(233 个测站)。
  • 沐浴水质(env_bathing_water):读取 LINDAS 数据立方体 foen/ubd01041prod——这是唯一具有真实多年时间序列的水文数据立方体(自 2020 年起的季节性采样数据)。数据在每年沐浴季结束后更新(不提供实时监测),调查仅覆盖官方上报的沐浴地点(许多热门露天泳场不在调查范围内)。许可信息在图/数据集中声明,而非数据立方体中;因此每个响应都会包含明确的许可字段,如果没有许可信息,则会如实注明“未声明”。参见 docs/probe-lindas-hydro.md(补充说明 N1–N7)。
  • LINDAS 中没有地下水数据:已于 2026-07-24 通过多语言数据立方体搜索验证——LINDAS 没有地下水数据立方体(无法通过 SPARQL 获取 NAQUA 地下水位)。
  • NABEL:仅提供近实时数据;此服务不提供历史时间序列。
  • 自然灾害(env_hazard_overview / env_hazard_regions):原有的 naturgefahren.ch/api/v1/warnings/* REST 端点已于 2026 年停用;截至 2026-07-26 的验证结果表明,没有稳定且有文档说明的公共 JSON 警报汇总源(已检查 MeteoSwiss OGD/STAC、opendata.swiss 以及未公开文档的应用 API)。为避免不可靠的网页抓取,这两个工具现在是无网络的指引/路由工具:会以确定性的方式指向此服务中专用的实时工具(洪水→env_flood_warnings、雪崩→env_avalanche_bulletin、野火→env_wildfire_danger、积雪→env_snow_current)以及官方门户。汇总的天气警报(风暴/雷暴/高温)属于 MeteoSwiss 的职责范围,应由 meteoswiss-mcp 提供。参见 docs/probe-naturgefahren-hazards.md。
  • 野火危险等级(env_wildfire_danger):waldbrandgefahr.ch 于 2026 年以 Rails/React 应用取代其 REST API;目前没有稳定的 JSON 端点。当前危险等级通过两步式、由 HTML 承载的约定读取:首页的 data-react-props 会提供一个已签名的 ActiveStorage Blob URL(warnMapJsonPath)以及州映射,随后再获取该 URL 的内容。如果该结构发生变化,模式保护机制会优雅降级。未筛选的结果最多显示 40 个区域(按危险等级从高到低排列);若要获取某州的完整列表,请按 canton 筛选。参见 docs/probe-naturgefahren-waldbrand.md。
  • 狩猎统计(env_hunting_stats):jagdstatistik.ch 后端没有文档说明(这是一个根据内容协商返回数据的 Web 应用端点)。如果结构发生变化,模式保护机制会优雅降级。物种/州/数据类型查询信息已嵌入(采集于 2026-07-19);2015–2024 年的数值会实时获取。许可情况(调查于 2026-07-19):数据归 BAFU 所有(汇总自各州办事处;网站技术由 Wildtier Schweiz 提供),且未作为带许可的数据集发布在 opendata.swiss 上;数据源未声明明确许可。因此,响应必须注明数据来源为 BAFU;仍在等待 BAFU 正式确认许可。参见 docs/probe-jagdstatistik.md。
  • 道路和铁路噪声不在范围内(ch.bafu.laerm-*、ch.bav.laermbelastung-*):已于 2026-07-28 验证。BAFU 道路噪声图层 ch.bafu.laerm-strassenlaerm_tag / _nacht 对相同的 identify 请求返回 HTTP 400——它们是纯栅格服务(type: wmts、tooltip: false),无法查询属性,因此从技术上讲不可能按点查询。铁路噪声的情况不同:ch.bav.laermbelastung-eisenbahn_* 确实会返回 HTTP 200 和真实属性(de_es、de_pointofdetermination),因此可以查询,但有意未接入——此服务的工具预算已用尽,共 21 个;而铁路噪声需要单独设计时段/属性模型。记忆口诀:航空器噪声有线条,道路噪声只有像素——铁路噪声有数据,但这是有意省略的。参见 docs/probe-fluglaerm.md。
  • 航空器噪声是截止日期固定的地籍数据,而非实时服务(env_noise_*):validfrom 的日期范围从 01.03.2009(CDB Genève)到 16.04.2024(LBK St. Gallen-Altenrhein);各机场单独更新,且不另行通知。因此,source_freshness 从不声称数据是“实时”的,而是记录实际匹配到的登记数据的 validfrom。覆盖范围仅限机场周边;瑞士大部分地区根本没有噪声地籍数据,工具会明确报告这一点,而非返回空列表。小半径查询没有命中时,存在歧义(可能位于所有地籍数据的覆盖范围之外,也可能位于最内侧等值线内——在 Kloten 跑道上,半径为 100 m 时这两种情况看起来相同),因此工具会使用更大的半径再查询一次,以区分 no_cadastre 和 wide_area_only。
  • LSV 限值检查不包括军用机场:《噪声防治条例》附录 5 明确适用于民用机场。军用机场适用附录 8;由于尚未核实相关规定,env_noise_limits_check 会拒绝对 period="military" 进行检查,并指明正确的依据,而不会套用看似合理、实则错误的表格。
职责矩阵 — 水体、积雪与降水(与 meteoswiss-mcp 的职责划分)

为避免在整个项目组合中重复提供水体、积雪和降水数据,职责划分如下:meteoswiss-mcp 负责大气降水和天气;swiss-environment-mcp 负责地表水体(BAFU 领域:流量、水位、水温、沐浴水质)、地面积雪和雪崩危险。经核对实际 LINDAS 数据立方体维度(2026-07-24):测量量没有重叠。

数据swiss-environment-mcp(BAFU / SLF)meteoswiss-mcp(MeteoSwiss)
流量(m³/s)✅ env_hydro_current(LINDAS hydro/river)❌
水位(m a.s.l.)✅ env_hydro_current(LINDAS hydro/river + lake)❌
水温(°C)✅ env_hydro_current❌(测量空气温度)
沐浴水质(E.coli 等)✅ env_bathing_water(LINDAS ubd0104)❌
地面积雪深度(HS)✅ env_snow_current(SLF IMIS)❌
24 小时新雪量(HN_1D)✅ env_snow_current(SLF IMIS)❌
雪崩危险等级✅ env_avalanche_bulletin(SLF,EAWS 1–5)❌
作为当前天气状况的降雪❌✅ meteo_current / meteo_forecast(天气代码)
降水量(mm):测量网络、预报、气候常年值❌✅ meteo_current / meteo_forecast / meteo_climate_normals
SLF IMIS 山区站点的降水✅ 仅作为雪盖背景信息,没有独立的降水工具(MeteoSwiss 网络)
天气预警(风暴、雷暴、酷热)❌✅ meteo_warnings
自然灾害预警(洪水、雪崩、野火)✅ env_flood_warnings、env_hazard_*、env_wildfire_danger❌

规则:所有水体内及水体上的数据(流量、水位、水温、沐浴水质)、地面上的积雪和雪崩危险均归 swiss-environment-mcp(BAFU/SLF)负责;大气降水(以 mm 表示的雨/降雪)以及天气、预报、预警和气候常年值均归 meteoswiss-mcp 负责。SLF IMIS 降水端点(RR_10MIN_SUM)有意不接入为工具,因此不会与 MeteoSwiss 重复。积雪/雪崩工具已上线(见 docs/probe-slf.md)。 TODO(不在此处范围内):在 meteoswiss-mcp README 中同步此矩阵——该仓库不属于本次更改范围。


测试

# Unit tests (no API keys or network required)
PYTHONPATH=src pytest tests/ -m "not live"

# Integration tests (requires live BAFU APIs)
PYTHONPATH=src pytest tests/ -m "live"

# Linting
ruff check src/

贡献

参见 CONTRIBUTING.md(英语)· CONTRIBUTING.de.md(德语)


安全

安全政策与安全态势:SECURITY.md(英语)· SECURITY.de.md(德语)。 完整安全架构:docs/security.md。


更新日志

参见 CHANGELOG.md


许可证

MIT 许可证 — 参见 LICENSE

源数据受 BAFU 使用条款约束。使用其数据时必须注明 BAFU。


作者

Hayal Oezkan · github.com/malkreide


致谢与相关项目

服务描述
zurich-opendata-mcp苏黎世市开放数据(OSTLUFT 空气质量、天气、停车和地理数据)
swiss-transport-mcp瑞士公共交通——OJP 2.0 行程规划、SIRI-SX 中断信息
swiss-road-mobility-mcpGBFS 共享出行、电动汽车充电、DATEX II 交通信息
swiss-statistics-mcpBFS STAT-TAB——682 个统计数据集

协同示例: “今天 Schulhaus Leutschenbach 的空气质量如何?与全国 NABEL 平均值相比如何?”
→ zurich-opendata-mcp(OSTLUFT,本地)+ swiss-environment-mcp(NABEL,全国)

安装

通过 uv 的 uvx 运行——无需克隆或手动安装。将其添加到 MCP 客户端配置中(Claude Desktop、Cursor 和 Windsurf 使用 mcpServers;VS Code 在 .vscode/mcp.json 中使用顶层 servers 键):

{
  "mcpServers": {
    "swiss-environment-mcp": {
      "command": "uvx",
      "args": [
        "swiss-environment-mcp"
      ]
    }
  }
}

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。