MCP server for Swiss federal geodata (Swisstopo APIs) — 13 tools for geocoding, height, STAC, WMTS, ÖREB and more
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
claude mcp add swisstopo-mcp -- uvx swisstopo-mcp{
"mcpServers": {
"swisstopo-mcp": {
"command": "uvx",
"args": ["swisstopo-mcp"]
}
}
}MCP Servers overview
> 🇨🇭 **Part of the [Swiss Public Data MCP Portfolio](https://github.com/malkreide)**
# swisstopo-mcp

[](https://opensource.org/licenses/MIT)
[](https://www.python.org/downloads/)
[](https://modelcontextprotocol.io/)
[](https://github.com/malkreide/swisstopo-mcp)

> MCP server for Swiss federal geodata -- maps, elevation, geocoding, cadastral extracts, and downloadable datasets via Swisstopo APIs
[🇩🇪 Deutsche Version](README.de.md)
---
## Overview
`swisstopo-mcp` gives AI assistants access to Switzerland's official geodata infrastructure through 20 tools, all without authentication:
| Source | Data | API |
|--------|------|-----|
| **Swisstopo REST API** | 500+ geodata layers (buildings, boundaries, land use) | REST/JSON |
| **Geocoding** | Official addresses, place names, postal codes | REST/JSON |
| **Height Service** | Elevation above sea level, elevation profiles | REST/JSON |
| **STAC Catalog** | Orthophotos, elevation models, 3D buildings | STAC 0.9 |
| **WMTS** | National maps, aerial images, zoning maps | URL builder |
| **OEREB Cadastre** | Public-law restrictions, parcels | REST/JSON (cantonal) |
| **geodienste.ch** | Interkantonale Basisgeodaten (cadastral survey, contaminated sites, hazard maps, …) | OGC API Features / WMS / WFS |
| **OpenStreetMap** | Points of interest (schools, playgrounds, pharmacies, …) | Overpass API (ODbL) |
| **OpenPLZ API** | Administrative address level: postal codes → commune (**BFS number**) → district → canton | REST/JSON (BFS + swisstopo OGD) |
**Anchor demo query:** *"Which communes are in the Uster district, and what are their BFS numbers for joining with BFS statistics data?"*
(The BFS commune number is the official join key to [`swiss-statistics-mcp`](https://github.com/malkreide) and [`zurich-opendata-mcp`](https://github.com/malkreide/zurich-opendata-mcp) — this is what turns a geodata wrapper into a semantic connector at the commune level.)
[→ More use cases by audience →](EXAMPLES.md)
### Demo

---
## Features
- 🗺️ **20 tools** (REST, Geocoding, Height, STAC, WMTS, OEREB, geodienste.ch, OpenStreetMap/Overpass, OpenPLZ)
- 🏛️ Resolve the administrative address level (PLZ → commune/**BFS number** → district → canton) via OpenPLZ
- 🔍 Geocode Swiss addresses and reverse-geocode coordinates
- 🏔️ Query elevation and compute elevation profiles
- 📦 Discover and download geodatasets (orthophotos, 3D buildings, historical maps)
- 🏗️ Identify map features at coordinates across 500+ Swisstopo layers
- 🔗 Generate shareable map.geo.admin.ch links
- 📋 Look up cadastral property IDs (EGRID) and retrieve OEREB extracts
- 🔓 **No API key required** for all tools (OEREB extract needs a supported canton)
- ☁️ **Dual transport** -- stdio (Claude Desktop) + Streamable HTTP (cloud)
---
## Prerequisites
- Python 3.11+
- [uv](https://github.com/astral-sh/uv) (recommended) or pip
---
## Installation
```bash
# Clone the repository
git clone https://github.com/malkreide/swisstopo-mcp.git
cd swisstopo-mcp
# Install
pip install -e .
# or with uv:
uv pip install -e .
```
Or with `uvx` (no permanent installation):
```bash
uvx swisstopo-mcp
```
---
## Quickstart
```bash
# stdio (for Claude Desktop)
python -m swisstopo_mcp.server
# Streamable HTTP (port 8000)
python -m swisstopo_mcp.server --http --port 8000
```
Try it immediately in Claude Desktop:
> *"Where is Bahnhofstrasse 1, Zurich? Give me the coordinates."*
> *"What is the elevation at the Uetliberg summit?"*
> *"What buildings are at coordinates 2683500, 1247500 (LV95)?"*
---
## Configuration
### Claude Desktop
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
```json
{
"mcpServers": {
"swisstopo": {
"command": "python",
"args": ["-m", "swisstopo_mcp.server"]
}
}
}
```
Or with `uvx`:
```json
{
"mcpServers": {
"swisstopo": {
"command": "uvx",
"args": ["swisstopo-mcp"]
}
}
}
```
**Config file locations:**
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
### Cloud Deployment (SSE for browser access)
For use via **claude.ai in the browser** (e.g. on managed workstations without local software):
**Render.com (recommended):**
1. Push/fork the repository to GitHub
2. On [render.com](https://render.com): New Web Service -> connect GitHub repo
3. Set start command: `python -m swisstopo_mcp.server --http --port 8000`
4. In claude.ai under Settings -> MCP Servers, add: `https://your-app.onrender.com/sse`
---
## Available Tools
### REST API (Layer & Feature Queries)
| Tool | Description |
|------|-------------|
| `swisstopo_map_query` | The national map catalogue (api3.geo.admin.ch). One `operation` per call — see the five below |
| `swisstopo_zoning_at` | Harmonised building zone at a coordinate — one call, no layer lookup (not legally binding) |
| `swisstopo_municipality_at` | Municipality, canton and official BFS number at a coordinate |
#### `swisstopo_map_query` operations
| `operation` | Answers | Required arguments |
|-------------|---------|--------------------|
| `search_layers` | Which layers exist for a keyword? (500+ catalogue) | `query` |
| `layer_info` | What fields can I query on this layer, and what is its legend? | `layer` |
| `features_at_point` | What is at this coordinate? | `layers` + a point (`lat`/`lon` **or** `easting`/`northing`) |
| `features_by_attribute` | Which features carry this value? (e.g. buildings by EGID) | `layer`, `search_field`, `search_text` |
| `feature_by_id` | Give me this one feature in full, with geometry | `layer`, `feature_id` |
Arguments belonging to a different operation are **rejected, not ignored** — the
error names the ones the chosen operation accepts. Silently dropping a
misplaced `search_field` would return a plausible answer to a question nobody
asked, which is the failure mode the whole envelope design is against.
### Geocoding
| Tool | Description |
|------|-------------|
| `swisstopo_geocode` | Convert Swiss addresses, place names, or postal codes to coordinates |
| `swisstopo_reverse_geocode` | Find the nearest address for given coordinates |
### Height Service
| Tool | Description |
|------|-------------|
| `swisstopo_get_height` | Get elevation above sea level (m a.s.l.) at a coordinate |
| `swisstopo_elevation_profile` | Compute an elevation profile along a line |
| `swisstopo_convert_coordinates` | Official WGS84 ↔ LV95 conversion via the swisstopo REFRAME service |
### STAC Catalog (Geodata Downloads)
| Tool | Description |
|------|-------------|
| `swisstopo_search_geodata` | Search the STAC catalog for downloadable geodatasets |
| `swisstopo_get_collection` | Get details and download links for a STAC collection |
### WMTS (Map URLs)
| Tool | Description |
|------|-------------|
| `swisstopo_map_url` | Generate a map.geo.admin.ch URL for browser display |
### OEREB Cadastre
| Tool | Description |
|------|-------------|
| `swisstopo_get_egrid` | Resolve a cadastral property ID (EGRID) from coordinates |
| `swisstopo_get_oereb_extract` | Retrieve public-law land-use restrictions (OEREB) for a parcel |
### Consolidated Geodata Façade
One façade over several map/layer sources, kept under the 25-tool budget (see
[`docs/geodaten-erweiterung-phase1.md`](docs/geodaten-erweiterung-phase1.md)):
| Tool | Description |
|------|-------------|
| `swisstopo_list_available_layers` | Discover layer keys for `swisstopo_query_geodata` (`strassenverzeichnis`, `oereb-verfuegbarkeit`, `geodienste:<topic>:<canton>`); filters to contract-free geodienste datasets |
| `swisstopo_query_geodata` | Query a chosen layer by `point` / `bbox` / `commune` — amtliches Strassenverzeichnis, interkantonale geodienste.ch data (OGC API Features), or ÖREB availability |
| `swisstopo_query_osm_features` | OpenStreetMap POIs (schools, playgrounds, pharmacies, …) around a point via Overpass — separate source, ODbL (© OpenStreetMap contributors) |
### Administrative Address Level (OpenPLZ)
The amtliche address hierarchy **PLZ → commune → district → canton**, served by
the [OpenPLZ API](https://openplzapi.org) (data: BFS municipal directory +
swisstopo street directory, Swiss OGD — a **separate source and licence** from
the swisstopo geodata above). Every commune-bearing response exposes
`bfs_commune_number` as a named top-level field: the official **join key** to
BFS statistics (`swiss-statistics-mcp`) and `zurich-opendata-mcp`.
| Tool | Description |
|------|-------------|
| `swisstopo_lookup_postal_code` | Resolve a Swiss postal code → locality, commune (+**BFS number**), district, canton |
| `swisstopo_find_commune` | Resolve a commune both directions (`name` ↔ `bfs_number`) or list all communes of a `canton` / `district`. Accepts canton abbreviation (`ZH`) or key (`1`); resolution happens server-side |
| `swisstopo_search_address` | Full-text search over Swiss streets and localities, returning commune + BFS number per hit |
### Example Use Cases
| Query | Tool |
|-------|------|
| *"Where is Bahnhofstrasse 1, Zurich?"* | `swisstopo_geocode` |
| *"What is the elevation at the Uetliberg summit?"* | `swisstopo_get_height` |
| *"What buildings are at coordinates 2683500, 1247500?"* | `swisstopo_map_query` (`operation='features_at_point'`) |
| *"Find orthophoto datasets for download"* | `swisstopo_search_geodata` What people ask about swisstopo-mcp
What is malkreide/swisstopo-mcp?
+
malkreide/swisstopo-mcp is mcp servers for the Claude AI ecosystem. MCP server for Swiss federal geodata (Swisstopo APIs) — 13 tools for geocoding, height, STAC, WMTS, ÖREB and more It has 4 GitHub stars and was last updated today.
How do I install swisstopo-mcp?
+
You can install swisstopo-mcp by cloning the repository (https://github.com/malkreide/swisstopo-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is malkreide/swisstopo-mcp safe to use?
+
Our security agent has analyzed malkreide/swisstopo-mcp and assigned a Trust Score of 87/100 (tier: Trusted). See the full breakdown of passed checks and flags on this page.
Who maintains malkreide/swisstopo-mcp?
+
malkreide/swisstopo-mcp is maintained by malkreide. The last recorded GitHub activity is from today, with 0 open issues.
Are there alternatives to swisstopo-mcp?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy swisstopo-mcp to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/malkreide-swisstopo-mcp)<a href="https://claudewave.com/repo/malkreide-swisstopo-mcp"><img src="https://claudewave.com/api/badge/malkreide-swisstopo-mcp" alt="Featured on ClaudeWave: malkreide/swisstopo-mcp" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!