Bag Health Mcp

io.github.malkreide由 GitHub 账号 malkreide 发布v0.4.1更新于 Oct 24, 2026

BAG public-health open data: indicators, programmes, statistics

已验证STDIO仅桌面位置与生活数据与分析

概览

AI 生成的概览

只读 MCP 服务器,为助手提供瑞士公共卫生数据:BAG 传染病监测,以及 Obsan、Versorgungsatlas 和 Sucht Schweiz 的指标。

可以做什么
列出并浏览 BAG 传染病仪表盘的疾病主题、数据系列、筛选维度和导出文件,查看当前数据版本与可用导出,并可下载原始 CSV/JSON 导出、按系列及州、年龄、性别获取时间序列监测数据,以及获取州级疫情概况。按来源、主题、地区和年份范围检索 Obsan、Versorgungsatlas 与 Sucht Schweiz 的健康指标,并获取单个指标的时间序列及其口径(全国、按州、按年龄组、按社会地位)和置信区间。读取州代码、疾病分类和数据许可条款等静态参考资源。运行内置提示词以生成州级公共卫生情况简报或疾病是否升高的核查。
适用场景
需要瑞士公共卫生数据时适用:某州或某病原体的当前及历史传染病监测、污水信号,或青少年饮酒等群体健康指标,并附带来源标注。适合学校与市政公共卫生报告,而非个人医疗建议。
运行要求
通过 stdio 在本地运行,通常用 uvx 从 PyPI 包启动,需要 Python/uv 运行时。无需 API 密钥或账户,会访问三个公开 HTTPS 数据主机。可选 HTTP 模式通过 MCP_TRANSPORT、MCP_HOST、MCP_PORT、MCP_AUTH_TOKEN、MCP_CORS_ORIGINS、MCP_ALLOWED_HOSTS 等环境变量配置。
安装前请注意
所有工具均为只读,数据是聚合的公开统计,不构成个人建议、诊断或病例评估。数据非实时(每周三更新),上游 API 标注为 beta,结构可能变动。复用数据须注明来源。若启用 HTTP 传输,除网络隔离环境外不要绑定到 localhost 之外;对外暴露时应设置 MCP_AUTH_TOKEN 和 MCP_ALLOWED_HOSTS。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Bag Health Mcp,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

bag-health-mcp

[PyPI] [Python 3.11+] [License: MIT] [Swiss Public Data MCP Portfolio]

Part of the Swiss Public Data MCP Portfolio — connecting AI models to Swiss public data sources.

🇩🇪 Deutsche Version

MCP server for Swiss public health data. Its core is the Swiss Federal Office of Public Health (BAG) Infectious Disease Dashboard (IDD) — epidemiological surveillance for 51 pathogens (influenza, COVID-19, measles, wastewater surveillance, and more) — extended with a multi-source health-indicator layer over the Swiss Health Observatory (Obsan), the Versorgungsatlas (health-care supply atlas, with cantonal series) and Sucht Schweiz (HBSC youth survey). All read-only, public Open Government Data.


What You Can Do

"Wie ist die aktuelle Grippesituation im Kanton Zürich verglichen mit den letzten Wochen?"→ bag_health_mcp__get_canton_situation(canton="ZH")
"Gibt es aktuell einen Masernausbruch in der Schweiz?"→ bag_health_mcp__get_disease_data(series_id="measles/cases/incValue/year", canton="all")
"Wie entwickelt sich das SARS-CoV-2-Signal im Abwasser?"→ bag_health_mcp__list_series(topic="wastewater_viral_load")→ bag_health_mcp__get_disease_data(series_id="wastewater_viral_load/NA/value/date", ...)
"Welche Krankheitsdaten stellt das BAG aktuell bereit?"→ bag_health_mcp__list_diseases()
"Wie hat sich der Alkoholkonsum bei 15-Jährigen seit 2010 entwickelt?"   # 🎯 anchor query→ bag_health_mcp__search_health_indicators(source="suchtschweiz", topic="alkohol")→ bag_health_mcp__get_indicator_series(source="suchtschweiz",      indicator_id="monam/alkoholkonsum-alter-11-15", region="ZH", year_from=2010)→ More use cases by audience →

