loading…
Search for a command to run...
loading…
MCP server connecting AI models to SRG SSR public APIs – weather, TV/radio metadata, program guide and Swiss votations/elections since 1900.
MCP server connecting AI models to SRG SSR public APIs – weather, TV/radio metadata, program guide and Swiss votations/elections since 1900.
🇨🇭 Part of the Swiss Public Data MCP Portfolio
License: MIT
Python 3.11+
MCP
CI
Data Source
MCP server connecting AI models to SRG SSR public APIs – weather, TV/radio metadata, program guide and Swiss votations/elections since 1900 (SRF, RTS, RSI, RTR, SWI).
srgssr-mcp gives AI assistants like Claude direct access to the public APIs of SRG SSR – Switzerland's national public broadcaster. Weather forecasts, TV and radio metadata, electronic program guides, and historical democratic data (votations and elections since 1900) are all accessible through a single standardised MCP interface.
The server covers five thematic clusters: SRF Weather, Video, Audio, EPG and Polis (Swiss Democracy). Each cluster maps to a group of purpose-built tools that translate raw SRG SSR API data into clean JSON responses.
Anchor demo query: "What were the cantonal results of the popular vote on initiative X in Zurich?" – answered with historical real-time data from the Polis system, not a hallucination.
⚠️ Terms of use: SRG SSR APIs are available for non-commercial use. For commercial use, contact [email protected] directly.
# Clone the repository
git clone https://github.com/malkreide/srgssr-mcp.git
cd srgssr-mcp
# Install
pip install -e .
Or with uvx (no permanent installation):
uvx srgssr-mcp
Or via pip:
pip install srgssr-mcp
# Set credentials
export SRGSSR_CONSUMER_KEY="your-consumer-key"
export SRGSSR_CONSUMER_SECRET="your-consumer-secret"
# Start the server (stdio mode for Claude Desktop)
srgssr-mcp
Try it immediately in Claude Desktop:
"What will the weather be like in Zurich tomorrow?" "What's on SRF 1 tonight?" "Which popular votes took place in the canton of Bern between 2010 and 2020?"
Minimal (recommended):
{
"mcpServers": {
"srgssr": {
"command": "uvx",
"args": ["srgssr-mcp"],
"env": {
"SRGSSR_CONSUMER_KEY": "your-consumer-key",
"SRGSSR_CONSUMER_SECRET": "your-consumer-secret"
}
}
}
}
Config file locations:
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.jsonAfter saving, restart Claude Desktop completely.
Compatible with Cursor, Windsurf, VS Code + Continue, LibreChat, Cline, and self-hosted models via mcp-proxy. Set the same environment variables.
For use via claude.ai in the browser (e.g. on managed workstations without local software):
SRGSSR_CONSUMER_KEY=... \
SRGSSR_CONSUMER_SECRET=... \
SRGSSR_MCP_TRANSPORT=streamable-http \
SRGSSR_MCP_HOST=0.0.0.0 \
SRGSSR_MCP_PORT=8000 \
python -m srgssr_mcp.server
Transport, host, port and mount path are all driven by environment variables
(see srgssr_mcp.server.Settings). Valid values for SRGSSR_MCP_TRANSPORT
are stdio (default), sse, and streamable-http.
💡 "stdio for the developer laptop, SSE for the browser."
This server exposes all three orthogonal MCP primitives:
| Primitive | Mental model | What's here |
|---|---|---|
| Tools (verbs) | Executable functions / parametrized queries | 15 tools — search, list, fetch, aggregate |
| Resources (nouns) | Cache-friendly passive data behind URIs | EPG entries and immutable votation results |
| Prompts (recipes) | Reusable workflow templates | Voting analysis & daily briefing |
Tools cover parametrized searches (year ranges, free-text, paginated listings) where every call may yield different results. Resources expose stable data points that are safe to cache: a published EPG for a given channel/date, or the final result of a closed Swiss votation. Prompts standardise recurring multi-step analyses so users don't have to phrase them from scratch.
| URI template | Description |
|---|---|
epg://{bu}/{channel_id}/{date} |
Daily TV/radio program guide for SRF, RTS, RSI (e.g. epg://srf/srf1/2026-04-30) |
votation://{votation_id} |
Detailed result of a closed Swiss popular vote (e.g. votation://v1) |
| Name | Arguments | Purpose |
|---|---|---|
analyse_abstimmungsverhalten |
votation_id, focus (stadt_land / sprachregionen / kantone) |
Structured analysis of a Swiss popular vote |
tagesbriefing_kanton |
location, channel_id, business_unit, date |
Daily briefing combining weather and EPG |
This server uses snake_case for tool names, following Python ecosystem idioms. While MCP best practice favors camelCase for optimal LLM tokenization, snake_case remains acceptable and keeps tool names aligned with the underlying Python function identifiers.
All tools follow the pattern srgssr_<domain>_<action> with the namespace prefix srgssr_ and a semantically meaningful <domain>_<action> suffix (e.g. srgssr_weather_current, srgssr_polis_get_votations).
| Tool | Description | Data Source |
|---|---|---|
srgssr_weather_search_location |
Search for a location by name or postal code to obtain a geolocationId |
SRF Meteo |
srgssr_weather_current |
Current weather conditions for a Swiss location | SRF Meteo |
srgssr_weather_forecast_24h |
Hourly 24-hour forecast | SRF Meteo |
srgssr_weather_forecast_7day |
Daily 7-day forecast | SRF Meteo |
| Tool | Description | Data Source |
|---|---|---|
srgssr_video_get_shows |
List TV shows for a business unit | SRG SSR IL |
srgssr_video_get_episodes |
Retrieve latest episodes of a show | SRG SSR IL |
srgssr_video_get_livestreams |
List live TV channels | SRG SSR IL |
| Tool | Description | Data Source |
|---|---|---|
srgssr_audio_get_shows |
List radio shows for a business unit | SRG SSR IL |
srgssr_audio_get_episodes |
Retrieve audio episodes of a show | SRG SSR IL |
srgssr_audio_get_livestreams |
List live radio stations | SRG SSR IL |
| Tool | Description | Data Source |
|---|---|---|
srgssr_epg_get_programs |
Daily program schedule for a TV or radio channel | SRG SSR IL |
| Tool | Description | Data Source |
|---|---|---|
srgssr_polis_get_votations |
Popular votes since 1900 (national or cantonal) | Polis API |
srgssr_polis_get_votation_results |
Detailed results of a specific vote | Polis API |
srgssr_polis_get_elections |
Election results since 1900 | Polis API |
| Code | Unit | Language |
|---|---|---|
srf |
SRF (Schweizer Radio und Fernsehen) | German |
rts |
RTS (Radio Télévision Suisse) | French |
rsi |
RSI (Radiotelevisione svizzera) | Italian |
rtr |
RTR (Radiotelevisiun Svizra Rumantscha) | Romansh |
swi |
SWI swissinfo.ch | Multilingual |
| Query | Tool |
|---|---|
| "Weather in Zurich tomorrow?" | srgssr_weather_forecast_24h |
| "What's on SRF 1 tonight?" | srgssr_epg_get_programs |
| "Latest Tagesschau episodes?" | srgssr_video_get_episodes |
| "Popular votes in Canton Bern 2010–2020?" | srgssr_polis_get_votations |
| "Cantonal results of the mask initiative vote?" | srgssr_polis_get_votation_results |
| "All current RTS radio shows?" | srgssr_audio_get_shows |
→ More use cases by audience →
┌─────────────┐
│ Claude / LLM│
└──────┬──────┘
│ MCP (stdio)
┌──────▼───────────────────┐
│ srgssr-mcp Server │
│ ├─ Weather Tools (4) │
│ ├─ EPG Tools (1) │
│ ├─ Polis Tools (3) │
│ ├─ Video Tools (3) │
│ └─ Audio Tools (3) │
└──────┬───────────────────┘
│ HTTPS (OAuth2)
┌──────▼──────────────┐
│ SRG SSR Public APIs │
│ developer.srgssr.ch│
└─────────────────────┘
| Source | Data | Access |
|---|---|---|
| developer.srgssr.ch | SRG SSR PUBLIC API V2 (weather, A/V, EPG, Polis) | OAuth2 (free registration) |
Attribution: SRG SSR APIs are subject to the SRG SSR Terms of Use.
This server is in Phase 1: Read-only Wrapper.
The server exposes only GET-style operations against public SRG SSR APIs. There are no write, mutate or delete capabilities by design — see Safety & Limits for the threat-model implications.
swiss-statistics-mcp or swiss-transport-mcp).This server is built and tested against MCP protocol version 2025-06-18.
The version is pinned explicitly as PROTOCOL_VERSION in src/srgssr_mcp/_app.py and validated at import time against the installed SDK's SUPPORTED_PROTOCOL_VERSIONS — a fastmcp/mcp upgrade that drops support for the pinned revision will fail fast at startup instead of silently changing wire-level behaviour. Bumps are tracked in CHANGELOG.md under the matching release.
.github/dependabot.yml, monthly cadence, grouped under the mcp-sdk label) and run the full test suite before merge.CHANGELOG.md and, if it changes the externally observable wire contract, triggers a minor or major release per Semantic Versioning.srgssr-mcp/
├── src/srgssr_mcp/
│ ├── __init__.py # Package
│ └── server.py # FastMCP server: 14 tools, OAuth2 client
├── .github/
│ └── workflows/
│ └── ci.yml # GitHub Actions CI (Python 3.11–3.13)
├── pyproject.toml # Build configuration (hatchling)
├── CHANGELOG.md
├── CONTRIBUTING.md # English
├── CONTRIBUTING.de.md # German
├── LICENSE # MIT
├── README.md # This file (English)
└── README.de.md # German version
| Aspect | Details |
|---|---|
| Access | Read-only — the server only reads from SRG SSR APIs and cannot post, modify or delete any content |
| Personal data | No personal data — all endpoints serve public broadcast metadata, weather observations and historical votation/election results |
| Rate limits | Subject to the tier of your OAuth2 application on developer.srgssr.ch; the server adds sensible per-query caps (e.g. max 100 episodes, 50 shows per list call) |
| Timeout | 30 seconds per upstream API call |
| Authentication | OAuth2 Client Credentials (free registration); secrets stay local, never logged |
| Licensing & use | SRG SSR APIs are for non-commercial use; commercial use requires written permission from [email protected] |
| Terms of Service | Subject to the SRG SSR Developer Terms of Use — users remain responsible for attribution and compliance |
The server implements a code-layer egress allowlist (SEC-021, combined with SEC-004 SSRF defense) to prevent unintended external requests. Every outbound HTTP request is validated by _validate_url_safe() in src/srgssr_mcp/_http.py before it is issued.
Three controls per request:
http://, file://, ftp:// and other non-HTTPS schemes are rejected.ALLOWED_HOSTS = {"api.srgssr.ch"} (exact match — subdomain tricks like api.srgssr.ch.attacker.example are blocked).169.254.169.254 cloud-metadata), CGNAT, multicast and reserved ranges (IPv4 + IPv6). Any single match aborts the request — defense-in-depth against DNS rebinding.Violations surface as ValueError and are mapped to a localized Konfigurationsfehler: … message by _handle_error, so internal network details never leak to the MCP client.
Adding a new SRG SSR domain:
ALLOWED_HOSTS in src/srgssr_mcp/_http.py.CHANGELOG.md.tests/test_unit.py (mirror test_validate_url_safe_accepts_public_srgssr_host).Network-Layer Egress (for future SSE/HTTP deployments): see docs/network-egress.md. For the current stdio transport, network-layer controls do not apply — the process runs in the MCP client's user context.
The server uses structured logging (OBS-003) via structlog with JSON output to stderr — keeping stdout clean for the stdio transport's JSON-RPC traffic.
Format:
timestamp on every recorddebug, info, notice, warning, error, critical, alert, emergencytool, business_unit, channel_id, query, etc.Example output:
{"event": "tool_invoked", "tool": "srgssr_weather_search_location", "query": "Bern", "level": "info", "logger": "mcp.srgssr.weather", "timestamp": "2026-04-30T14:23:45.123Z"}
{"event": "tool_succeeded", "tool": "srgssr_weather_search_location", "query": "Bern", "result_count": 3, "matched_variant": "Bern", "level": "info", "logger": "mcp.srgssr.weather", "timestamp": "2026-04-30T14:23:45.456Z"}
Log levels (RFC 5424):
| Level | Used for |
|---|---|
debug |
OAuth token cache hits, internal state |
info |
Tool invocations, successful responses, server lifecycle |
warning |
Recoverable conditions (rate-limit approaching, unsupported business unit) |
error |
API failures, timeouts (recoverable) |
critical |
Credential issues, service degradation |
Configuration:
The default level is info. Override via the SRGSSR_LOG_LEVEL environment variable (debug, info, warning, error, critical):
SRGSSR_LOG_LEVEL=debug srgssr-mcp
JSON output is aggregator-friendly — pipe stderr to Datadog, Splunk, Loki, etc., and filter by structured fields (tool, business_unit, level) without regex parsing.
# Unit tests (no network required)
PYTHONPATH=src pytest tests/ -m "not live"
# Integration tests (requires SRG SSR API keys)
PYTHONPATH=src pytest tests/ -m "live"
# Linting
ruff check src/
See CONTRIBUTING.md
See CHANGELOG.md
All data exposed by this server is fetched live from a single upstream
provider, SRG SSR Public API V2 (https://api.srgssr.ch). Every tool
return is a typed Pydantic BaseModel that
embeds source / license / provenance_url / fetched_at at the top
level — so downstream consumers can record the data origin without
round-tripping through this README. FastMCP exposes the corresponding
outputSchema in the tools/list manifest so MCP clients can plan
follow-up calls precisely.
| Cluster | Provider | License | Notes |
|---|---|---|---|
| Weather | SRF Meteo (api.srgssr.ch) | SRG SSR Terms of Use | Geo-restricted to Switzerland |
| Video / Audio / EPG | SRF · RTS · RSI · RTR · SWI | SRG SSR Terms of Use | Metadata only — stream URLs are not redistributed |
| Polis (Votations / Elections) | SRG SSR Polis | SRG SSR Terms of Use | Historical data since 1900 |
Use of the SRG SSR APIs
This server's MIT license covers the source code only; it does not relicense the upstream data.
MIT License — see LICENSE
The SRG SSR APIs used in this project are subject to the SRG SSR Terms of Use.
Hayal Oezkan · github.com/malkreide
| Server | Description |
|---|---|
| zurich-opendata-mcp | City of Zurich open data (OSTLUFT air quality, weather, parking, geodata) |
| swiss-transport-mcp | Swiss public transport – OJP 2.0 journey planning, SIRI-SX disruptions |
| swiss-environment-mcp | BAFU environmental data – air quality, hydrology, natural hazards |
| swiss-statistics-mcp | BFS STAT-TAB – 682 statistical datasets |
| fedlex-mcp | Swiss federal law via Fedlex SPARQL |
Synergy example: "What were the results of the 2020 popular votes in Canton Zurich – and how did turnout compare to the national average?"
→ srgssr-mcp (Polis, cantonal results) + swiss-statistics-mcp (BFS, turnout data)
Выполни в терминале:
claude mcp add srgssr-mcp -- npx Web content fetching and conversion for efficient LLM usage.
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
автор: modelcontextprotocolProvides auto-configuration for setting up an MCP server in Spring Boot applications.
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also
автор: xuzexin-hzНе уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории ai