Back to Discover

bakom-mcp

connector

malkreide

BAKOM telecommunications and media open data

View on GitHub
0 starsSynced Aug 14, 2026

Install to Claude Code

/plugin marketplace add malkreide/bakom-mcp

README

๐Ÿ‡จ๐Ÿ‡ญ Part of the Swiss Public Data MCP Portfolio

๐Ÿ“ก bakom-mcp

Version License: MIT Python 3.11+ MCP Auth CI

MCP server for BAKOM open data โ€“ broadband, mobile coverage, media and Swiss telecom statistics.

๐Ÿ‡ฉ๐Ÿ‡ช Deutsche Version

Demo: Claude queries fibre and 5G coverage via MCP tool call


Overview

bakom-mcp connects AI assistants like Claude to the Swiss Federal Office of Communications (BAKOM) open data infrastructure. It enables natural-language queries about broadband availability, 5G/4G coverage, mobile antenna locations, BAKOM datasets on radio and television, and telecommunications statistics โ€” all without API keys.

All data is published as Open Government Data (OGD) on opendata.swiss / geo.admin.ch under CC BY 4.0 โ€” see the Data Licence section below for attribution requirements.

Anchor demo query: "Which school buildings in district 7 do not yet have fibre optic connectivity?"

bakom_multi_standort_konnektivitaet delivers the comparison table automatically.

โ†’ More use cases by audience โ†’


Scope

What this server does

โœ“ Read-only queries against three public BAKOM/Confederation APIs:

  • api3.geo.admin.ch / wms.geo.admin.ch (broadband, mobile coverage, antennas)
  • ckan.opendata.swiss (telecom statistics, dataset metadata)

โœ“ Returns aggregated, anonymous data โ€” no personal data, no household-level identification.

โœ“ Bound to Swiss WGS84 coordinates (lat 45.8โ€“47.9, lon 5.9โ€“10.6) via Pydantic input validation.

โœ“ Egress is locked to a code-layer allow-list of the six known data-source hosts.

What this server does not

โœ— Send data anywhere (read-only, no write tools).

โœ— Access the local filesystem (no path-traversal surface).

โœ— Use authentication tokens (none required โ€” all sources are public OGD).

โœ— Cache or persist user inputs across calls.

โœ— Execute shell commands or arbitrary code (no subprocess/os.system/eval).


Features

  • ๐Ÿ“ถ Broadband availability โ€“ Fixed-line coverage at 30/100/300/500/1000 Mbit/s (250ร—250m grid)
  • ๐Ÿ”Œ Fibre status โ€“ FTTB/FTTH availability per location
  • ๐Ÿ“ Multi-location comparison โ€“ Connectivity check for up to 20 locations simultaneously
  • ๐Ÿ“ฑ Mobile coverage โ€“ 5G/4G/3G outdoor coverage (100ร—100m grid)
  • ๐Ÿ“ก Antenna search โ€“ Mobile and broadcast transmitters within a configurable radius
  • ๐Ÿ“บ Radio & TV datasets โ€“ Full-text search across BAKOM's radio and television datasets on opendata.swiss
  • ๐Ÿ—ž๏ธ Media landscape โ€“ BAKOM media structure reports and datasets
  • ๐Ÿ“Š Telecom statistics โ€“ Fixed-line, mobile, broadband market data via opendata.swiss
  • ๐Ÿ—‚๏ธ Broadband Atlas catalogue โ€“ All BAKOM dataset layers with direct API links
  • ๐Ÿ”“ No authentication required โ€“ All data is Open Government Data (OGD)

Prerequisites

  • Python 3.11+
  • uv or pip for installation
  • Internet connection (live APIs: geo.admin.ch, opendata.swiss)

Installation

# Recommended: uvx (no permanent installation required)
uvx bakom-mcp

# Or install with pip
pip install bakom-mcp

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

Quickstart

Claude Desktop

Add to claude_desktop_config.json:

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

Config file locations:

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

Cloud / HTTP Transport

python -m bakom_mcp.server --http
# Server running at http://localhost:8050/mcp

Configuration via environment variables (see .env.example):

VariableDefaultPurpose
BAKOM_MCP_HOST127.0.0.1Bind address. Set to 0.0.0.0 only on trusted networks (warning logged).
BAKOM_MCP_PORT8050TCP port.
BAKOM_MCP_CORS_ORIGINS(empty)Comma-separated allowed origins for browser clients. Empty = CORS disabled.