🎯 Anchor demo query — «Wie hat sich der Alkoholkonsum bei 15-Jährigen im Kanton Zürich seit 2010 entwickelt, und wie steht der Kanton im Schweizer Vergleich da?» The HBSC youth series (via Obsan) answers the Switzerland-wide trend since 2010 with 95% confidence intervals. This particular indicator is national only, so the response includes a region_note saying so (HBSC is not cantonally representative). Most other Obsan indicators are published by canton — see the note on cuts below. These are aggregated population statistics — not individual advice. See docs/tool-design-health-indicators.md.


Tools

Infectious-disease surveillance (BAG IDD):

ToolDescription
bag_health_mcp__list_diseasesList all 51 disease topics, grouped by category
bag_health_mcp__list_seriesList data series for a specific disease
bag_health_mcp__get_series_detailsGet available filter dimensions (canton, age, sex)
bag_health_mcp__get_disease_dataFetch time-series surveillance data
bag_health_mcp__get_canton_situationSituational overview for a canton (Schulamt use case)
bag_health_mcp__list_export_filesList available complete export datasets
bag_health_mcp__download_exportDownload raw CSV/JSON export
bag_health_mcp__get_data_versionCurrent data version (updated every Wednesday)

Health indicators — Obsan, Versorgungsatlas & Sucht Schweiz (multi-source):

ToolDescription
bag_health_mcp__search_health_indicatorsSearch indicators by source (obsan / versorgungsatlas / suchtschweiz), topic, region, year range
bag_health_mcp__get_indicator_seriesFetch one indicator's time series, naming which cut it is (variant: national / by canton / by age class / by social position / distribution) and which others exist. Pass region='ZH' for the cantonal cut; 95% CIs throughout

⚠️ Aggregated population statistics only. The indicator tools serve population-level aggregates (prevalences/metrics by age/sex/region) — not individual advice, diagnosis or case assessment, and no personal data. This is stated in both tool descriptions and every response (aggregate_statistics_notice), and matters especially for suchtschweiz (HBSC), which touches prevention topics in a school context. Sources: Obsan ind.obsan.admin.ch (clean JSON API); Sucht Schweiz HBSC via the Obsan mirror (national); Versorgungsatlas returns a cantonal year/value series (26 cantons + a CH national total, with 95% CIs and a canton-vs-CH ratio) from the Tarifpool. See the per-source probe notes.

Obsan publishes an indicator in several cuts, not one series. Measured over 60 catalogue entries on 2026-08-08: 50 have a cantonal cut (kg), 49 one by age class (ag), 24 one by social position (sd) — and only 3 the plain national one (g). They are different measurements with different units, so get_indicator_series names the cut it returned in variant and lists the rest in variants_available, rather than presenting one as a stand-in for another. Eight of the 60 publish no series at all; that case fails with its reason instead of returning an empty result. The census is recorded and dated in tests/fixtures/obsan_variant_census.json.

Tool annotations

All tools carry MCP tool annotations so a host can reason about them without calling. Every tool is identical here — it only ever reads from the public, allow-listed data sources (BAG IDD, Obsan, Versorgungsatlas):

AnnotationValueMeaning
readOnlyHinttrueNo tool mutates any state.
destructiveHintfalseNo destructive side effects.
idempotentHinttrueRepeating a call has no additional effect.
openWorldHinttrueTools reach an external system (the upstream data APIs).

A host may therefore treat all calls as safe, cacheable reads. The values are declared once as READ_ONLY in server.py and applied to all 10 tools.

MCP Primitives

This server uses all three MCP primitives, each for what it is best at:

Tools (10) — live, parameterised actions that call the IDD API (above).

Resources — static, read-only reference data a host can fetch and cache, no arguments or upstream call needed:

Resource URIDescription
bag://reference/cantonsCanton codes accepted by the tools (incl. FL, all)
bag://reference/disease-categoriesDisease-topic taxonomy by category
bag://reference/data-licenceSource, attribution and licence terms

