mcpField
W
wsl-envidat-mcp

wsl-envidat-mcp

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

关于 wsl-envidat-mcp

wsl-envidat-mcp 将瑞士 WSL 研究机构在 EnviDat 发布的环境研究数据接入 MCP 客户端,适用于查找森林、雪与冰、自然灾害、生物多样性及景观数据。它提供关键词、领域和地理范围筛选,以及雪崩、森林和自然灾害主题工具。

主要功能

  1. 01按关键词、领域和地理范围搜索
  2. 02获取数据集详情及下载链接
  3. 03浏览研究单位、标签和最新数据集
  4. 04查询雪崩、森林和自然灾害专题
  5. 05提供组织与研究领域资源
  6. 06支持 stdio 和 Streamable HTTP

适用场景

  1. 01查找瓦莱州雪崩事故数据
  2. 02查看苏黎世州森林健康数据
  3. 03搜索布里恩茨附近的滑坡风险数据
  4. 04按地理范围查找康斯坦茨湖周边数据

MCP 相关

该 MCP 服务通过工具和资源向客户端开放 EnviDat CKAN API 的公开环境研究数据。所有工具均为只读,无需 API 密钥。

配置

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

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

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

安装包
pypiwsl-envidat-mcp0.3.1

工具

10

收录的工具列表 · 更新于 2 周前

参数类型必填说明
paramsany是

详细介绍

🇨🇭 属于 瑞士公共数据 MCP 组合

wsl-envidat-mcp 🌲❄️⛰️

Version License: MIT Python 3.11+ MCP Data Source No API Key CI

MCP 服务通过 EnviDat 将 AI 模型连接到 WSL 的瑞士环境研究数据,涵盖森林、雪、雪崩、自然灾害和生物多样性,无需 API 密钥。

🇩🇪 德语版


阶段

此服务处于 阶段 1:只读封装。

属性状态
读取工具✅ 10 个工具,全部为 readOnlyHint: true
写入工具❌ 无(EnviDat 是只读公共数据)
语义层⚠️ 部分实现——三个领域工具整理了 Solr 查询
OAuth / 身份验证网关❌ 无需(公共开放数据,无需 API 密钥)
容器加固✅ 多阶段 Dockerfile,非 root 用户运行
测试套件✅ 38 个离线单元测试 + 31 个实时集成测试
审计运行✅ 2026-05-27(mcp-audit-skill v1.0.0)

第二阶段构想(缓存层、将森林 + 雪 + 灾害数据整合为“形势概览”的语义聚合工具):已在 docs/ 下跟踪。


概述

WSL(瑞士联邦森林、雪与景观研究所 / Swiss Federal Research Institute for Forest, Snow and Landscape)是欧洲领先的环境研究机构之一。其开放数据平台 EnviDat 提供对 1,000 多个研究数据集、最长达 130 年的时间序列,以及来自 6,000 多个监测站的数据的访问。

此 MCP 服务将 EnviDat CKAN API 封装为 10 个工具和 2 个资源,使 AI 助手能够按关键词、领域或地理边界框搜索、筛选和获取 WSL 研究数据——无需 API 密钥。

示例演示查询: “苏黎世 Schulhaus Leutschenbach 周边的空气质量和森林健康状况如何——WSL 对该州当前的森林状况有何评价?”

演示

演示:Claude 使用 wsl_get_avalanche_data、wsl_get_forest_data 和 wsl_catalog_stats


功能

  • 10 个工具,涵盖全文搜索、领域专用查询、空间搜索和精选主题工具(雪崩、森林、自然灾害)
  • 2 个 MCP 资源,用于组织机构和研究领域
  • 5 个研究领域:森林 · 生物多样性 · 自然灾害 · 雪与冰 · 景观
  • 815 多个数据集、始于 1890 年的时间序列,以及来自 SLF 雪崩研究所的数据
  • 无需 API 密钥——所有数据均通过开放许可公开访问
  • 双传输方式:stdio(Claude Desktop / 本地)+ Streamable HTTP(云端部署)
  • 与模型无关:适用于 Claude、GPT-4 以及任何兼容 MCP 的客户端

前提条件

  • Python 3.11+
  • pip 或 uv / uvx
  • 互联网连接(调用 envidat.ch 实时 API)

安装

# Recommended: uvx (no installation needed)
uvx wsl-envidat-mcp

# Or with pip
pip install wsl-envidat-mcp

# Development
git clone https://github.com/malkreide/wsl-envidat-mcp.git
cd wsl-envidat-mcp
pip install -e ".[dev]"