Docker

A hardened container image is provided. Suitable for cloud deployments behind a reverse proxy (Caddy, Traefik, nginx).

# Build & run via compose (recommended)
docker compose up --build

# Or via docker run
docker build -t bakom-mcp:latest .
docker run --rm \
  --read-only \
  --cap-drop=ALL \
  --security-opt=no-new-privileges \
  --tmpfs /tmp:rw,size=16M \
  -p 127.0.0.1:8050:8050 \
  bakom-mcp:latest

The image runs as non-root (UID 10001), uses a read-only filesystem, drops all Linux capabilities and refuses privilege escalation. Resource limits are configured in docker-compose.yml (256 MB memory, 0.5 CPU, 64 PIDs). The default port mapping binds to 127.0.0.1 only โ€” for public exposure, terminate TLS and CORS at a reverse proxy.

Cursor / VS Code / LibreChat

{
  "bakom": {
    "command": "uvx",
    "args": ["bakom-mcp"],
    "transport": "stdio"
  }
}

๐Ÿ’ก "stdio for the developer laptop, HTTP/SSE for the browser."


Available Tools (12)

Broadband & Connectivity

ToolDescription
bakom_broadband_coverageFixed-line coverage at a coordinate (30โ€“1000 Mbit/s)
bakom_glasfaser_verfuegbarkeitFTTB/FTTH fibre availability
bakom_multi_standort_konnektivitaetConnectivity comparison for up to 20 locations

Mobile & Transmitters

ToolDescription
bakom_mobilfunk_abdeckung5G/4G/3G outdoor coverage
bakom_sendeanlagen_sucheMobile antennas within a configurable radius
bakom_frequenzdatenRadio/TV transmitter sites near a location

Media & RTV

ToolDescription
bakom_rtv_sucheSearch BAKOM radio/TV datasets on opendata.swiss
bakom_medienstruktur_infoSwiss media landscape datasets
bakom_aktuellRecently updated BAKOM datasets on a topic (catalogue, not press releases)
bakom_medien_statistikMarket shares, reach and programme structure from the BAKOM cubes on LINDAS

Statistics & Catalogue

ToolDescription
bakom_telekomstatistik_uebersichtTelecom statistics from opendata.swiss
bakom_breitbandatlas_datensaetzeFull catalogue of Broadband Atlas layers
bakom_check_api_status๐Ÿ” Health check for all configured data sources

Example Prompts

What is the broadband situation at Schulhaus Leutschenbach (47.4148, 8.5654)?

Compare 5G and fibre coverage for these three school buildings: [coordinates]

Which radio stations are licensed in canton Zurich?

Show me the current BAKOM position on 5G frequency allocation.

List all Broadband Atlas datasets available via geo.admin.ch.

Safety & Limits

AspectDetails
AccessRead-only (readOnlyHint: true) โ€” the server cannot modify or delete any data
Personal dataNo personal data โ€” all sources are aggregated, public open data
Rate limitsBuilt-in per-query caps (max 50 antennas, max 20 locations, max 50 RTV results)
Timeout20 seconds per API call
AuthenticationNo API keys required โ€” all 3 APIs are publicly accessible
LicencesAll data under CC0 / open licences (Open Government Data)
Terms of ServiceSubject to ToS of the respective data sources: geo.admin.ch, opendata.swiss

Data Sources

SourceDataAuthentication
geo.admin.chBroadband Atlas, mobile coverage, antenna locationsNone
opendata.swissBAKOM datasets, telecom statisticsNone
lindas.admin.chBAKOM media statistics cubes (SPARQL)None

All data is published under open licences (CC0 / OGD).

Architecture decision โ€” media statistics

bakom_medien_statistik uses Architecture A (live API only), verified live on 2026-08-13:

  • The SPARQL endpoint is https://lindas.admin.ch/query; the /sparql path documented elsewhere returns 404.
  • The OFCOM cubes live in the named graph https://lindas.admin.ch/ofcom/cube. Without an explicit FROM, a query hits the default graph and sees 2010 cubes from every federal office instead of 540.
  • A bulk download exists for only 137 of 540 cubes, so a dump-first architecture would cover a quarter of the data.
  • An unknown graph answers HTTP 200 with zero rows โ€” a silent empty, not an error. Requests carry retry with exponential backoff; egress-policy violations are not retried.

