Server data from the Official MCP Registry
WSL / EnviDat environmental research datasets via CKAN
WSL / EnviDat environmental research datasets via CKAN
A well-structured, security-conscious MCP server for accessing Swiss environmental research data. The server is read-only, requires no authentication (appropriate for public open data), and implements proper input validation, error handling, and structured logging. Minor code quality observations noted, but no security vulnerabilities identified. Permissions are appropriately scoped to network HTTP access for the server's stated purpose. Supply chain analysis found 4 known vulnerabilities in dependencies (0 critical, 3 high severity). Package verification found 1 issue.
3 files analyzed Β· 10 issues found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
This plugin requests these system permissions. Most are normal for its category.
Add this to your MCP configuration file:
{
"mcpServers": {
"io-github-malkreide-wsl-envidat-mcp": {
"args": [
"wsl-envidat-mcp"
],
"command": "uvx"
}
}
}From the project's GitHub README.
π¨π Part of the Swiss Public Data MCP Portfolio
MCP server connecting AI models to Swiss environmental research data from WSL via EnviDat β forest, snow, avalanches, natural hazards and biodiversity, no API key required.
This server is in Phase 1: Read-only Wrapper.
| Property | Status |
|---|---|
| Read tools | β
10 tools, all readOnlyHint: true |
| Write tools | β none (EnviDat is read-only public data) |
| Semantic Layer | β οΈ partial β three domain tools curate Solr queries |
| OAuth / Auth Gateway | β not required (Public Open Data, no API key) |
| Container hardening | β multi-stage Dockerfile, non-root |
| Test suite | β 38 offline unit tests + 31 live integration tests |
| Audit run | β 2026-05-27 (mcp-audit-skill v1.0.0) |
Phase-2 ideas (caching layer, semantic aggregation tool combining forest +
snow + hazard data into a "Lage-Γbersicht"): tracked under docs/.
The WSL (EidgenΓΆssische Forschungsanstalt fΓΌr Wald, Schnee und Landschaft / Swiss Federal Research Institute for Forest, Snow and Landscape) is one of Europe's leading environmental research institutes. Its open data platform EnviDat provides access to 1,000+ research datasets, time series of up to 130 years, and data from 6,000+ monitoring stations.
This MCP server exposes the EnviDat CKAN API as 10 tools and 2 resources, enabling AI assistants to search, filter and retrieve WSL research data by keyword, domain, or geographic bounding box β all without an API key.
Anchor demo query: "How was air quality and forest health around Schulhaus Leutschenbach in Zurich β and what does the WSL say about the current forest condition in the canton?"
pip or uv / uvx# 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]"
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"wsl-envidat": {
"command": "uvx",
"args": ["wsl-envidat-mcp"]
}
}
}
Restart Claude Desktop, then ask:
No API key required. Optional environment variables:
| Variable | Default | Description |
|---|---|---|
MCP_TRANSPORT | stdio | Transport mode: stdio or streamable-http (legacy streamable_http is accepted) |
MCP_HOST | 127.0.0.1 | Bind address for streamable-http. Use 0.0.0.0 only inside a container. |
PORT | 8000 | Port for Streamable HTTP mode |
For use via claude.ai in the browser (e.g. on managed workstations without local software):
# 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 for the developer laptop, streamable-http for the browser."
β οΈ Multi-Replica Cloud Deployments: Session state lives in the server. Run a single replica or enable sticky sessions (Railway/Render setting, or
sessionAffinity: ClientIPon Kubernetes Services).
β οΈ Multi-Tenant / Unauthenticated Streamable HTTP: This server has no auth layer (
auth_model: none). Streamable HTTP without a reverse-proxy + OAuth/API-Gateway is intended only for single-user deployments (e.g. one user's claude.ai browser session). For multi-tenant use, front the server with an authenticating gateway.
A hardened multi-stage image is published to GitHub Container Registry on
every main push and semver tag. Runs as non-root (uid=1000), no build
tools in the runtime layer, multi-arch (linux/amd64 + linux/arm64).
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 hardening (excerpt):
securityContext:
runAsNonRoot: true
runAsUser: 1000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities: { drop: ["ALL"] }
| Tool | Description |
|---|---|
wsl_search | Unified search β combine query, domain, organization, and bbox filters |
wsl_get_dataset | Full metadata, DOI, download URLs for a specific dataset |
wsl_list_organizations | List all WSL research units on EnviDat |
wsl_get_organization | Details of a specific research unit incl. datasets |
wsl_list_tags | Browse available tags/keywords |
wsl_get_recent_datasets | Most recently updated datasets |
wsl_get_avalanche_data | SLF avalanche & snow data (incl. fatal accidents since 1936) |
wsl_get_forest_data | Forest data incl. National Forest Inventory (LFI) & Sanasilva |
wsl_get_naturgefahren_data | Natural hazard datasets (landslides, rockfall, floods) |
wsl_catalog_stats | Catalog overview and statistics |
| Query | Tool |
|---|---|
| "Fatal avalanche accidents in Valais since 2000?" | wsl_get_avalanche_data |
| "Forest health data for canton Zurich?" | wsl_get_forest_data |
| "Landslide risk datasets near Brienz?" | wsl_get_naturgefahren_data |
| "Most recent WSL publications on biodiversity?" | wsl_search(domain="biodiversitaet") |
| "Which datasets cover the area around Lake Constance?" | wsl_search(bbox=[9.0, 47.5, 9.7, 47.8]) |
| "How many datasets does SLF publish?" | wsl_get_organization |
| URI | Description |
|---|---|
envidat://organization/{name} | Research unit (e.g. slf, wsl) |
envidat://domain/{domain} | Domain overview with top datasets |
Valid domain values: 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 β ββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββ
| Component | Metaphor | Function |
|---|---|---|
api_client.py | Librarian | Handles all HTTP requests to EnviDat CKAN API |
server.py | Reception desk | Registers all 10 tools and 2 resources with FastMCP |
| Domain filters | Filing cabinet | Pre-configured keyword sets per research domain |
| Bounding box search | Map overlay | Spatial filtering via lat/lon coordinates |
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 # GitHub Actions CI (Python 3.11β3.13)
βββ 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
This server is part of the Swiss Open Data MCP Portfolio and integrates well with:
| Combination | Use Case |
|---|---|
+ zurich-opendata-mcp | Urban climate + forest condition around Zurich |
+ swiss-statistics-mcp | Population data + environmental quality |
+ swiss-transport-mcp | Avalanche risk + public transport connections |
+ fedlex-mcp | Forest protection law + actual LFI forest condition |
+ global-education-mcp | Compare environmental education data internationally |
OR is treated as a stopword β use single, specific search terms per querylimit and rows parameters conservatively. The server enforces a 30-second timeout per request.For the full security posture (egress allow-list, redirect handling, accepted risks) see SECURITY.md.
# 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 runs the offline suite on every PR. The live suite runs only on main
pushes and manual workflow_dispatch triggers, so build status is not
coupled to upstream availability.
See CHANGELOG.md
See CONTRIBUTING.md
MIT License β see LICENSE
Data on EnviDat is published under various open licenses (Creative Commons, CC0) β see individual dataset metadata.
Hayal Oezkan Β· malkreide
Be the first to review this server!
by Modelcontextprotocol Β· Developer Tools
Read, search, and manipulate Git repositories programmatically
by Modelcontextprotocol Β· Developer Tools
Web content fetching and conversion for efficient LLM usage
by Toleno Β· Developer Tools
Toleno Network MCP Server β Manage your Toleno mining account with Claude AI using natural language.