快速开始

Claude Desktop

编辑 ~/Library/Application Support/Claude/claude_desktop_config.json(macOS)或 %APPDATA%\Claude\claude_desktop_config.json(Windows):

{
  "mcpServers": {
    "wsl-envidat": {
      "command": "uvx",
      "args": ["wsl-envidat-mcp"]
    }
  }
}

重启 Claude Desktop,然后询问:

  • "瑞士致命雪崩事故有哪些 WSL 数据集?"
  • "显示苏黎世州的 LFI 森林清查数据。"
  • "SLF 在 EnviDat 上发布了哪些自然灾害研究数据?"
  • "有没有关于 2022 年夏季干旱状况的 WSL 数据集?"
  • "高山生态系统有哪些生物多样性数据?"

配置

无需 API 密钥。可选环境变量:

变量默认值说明
MCP_TRANSPORTstdio传输模式:stdio 或 streamable-http(也接受旧版 streamable_http)
MCP_HOST127.0.0.1streamable-http 的绑定地址。仅在容器内使用 0.0.0.0。
PORT8000Streamable HTTP 模式的端口
云端部署(Streamable HTTP)

供浏览器中的 claude.ai 使用(例如,在没有本地软件的托管工作站上):

# Local: keep MCP_HOST at its default 127.0.0.1
MCP_TRANSPORT=streamable-http PORT=8000 python -m wsl_envidat_mcp.server

# Container: bind to all interfaces inside the container only
MCP_TRANSPORT=streamable-http MCP_HOST=0.0.0.0 PORT=8000 python -m wsl_envidat_mcp.server

💡 "开发者笔记本使用 stdio,浏览器使用 streamable-http。"

⚠️ **多副本云端部署:**会话状态保存在服务端。 运行单个副本,或启用会话保持(Railway/Render 设置, 或在 Kubernetes Services 上设置 sessionAffinity: ClientIP)。

⚠️ **多租户/未经身份验证的 Streamable HTTP:**此服务没有 身份验证层(auth_model: none)。没有反向代理 + OAuth/API-Gateway 的 Streamable HTTP 仅适用于单用户部署 (例如,单个用户的 claude.ai 浏览器会话)。如需多租户使用, 请在服务前部署带身份验证功能的网关。

容器镜像(推荐用于云端)

每次推送到 main 和每次发布 semver 标签时,都会向 GitHub Container Registry 发布经过加固的多阶段镜像。以非 root 用户(uid=1000)运行,运行时层不包含 构建工具,并支持多架构(linux/amd64 + linux/arm64)。

发布工作流为 .github/workflows/container.yml — 而非 publish.yml;后者只会在发布时将 Python 软件包上传到 PyPI。 container.yml 负责交付,而非门禁:它不会阻止拉取请求;其中运行失败 意味着镜像缺失,而非代码存在问题。

docker run --rm -p 8000:8000 \
  --read-only --tmpfs /tmp \
  --cap-drop=ALL --security-opt=no-new-privileges \
  ghcr.io/malkreide/wsl-envidat-mcp:latest

Kubernetes 加固(节选):

securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  capabilities: { drop: ["ALL"] }

可用工具

工具说明
wsl_search统一搜索 — 可组合使用 query、domain、organization 和 bbox 筛选条件
wsl_get_dataset获取特定数据集的完整元数据、DOI 和下载 URL
wsl_list_organizations列出 EnviDat 上所有 WSL 研究单位
wsl_get_organization获取特定研究单位的详细信息,包括其数据集
wsl_list_tags浏览可用标签/关键词
wsl_get_recent_datasets获取最近更新的数据集
wsl_get_avalanche_dataSLF 雪崩与雪况数据(包括 1936 年以来的致命事故)
wsl_get_forest_data森林数据,包括国家森林清查(LFI)和 Sanasilva
wsl_get_naturgefahren_data自然灾害数据集(土石流、落石、洪水)
wsl_catalog_stats数据目录概览与统计信息
使用场景示例
查询工具
"2000 年以来瓦莱州有哪些致命雪崩事故?"wsl_get_avalanche_data
"苏黎世州有哪些森林健康数据?"wsl_get_forest_data
"布里恩茨附近有哪些山体滑坡风险数据集?"wsl_get_naturgefahren_data
"WSL 最近发布了哪些生物多样性相关内容?"wsl_search(domain="biodiversitaet")
"哪些数据集覆盖博登湖周边区域?"wsl_search(bbox=[9.0, 47.5, 9.7, 47.8])
"SLF 发布了多少个数据集?"wsl_get_organization

