srgssr-mcp
The srgssr-mcp server connects AI assistants to SRG SSR (Switzerland's national public broadcaster) public APIs, providing read-only access to Swiss weather, TV/radio metadata, program guides, and historical democratic data.
π¦οΈ Weather (SRF Meteo, Switzerland only)
Search locations by name or postal code
Get current conditions (temperature, wind, precipitation, humidity)
24-hour hourly forecast and 7-day daily forecast
πΊ Video / TV
List TV shows, fetch latest episodes, and get live TV channels for any SRG SSR business unit (SRF, RTS, RSI, RTR, SWI)
ποΈ Audio / Radio
List radio shows/podcasts, fetch latest episodes, and get live radio stations for any business unit
π EPG (Electronic Program Guide)
Get the full daily program schedule for any SRF, RTS, or RSI TV/radio channel on a specific date
π³οΈ Polis (Swiss Democracy)
Browse popular votes and referenda since 1900 (filterable by year range and canton)
Retrieve detailed results for a specific vote (yes/no shares, turnout, cantonal breakdowns)
Browse election results (National Council, Council of States, cantonal) since 1900
π Daily Briefing
Combined single-call tool aggregating the 24-hour weather forecast and EPG for a specified channel
Key constraints: EPG is only available for SRF, RTS, and RSI (not RTR or SWI). All access is read-only. Requires free OAuth2 credentials from developer.srgssr.ch; commercial use requires written permission.
Allows AI agents to query SRG SSR public APIs for weather forecasts, TV/radio metadata, program guides, and Swiss votation/election results since 1900.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@srgssr-mcpwhat's the weather in Zurich today?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
π¨π Part of the Swiss Public Data MCP Portfolio
πΊ srgssr-mcp
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).
Overview
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.
Related MCP server: swiss-food-safety-mcp
Features
π¦οΈ Weather β location search, current conditions, 24h hourly forecast, 7-day forecast (SRF Meteo)
πΊ Video β TV show listings, latest episodes, live TV channels across all business units
ποΈ Audio β radio show listings, audio episodes, live radio stations
π EPG β daily program schedule for any TV or radio channel
π³οΈ Polis β popular votes and elections since 1900, national and cantonal results
π’ Multi-unit β SRF (DE), RTS (FR), RSI (IT), RTR (RM), SWI (multilingual)
π OAuth2 β automatic token management with Client Credentials flow
βοΈ Dual transport β stdio for Claude Desktop, Streamable HTTP/SSE for cloud deployment
Prerequisites
Python 3.11+
API keys from developer.srgssr.ch (free registration):
Create an account and log in
Under "My Apps", create a new application
Add the product SRG SSR PUBLIC API V2
Note your Consumer Key and Consumer Secret
β οΈ Terms of use: SRG SSR APIs are available for non-commercial use. For commercial use, contact api@srgssr.ch directly.
Installation
# 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-mcpOr via pip:
pip install srgssr-mcpQuickstart
# 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-mcpTry 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?"
Configuration
Claude Desktop
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:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
After saving, restart Claude Desktop completely.
Other MCP Clients
Compatible with Cursor, Windsurf, VS Code + Continue, LibreChat, Cline, and self-hosted models via mcp-proxy. Set the same environment variables.
Cloud Deployment (SSE for browser access)
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.serverTransport, 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."
MCP Primitives
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.
Resources
URI template | Description |
| Daily TV/radio program guide for SRF, RTS, RSI (e.g. |
| Detailed result of a closed Swiss popular vote (e.g. |
Prompts
Name | Arguments | Purpose |
|
| Structured analysis of a Swiss popular vote |
|
| Daily briefing combining weather and EPG |
Available Tools
Tool Naming Convention
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).
π¦οΈ SRF Weather (4 tools)
Tool | Description | Data Source |
| Search for a location by name or postal code to obtain a | SRF Meteo |
| Current weather conditions for a Swiss location | SRF Meteo |
| Hourly 24-hour forecast | SRF Meteo |
| Daily 7-day forecast | SRF Meteo |
πΊ Video (3 tools)
Tool | Description | Data Source |
| List TV shows for a business unit | SRG SSR IL |
| Retrieve latest episodes of a show | SRG SSR IL |
| List live TV channels | SRG SSR IL |
ποΈ Audio (3 tools)
Tool | Description | Data Source |
| List radio shows for a business unit | SRG SSR IL |
| Retrieve audio episodes of a show | SRG SSR IL |
| List live radio stations | SRG SSR IL |
π EPG β Electronic Program Guide (1 tool)
Tool | Description | Data Source |
| Daily program schedule for a TV or radio channel | SRG SSR IL |
π³οΈ Polis β Swiss Democracy (3 tools)
Tool | Description | Data Source |
| Popular votes since 1900 (national or cantonal) | Polis API |
| Detailed results of a specific vote | Polis API |
| Election results since 1900 | Polis API |
Supported Business Units
Code | Unit | Language |
| SRF (Schweizer Radio und Fernsehen) | German |
| RTS (Radio TΓ©lΓ©vision Suisse) | French |
| RSI (Radiotelevisione svizzera) | Italian |
| RTR (Radiotelevisiun Svizra Rumantscha) | Romansh |
| SWI swissinfo.ch | Multilingual |
Example Use Cases
Query | Tool |
"Weather in Zurich tomorrow?" |
|
"What's on SRF 1 tonight?" |
|
"Latest Tagesschau episodes?" |
|
"Popular votes in Canton Bern 2010β2020?" |
|
"Cantonal results of the mask initiative vote?" |
|
"All current RTS radio shows?" |
|
β More use cases by audience β
Architecture
βββββββββββββββ
β 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β
βββββββββββββββββββββββData Sources
Source | Data | Access |
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.
Development Phase
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.
Phase 1 Completion Criteria
14 read-only tools across five thematic clusters (Weather, Video, Audio, EPG, Polis)
OAuth2 Client Credentials authentication with token caching
Bilingual documentation (EN/DE)
Test suite (unit + live) β see OPS-001
Structured logging β see OBS-003 and CHANGELOG
Production-ready error handling (uniform retry/backoff, typed error envelopes)
Future Phases
Phase 2 (Write): Not planned. The SRG SSR Public APIs are read-only by contract; there is no upstream surface to write to.
Phase 3 (Multi-Agent): Evaluation deferred. Will be reconsidered once user feedback indicates concrete multi-agent workflows that this server should orchestrate (e.g. cross-server aggregation with
swiss-statistics-mcporswiss-transport-mcp).
MCP Protocol Version
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.
Update Policy
SDK dependency updates land via Dependabot (
.github/dependabot.yml, monthly cadence, grouped under themcp-sdklabel) and run the full test suite before merge.Spec bumps are evaluated on a feature branch against the relevant MCP SDK release; the official MCP changelog is the source of truth for breaking changes.
A spec-version bump is always documented in
CHANGELOG.mdand, if it changes the externally observable wire contract, triggers a minor or major release per Semantic Versioning.
Project Structure
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
βββ SECURITY.md # Security policy (English)
βββ SECURITY.de.md # Security policy (German)
βββ LICENSE # MIT
βββ README.md # This file (English)
βββ README.de.md # German versionπ‘οΈ Safety & Limits
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 api@srgssr.ch |
Terms of Service | Subject to the SRG SSR Developer Terms of Use β users remain responsible for attribution and compliance |
Known Limits
Rate Limits: SRG SSR APIs enforce rate limits β see developer.srgssr.ch for details on the tier of your OAuth2 application
Data Freshness: EPG data may be delayed by up to 6 hours
Historical Data: Polis data goes back to 1900 β older data is not available
Geo-Restriction: Some streaming APIs are only available within Switzerland
API keys required: SRG SSR APIs require free OAuth2 credentials from developer.srgssr.ch
Non-commercial use: SRG SSR API terms restrict commercial use without explicit permission from api@srgssr.ch
Weather coverage: SRF Meteo covers Switzerland only
Security
For the full security posture, vulnerability reporting process and accepted-risk register, see SECURITY.md (English) Β· SECURITY.de.md (German). The key egress control is summarised below.
Egress Allowlist
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:
HTTPS-only β
http://,file://,ftp://and other non-HTTPS schemes are rejected.Host allowlist β the URL hostname must equal one of
ALLOWED_HOSTS = {"api.srgssr.ch"}(exact match β subdomain tricks likeapi.srgssr.ch.attacker.exampleare blocked).IP blocklist β every resolved IP for the hostname is checked against private, loopback, link-local (incl.
169.254.169.254cloud-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:
Update
ALLOWED_HOSTSinsrc/srgssr_mcp/_http.py.Document the reason in the PR and
CHANGELOG.md.Add a positive test case in
tests/test_unit.py(mirrortest_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.
Logging
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:
JSON-encoded events, one per line
ISO 8601 UTC
timestampon every recordRFC 5424 severity levels:
debug,info,notice,warning,error,critical,alert,emergencyPer-call bound context:
tool,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 |
| OAuth token cache hits, internal state |
| Tool invocations, successful responses, server lifecycle |
| Recoverable conditions (rate-limit approaching, unsupported business unit) |
| API failures, timeouts (recoverable) |
| 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-mcpJSON output is aggregator-friendly β pipe stderr to Datadog, Splunk, Loki, etc., and filter by structured fields (tool, business_unit, level) without regex parsing.
Testing
# 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/Contributing
See CONTRIBUTING.md (English) Β· CONTRIBUTING.de.md (German)
Changelog
See CHANGELOG.md
Data Sources & Licenses
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
Non-commercial use: free, no application required.
Commercial use: written permission required via api@srgssr.ch.
This server's MIT license covers the source code only; it does not relicense the upstream data.
License
MIT License β see LICENSE
The SRG SSR APIs used in this project are subject to the SRG SSR Terms of Use.
Author
Hayal Oezkan Β· github.com/malkreide
Credits & Related Projects
Data: SRG SSR Developer Portal Β· SRF Meteo Β· Polis API
Protocol: Model Context Protocol β Anthropic / Linux Foundation
Related:
Server | Description |
City of Zurich open data (OSTLUFT air quality, weather, parking, geodata) | |
Swiss public transport β OJP 2.0 journey planning, SIRI-SX disruptions | |
BAFU environmental data β air quality, hydrology, natural hazards | |
BFS STAT-TAB β 682 statistical datasets | |
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)
Portfolio: Swiss Public Data MCP Portfolio
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": {
"srgssr-mcp": {
"command": "uvx",
"args": [
"srgssr-mcp"
]
}
}
}Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/malkreide/srgssr-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server