Prompts — reusable, parameterised workflows a host can surface (e.g. as slash-commands):

PromptArgumentsPurpose
canton_situation_briefcantonDraft a Schulamt public-health situation brief
outbreak_checkdisease, cantonCheck whether a disease is currently elevated

Live surveillance data stays behind Tools (it is parameterised and changes weekly); fixed reference data is exposed as Resources; recommended multi-tool workflows are packaged as Prompts.


Relevance for Schools & City Administration

Schulamt / Kreisschulbehörden:

  • Monitor influenza and ARI incidence in your canton
  • Single measles case → alert for schools with low vaccination coverage
  • Pertussis tracking → protect unvaccinated infants (siblings of school children)

Stadtverwaltung / KI-Fachgruppe:

  • Public Health Reporting with structured weekly data
  • Wastewater surveillance as 1-week lead indicator before clinical cases

Synergy with portfolio:

  • bag-epl-mcp → "What treatments are listed?" (EPL medication database)
  • bag-health-mcp → "What is currently spreading?" (surveillance data)

Data Source

  • IDD API: https://api.idd.bag.admin.ch — No authentication required
  • Update cycle: Every Wednesday
  • Coverage: Switzerland + Liechtenstein (FL), 26 cantons
  • Topics: 51 pathogens, 1386 data series

Datenquellen & Lizenzen / Data sources & licences

SourceProviderLicenceAttribution required
Infectious Disease Dashboard (IDD)Federal Office of Public Health (FOPH / BAG)opendata.swiss Open Government Data — free use, source attribution required (Swiss OGD terms, CC BY-equivalent)Yes
Health indicatorsObsan — Swiss Health Observatory (ind.obsan.admin.ch)No explicit machine-readable licence; treat as Swiss OGD practice — free use, cite the per-indicator sourceYes
Health-care supply atlasVersorgungsatlas (BAG/Obsan, versorgungsatlas.ch)Same (Swiss OGD practice, cite source)Yes
HBSC youth surveySucht Schweiz — HBSC, obtained via the Obsan mirrorSame (Swiss OGD practice, cite «Sucht Schweiz — HBSC»)Yes

Required citation: Federal Office of Public Health FOPH — Infectious Disease Dashboard (IDD), open data via opendata.swiss. For the indicator tools, each response's provenance.source names the concrete upstream (e.g. «Sucht Schweiz — HBSC» via Obsan). Every tool response carries attribution in a provenance block (attribution + license fields) so downstream consumers can surface it automatically.

Architecture:                    ┌─────────────────┐    api.idd.bag.admin.ch (IDD API, no auth)  MCP Host          │  bag-health-mcp │──▶ ind.obsan.admin.ch   (Obsan JSON API)  (Claude, etc.) ──▶│  MCP SDK        │──▶ versorgungsatlas.ch  (indicator catalogue)                    │  10 Tools       │    all HTTPS, egress allow-listed, no auth                    └─────────────────┘

Installation

Claude Desktop (stdio)

json
{  "mcpServers": {    "bag-health": {      "command": "uvx",      "args": ["bag-health-mcp"]    }  }}

Cloud / HTTP

bash
pip install bag-health-mcppython -m bag_health_mcp.server --http --port 8000

Transport, host and port are set via environment variables — MCP_TRANSPORT (http/stdio), MCP_HOST, MCP_PORT — which is the recommended way for deployments (the --http flag still works for local use). The server binds to 127.0.0.1 by default so a local HTTP server is not exposed to the network. Container/cloud deployments bind all interfaces by setting MCP_HOST=0.0.0.0 explicitly — the provided Dockerfile does this.

⚠️ Security: HTTP transport exposes the server on the network. Only bind beyond 127.0.0.1 in a network-isolated environment — never directly on a public/shared network. Binding to a non-localhost host logs a warning at startup. The default stdio transport has no network surface. See docs/security-posture.md.

HTTP auth (optional): set MCP_AUTH_TOKEN to require Authorization: Bearer <token> on every HTTP request (401 otherwise). Unset = no auth (fine for stdio/local). This gates who may invoke the server; for real user identity, front it with a gateway.

