关于 wsl-envidat-mcp
wsl-envidat-mcp 将瑞士 WSL 研究机构在 EnviDat 发布的环境研究数据接入 MCP 客户端,适用于查找森林、雪与冰、自然灾害、生物多样性及景观数据。它提供关键词、领域和地理范围筛选,以及雪崩、森林和自然灾害主题工具。
主要功能
- 01按关键词、领域和地理范围搜索
- 02获取数据集详情及下载链接
- 03浏览研究单位、标签和最新数据集
- 04查询雪崩、森林和自然灾害专题
- 05提供组织与研究领域资源
- 06支持 stdio 和 Streamable HTTP
适用场景
- 01查找瓦莱州雪崩事故数据
- 02查看苏黎世州森林健康数据
- 03搜索布里恩茨附近的滑坡风险数据
- 04按地理范围查找康斯坦茨湖周边数据
MCP 相关
该 MCP 服务通过工具和资源向客户端开放 EnviDat CKAN API 的公开环境研究数据。所有工具均为只读,无需 API 密钥。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
10收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| params | any | 是 |
详细介绍
🇨🇭 属于 瑞士公共数据 MCP 组合
wsl-envidat-mcp 🌲❄️⛰️
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 对该州当前的森林状况有何评价?”
演示
功能
- 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_TRANSPORT | stdio | 传输模式:stdio 或 streamable-http(也接受旧版 streamable_http) |
MCP_HOST | 127.0.0.1 | streamable-http 的绑定地址。仅在容器内使用 0.0.0.0。 |
PORT | 8000 | Streamable 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_data | SLF 雪崩与雪况数据(包括 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
致谢与相关项目
- 数据:EnviDat – WSL 瑞士联邦森林、雪和景观研究所
- 协议:Model Context Protocol – Anthropic / Linux Foundation
- 作品集:瑞士公共数据 MCP 作品集
安装
通过 uv 的 uvx 运行——无需克隆或手动安装。添加到 MCP 客户端配置中(Claude Desktop、Cursor 和 Windsurf 使用 mcpServers;VS Code 在 .vscode/mcp.json 中使用顶层 servers 键):
{
"mcpServers": {
"wsl-envidat-mcp": {
"command": "uvx",
"args": [
"wsl-envidat-mcp"
]
}
}
}
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。