资源

URI描述
envidat://organization/{name}研究单位(例如 slf、wsl)
envidat://domain/{domain}领域概览及热门数据集

有效的领域值:wald、biodiversitaet、naturgefahren、schnee_eis、landschaft


架构

┌─────────────────┐     ┌───────────────────────────┐     ┌──────────────────────────┐
│   Claude / AI   │────▶│    WSL EnviDat MCP        │────▶│       envidat.ch          │
│   (MCP Host)    │◀────│    (MCP Server)           │◀────│                          │
└─────────────────┘     │                           │     │  CKAN API  (REST/JSON)   │
                        │  10 Tools · 2 Resources   │     │  Solr full-text search   │
                        │  Stdio | Streamable HTTP  │     │  1,000+ research datasets│
                        │                           │     │  815+ open datasets      │
                        │  server.py                │     │  Time series since 1890  │
                        │  api_client.py            │     └──────────────────────────┘
                        └───────────────────────────┘
基础设施组件
组件比喻功能
api_client.py图书管理员处理所有发往 EnviDat CKAN API 的 HTTP 请求
server.py接待处使用 FastMCP 注册全部 10 个工具和 2 个资源
领域筛选器文件柜为各研究领域预配置的关键词集
边界框搜索地图叠加层通过纬度/经度坐标进行空间筛选

项目结构

wsl-envidat-mcp/
├── src/wsl_envidat_mcp/
│   ├── __init__.py         # Package
│   ├── server.py           # MCP server — 10 tools, 2 resources
│   └── api_client.py       # HTTP client for EnviDat CKAN API
├── tests/
│   └── test_integration.py # 11 live API integration tests
├── .github/workflows/
│   ├── ci.yml              # Gates: lint, format, syntax, import, tests, version sync
│   ├── live.yml            # Scheduled live tests against envidat.ch (cron 05:47 UTC)
│   ├── container.yml       # Builds & pushes the ghcr.io image (delivery, not a gate)
│   └── publish.yml         # Uploads the Python package to PyPI on a release
├── pyproject.toml          # Project config (hatchling build backend)
├── CHANGELOG.md
├── CONTRIBUTING.md         # Contribution guide (English)
├── CONTRIBUTING.de.md      # Contribution guide (German)
├── SECURITY.md             # Security policy & posture (English)
├── SECURITY.de.md          # Security policy & posture (German)
├── LICENSE                 # MIT
├── README.md               # This file (English)
└── README.de.md            # German version

与其他 MCP 服务组合使用

此服务属于 Swiss Open Data MCP Portfolio,可与以下服务良好集成:

组合使用场景
+ zurich-opendata-mcp苏黎世周边的城市气候 + 森林状况
+ swiss-statistics-mcp人口数据 + 环境质量
+ swiss-transport-mcp雪崩风险 + 公共交通连接
+ fedlex-mcp森林保护法 + 实际 LFI 森林状况
+ global-education-mcp国际环境教育数据比较

已知限制

  • Solr 搜索:OR 会被视为停用词 — 每次查询请使用单个、明确的搜索词
  • 领域搜索:结果取决于 WSL 的内部关键词标记 — 并非所有数据集的标记都一致
  • 空间搜索:边界框筛选是近似的;请通过各数据集的元数据核实坐标
  • 实时 API:所有工具都会实时调用 envidat.ch — 结果取决于公共 API 是否可用
  • 语言:数据集元数据主要为英语和德语;部分较早的条目可能只有德语版本

安全与限制

  • 只读: 所有工具仅执行 HTTP GET 请求 — 不会在 EnviDat 上写入、修改或删除数据。
  • 无个人数据: API 返回研究元数据、数据集描述和下载 URL。此服务不会处理或存储任何个人身份信息(PII)。
  • 速率限制: EnviDat CKAN API 是公共 API,未公布速率限制。请谨慎使用 limit 和 rows 参数。此服务对每个请求强制执行 30 秒超时。
  • 数据时效性: 所有工具都会实时调用 API — 结果反映查询时 EnviDat 目录的当前状态。此服务不会进行缓存。
  • 服务条款: 数据受 EnviDat 使用条款约束。各数据集依据不同的开放许可证(Creative Commons、CC0)发布 — 请参阅数据集元数据。
  • 不作保证: 这是一个社区项目,与 WSL 或 EnviDat 无关联。服务可用性取决于上游 EnviDat API。