CORS (browser clients): set MCP_CORS_ORIGINS to a comma-separated origin allow-list to enable cross-origin browser access. The 2026-07-28 routing headers (Mcp-Method, Mcp-Name, Mcp-Protocol-Version) pass the preflight; no session header is exposed, because the server issues none. Empty = no cross-origin (never a wildcard).

Host allow-list (DNS rebinding): set MCP_ALLOWED_HOSTS to a comma-separated list of the names this server is reachable under, including the port, e.g. bag.example.ch:8000. Requests arriving under any other Host are rejected with 421; loopback stays allowed so container health checks keep working.

Unset on a non-localhost bind, the check is left off and a warning is logged — that is the gateway-fronted deployment, where the gateway validates Host. It is not guessed: on 0.0.0.0 the reachable name is unknowable here, and a wrong guess would reject the very deployment it is meant to protect.

This is independent of MCP_AUTH_TOKEN. The token says who is asking; this says under which name the server is addressed. A rebinding attack runs in a browser that already holds the token.

For running at scale (no session affinity needed, resource limits, MCP gateway), see the deployment & scaling guide and the reference manifests in deploy/.

Logging: the server emits structured JSON logs (one object per line, with an RFC 5424 severity) to stderr — stdout is reserved for the stdio JSON-RPC transport. Set the level with MCP_LOG_LEVEL (default INFO).

Tracing (optional): install the telemetry extra and point the server at an OTLP collector to get OpenTelemetry spans per tool-call plus instrumented outbound HTTP:

bash
pip install "bag-health-mcp[telemetry]"export OTEL_EXPORTER_OTLP_ENDPOINT="http://otel-collector:4318"# optional: OTEL_SERVICE_NAME=bag-health-mcp

Tracing is a no-op unless both the extra is installed and an OTEL_* endpoint is set. Spans carry only the tool name and (on error) the exception class — never tool arguments, cantons or surveillance data.


Available Disease Topics

CategoryTopics
Respiratoryinfluenza, covid19, acute_respiratory_infection, respiratory_pathogens
Entericcampylobacteriosis, salmonellosis, ehec, listeriosis, hepatitis_a/e
STI & Bloodbornehiv, aids, syphilis, gonorrhea, hepatitis_b/c, chlamydiosis
Vaccine-preventablemeasles, pertussis, rubella, tetanus, diphtheria, ipd, meningo
Vector-bornelyme_borreliosis, tick-borne_encephalitis, dengue, malaria, zika
Wastewaterwastewater_viral_load, wastewater_sequencing

Demo

[Demo: Claude queries BAG IDD via bag-health-mcp]

Claude asking about the influenza situation in canton Zurich — single tool call, structured result, actionable German-language summary.


MCP Protocol Version

This server speaks MCP 2026-07-28 natively, and still serves every older client over the same endpoint. The client's first request on a connection decides the era; a later claim from the other era is refused.

EraRevisionWho reaches it
Per-request envelope2026-07-28A request carrying the 2026-07-28 _meta envelope. No initialize, no session — the SDK's own Client lands here by default.
initialize handshake2024-11-05 … 2025-11-25Clients that do not speak 2026-07-28 yet. The server answers with the revision asked for, or with the 2025-11-25 ceiling when the request asks for something newer.

What "natively" means here, each point asserted in tests/test_spec_2026_07_28.py:

  • No session, in either era. No response carries Mcp-Session-Id; any replica can answer any request, so a plain round-robin load balancer is enough (see deployment & scaling). For handshake clients this is a deliberate stateless_http=True.
  • No deprecated capabilities. Protocol logging (ctx.info/ctx.warning), sampling and roots are deprecated in 2026-07-28 (SEP-2577). The server uses none of them; operational logs go to stderr. The test suite turns MCPDeprecationWarning into an error, so a reintroduced call fails CI.
  • No server-to-client requests. No tool asks the client anything, so nothing depends on a back-channel 2026-07-28 no longer has.
  • Progress (server-to-client, still in the spec) arrives in both eras, on the response stream of the tool call.
  • Cache hints (ttlMs/cacheScope, SEP-2549) on the listing methods, and CORS for the routing headers Mcp-Method, Mcp-Name, Mcp-Protocol-Version.