Scope, stated in the tool description because the README does not reach the model: the cubes cover the programmes that were surveyed, not the full inventory. LINDAS's own count cube reports 199+39+17 radio programmes for 2020, while the Programm dimension across all cubes exposes 128 labels โ€” some of which are the same station spelled differently (Energy BE / Energy Bern), plus Durchschnitt, which is an aggregate rather than a station. This tool is a statistics source, not a broadcaster register; licensed broadcasters are listed in the RTV database, which offers no machine-readable interface.


Synergies with the MCP Portfolio

bakom-mcp can be combined with other servers in the portfolio for multi-dimensional queries:

zurich-opendata-mcp  โ†’  school building addresses
         +
    bakom-mcp         โ†’  fibre and 5G status
         =
"Digital equity" dashboard for all school districts

Further combinations:

  • srgssr-mcp + bakom-mcp โ†’ Media coverage and broadcast network
  • swiss-statistics-mcp + bakom-mcp โ†’ Telecom market development
  • fedlex-mcp + bakom-mcp โ†’ Regulatory context (RTVG, FMG)

Project Structure

bakom-mcp/
โ”œโ”€โ”€ src/bakom_mcp/
โ”‚   โ”œโ”€โ”€ __init__.py          # Package
โ”‚   โ”œโ”€โ”€ server.py            # MCP server (12 tools, 2 resources)
โ”‚   โ””โ”€โ”€ py.typed             # PEP 561 type marker
โ”œโ”€โ”€ tests/
โ”‚   โ””โ”€โ”€ test_integration.py  # Integration tests (live APIs)
โ”œโ”€โ”€ assets/
โ”‚   โ””โ”€โ”€ demo.svg             # Demo flow diagram
โ”œโ”€โ”€ .github/workflows/
โ”‚   โ”œโ”€โ”€ ci.yml               # CI: lint, syntax, import, tests
โ”‚   โ””โ”€โ”€ publish.yml          # PyPI publish on release
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ pyproject.toml           # Build config (hatchling)
โ”œโ”€โ”€ CHANGELOG.md
โ”œโ”€โ”€ CONTRIBUTING.md          # Contribution guide (English)
โ”œโ”€โ”€ CONTRIBUTING.de.md       # Contribution guide (German)
โ”œโ”€โ”€ SECURITY.md              # Security policy (English)
โ”œโ”€โ”€ SECURITY.de.md           # Security policy (German)
โ”œโ”€โ”€ LICENSE                  # MIT License
โ”œโ”€โ”€ README.md                # This file (English)
โ””โ”€โ”€ README.de.md             # German version

Testing

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

# Integration tests (live APIs, internet required)
PYTHONPATH=src pytest tests/ -m "live"

Changelog

See CHANGELOG.md


Contributing

Contributions are welcome! See CONTRIBUTING.md (๐Ÿ‡ฉ๐Ÿ‡ช Deutsch) for guidelines on reporting bugs, suggesting features, and submitting pull requests.


Security

To report a vulnerability, see the Security Policy (๐Ÿ‡ฉ๐Ÿ‡ช Deutsch). Please report security issues privately via GitHub Security Advisories rather than public issues.


Software Licence

MIT License โ€” see LICENSE.

Data Licence

The BAKOM open data delivered through this server is published under CC BY 4.0. When using or redistributing tool outputs, attribute the source as:

Source: Federal Office of Communications (BAKOM) via opendata.swiss / geo.admin.ch ยท Licence: CC BY 4.0

Tool outputs already include this footer automatically. The Markdown response format ends with the attribution line; downstream applications that consume the JSON format should propagate the source/licence metadata to their end users.


Author

Hayal Oezkan ยท github.com/malkreide


Credits & Related Projects


Part of the Swiss Open Data MCP portfolio โ€” public data deserves public interfaces.

Installation

Run via uv's uvx โ€” no clone or manual install needed. Add to your MCP client config (mcpServers for Claude Desktop, Cursor and Windsurf; use a top-level servers key for VS Code in .vscode/mcp.json):

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

Rendered live from malkreide/bakom-mcp's GitHub README โ€” not stored, always reflects the source repo.

1 Install Method

NameDescriptionCategorySource
pypi packageInstall via pypi (stdio transport)mcp-serverbakom-mcp

0 Comments

Login required
Log in to post a comment or update on this repo.

No comments yet โ€” be the first to share an update.