有关完整的安全措施(出口允许列表、重定向处理、已接受风险),请参阅 SECURITY.md。


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 时不会悄然改变其中任何一个。此服务不会构建 ASGI 应用来发送 initialize 请求,因此该检查断言的是 SDK 常量,而非实测响应——这是较弱的做法,但至少明确说明了这一点。

server.py 中的 SUPPORTED_MCP_PROTOCOL_VERSION 指定了现代时代;若与 SDK 不匹配,启动时会记录警告。警告不是检查关卡——这正是测试文件的用途。

请注意,SDK 的 LATEST_PROTOCOL_VERSION 是现代时代的别名,而非握手时代的别名——若只针对它固定版本,当今客户端实际协商的时代仍会任其漂移。

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


服务器对 2026-07-28 的实际应用

固定一个修订版本,并不代表实际遵循了它。此前,这个服务器固定使用 2026-07-28,却仍采用更早时代的数据结构;上表所述属实,但实际传输的数据并没有听起来那么新。

每个工具结果包含两个通道。 该修订版本为工具结果提供了供读者使用的 content,以及供应用使用的 structuredContent,并以 outputSchema 作为两者之间的约定。现在,每个工具都会同时填充两者:content 中是与之前相同、供人阅读的 Markdown,structuredContent 中则是其背后的数据——带类型且有架构支持。

这不是一个新接口。这些字段与 response_format="json" 一直以来生成的有效载荷完全相同。该选项是 structuredContent 的前身:它之所以存在,只是因为在 2026-07-28 之前只有一个通道,所以机器可读版本必须作为 JSON 字符串,传到供读者使用的通道中。response_format 仍然有效,且仍只控制文本块。

它取代的做法甚至不如没有。签名 -> str 会让 SDK 发布 {"result": string} 作为 outputSchema,并在其下方重复 Markdown 块。以记录的测试样本对 wsl_search 进行测量:文本有 2,058 个字符,structuredContent.result 也有 2,058 个字符,二者逐字相同。outputSchema 是一种承诺;而这个架构承诺了结构,实际却在名为 result 的键下交付了散文。

serverInfo 现在包含其六个字段。 之前它只包含两个字段,其中一个还是空值。version 是其中最难处理的字段:其值通过 scripts/check_version_sync.py 在 pyproject.toml、server.json 和 README 的两个徽章之间保持同步,却没有传到客户端读取它的地方。现在,它直接来自包元数据,因此 src/ 中不再需要写入字面值。

工具标题已移至 title。 它们之前位于 annotations.title,这是该修订版本之前使用的字段。遵循架构并读取 tool.title 的客户端会得到 None,于是显示 slug。

**有意不使用的功能:**服务器、工具和资源上的 icons,以及增强任务的调用流程(execution)。两者都是可选的,而且在这里都没有实际对应内容——此仓库不包含图标资源,所有调用都是简短的 CKAN 查询,能在一次请求内迅速完成。声明使用其中任一项,都是没有实际内容支撑的说法。

tests/test_structured_output.py 通过实时的 ClientSession 验证了以上所有内容,并提供了一个负向对照,展示服务器未采用此做法时 SDK 的行为——这样,等默认行为改变的那一天,断言会明确指出变化,而不是悄然通过。

测试

# Unit tests — offline, no network access, all CKAN responses mocked via respx
PYTHONPATH=src pytest -m "not live"

# Live integration tests — actual HTTP calls to envidat.ch
PYTHONPATH=src pytest -m live

# Linting
ruff check src/
ruff format --check src/

CI 会在每个 PR 上运行离线测试套件。实时测试套件只会在推送到 main 和手动触发 workflow_dispatch 时运行,因此构建状态不会受上游服务可用性的影响。


更新日志

请参阅 CHANGELOG.md


贡献

请参阅 CONTRIBUTING.md


安全

请参阅 SECURITY.md(德语),了解安全状况以及如何报告漏洞。


许可证

MIT 许可证——请参阅 LICENSE

EnviDat 上的数据采用多种开放许可证(Creative Commons、CC0)发布——请参阅各数据集的元数据。


作者

Hayal Oezkan · malkreide


致谢与相关项目

安装

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

{
  "mcpServers": {
    "wsl-envidat-mcp": {
      "command": "uvx",
      "args": [
        "wsl-envidat-mcp"
      ]
    }
  }
}

评论

支持 Markdown

第一次接触 MCP?

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

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