Both revisions are pinned in tests/test_protocol_version.py and asserted against the installed SDK, so a Dependabot bump of mcp cannot move either one silently. The handshake ceiling is measured against a live initialize through the assembled ASGI stack, not read off a constant name.

Note that the SDK's LATEST_PROTOCOL_VERSION is an alias for the modern era, not for the handshake era — pinning against it alone would leave the handshake era free to drift.

Update policy. When the gate fails, do not edit the constant blindly: read the spec changelog between the two revisions, verify the server still behaves, then move the constant, this section, README.de.md and CHANGELOG.md together.


Safety & Limits

AspectDetails
AccessRead-only — no write operations possible
EgressCode-layer allow-list: the server only contacts three public data hosts (api.idd.bag.admin.ch, ind.obsan.admin.ch, www.versorgungsatlas.ch), HTTPS-only, enforced on every request incl. redirect hops (SSRF/SEC-004 + SEC-021). Network-layer companion policy in deploy/networkpolicy.yaml
Personal dataNone — all sources are aggregated/anonymised (BAG IDD at canton level by law; indicators are population aggregates by age/sex/region)
Rate limitsNo published IDD API rate limit; server caps responses at 104 data points per call by default (limit_weeks param)
Timeout30 s per API call
AuthenticationNo API keys required — all data publicly accessible
Data licenceopendata.swiss OGD — free use, source attribution required (CC BY-equivalent). FOPH IDD must be cited; see Data sources & licences
Terms of ServiceSubject to BAG IDD API ToS

Known Limitations

  • Beta API: IDD API is labelled v0.1 beta — schema may change without notice
  • Weekly cadence: Data is not real-time; updated Wednesdays only
  • Canton granularity: Some rare diseases have insufficient cases for canton-level data (suppressed for privacy)
  • Age groups: Available dimensions vary by disease series; use bag_health_mcp__get_series_details to check

Compliance

  • ISDS (Stadt Zürich): a draft information-security protection-needs classification (Schutzbedarfsanalyse per Grundwert + measures mapping) is in docs/isds-klassifikation.md. It is a technically-grounded draft pending ISBO/OIZ sign-off — not a binding classification.
  • Data classification (Schulamt): the data is classified ÖFFENTLICH / BUI (public OGD, no personal data, aggregated at canton level with small cells suppressed at source). Draft scheme + aggregation-risk note in docs/datenklassifikation-schulamt.md; the aggregating bag_health_mcp__get_canton_situation tool surfaces this in its response.
  • Security posture: lethal-trifecta assessment (the server is strictly read-only → not affected), secret-management decision (no secrets — public data), and network-exposure notes are in docs/security-posture.md.
  • Phase architecture: this is a Phase 1 (read-only) server; write/send capabilities are deferred behind documented prerequisites. See docs/roadmap.md.
  • Reporting vulnerabilities: see the security policy for how to report security issues privately.

Contributing

See CONTRIBUTING.md (Deutsch).

Security

See SECURITY.md (Deutsch) for the security posture and how to report a vulnerability confidentially.

License

Code: MIT (see LICENSE).

Data: BAG IDD is Open Government Data on opendata.swiss under free use with mandatory source attribution (Swiss OGD terms, CC BY-equivalent) — not public domain. Cite the Federal Office of Public Health FOPH (IDD) when reusing the data; see Data sources & licences.

Author

Hayal Oezkan · github.com/malkreide

Related Portfolio Servers

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):

json
{  "mcpServers": {    "bag-health-mcp": {      "command": "uvx",      "args": [        "bag-health-mcp"      ]    }  }}

来源:README.md,提交 02e802c

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

3
  1. v0.4.1最新Sep 27, 2026
  2. v0.4.0Sep 27, 2026
  3. v0.3.0Sep 16, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分