bag-epl-mcp について
bag-epl-mcpは、スイスBAGの電子給付プラットフォームにある医薬品、先天性疾患向け薬剤、医療機器のリストを調べるMCPサーバーです。保険適用の確認に使える規制情報と法的根拠を読み取り専用で提供します。
主な機能
- 01Spezialitätenlisteの検索
- 02GGSLの適用情報を確認
- 03MiGeLの機器・補助具を検索
- 04法的背景と出典リンクを提示
活用シーン
- 01医薬品が強制保険の対象か確認
- 02先天性疾患向け薬剤の適用情報を調査
- 03車椅子や補助具がMiGeLに掲載されているか確認
MCP 対応
スイスBAG ePLデータを照会する読み取り専用のツール、リソース、プロンプトをMCPクライアントに公開します。stdioとStreamable HTTPに対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
🇨🇭 Swiss Public Data MCP Portfolio の一部です
💊 bag-epl-mcp
スイス連邦公衆衛生局(BAG)の電子給付プラットフォーム(ePL)向け MCP サーバー — Spezialitaetenliste、GGSL、MiGeL
デモ
概要
bag-epl-mcp を使うと、AI モデルは実際のデータに基づき、自然言語でスイスの強制健康保険の適用範囲に関する質問に回答できます。
| リスト | 目的 | 法的根拠 |
|---|---|---|
| Spezialitaetenliste (SL) | 強制保険の対象となる医薬品 | KVG 第52条 |
| GGSL | 先天性疾患(IV)向けの医薬品 | IVG 付属書 |
| MiGeL | 医療機器・補助具 | KLV 第20条 |
代表的な質問: 「この医薬品は強制健康保険の対象ですか?」
→ epl_sl_suche:Spezialitaetenliste (SL) をリアルタイムで検索します
→ 利用者別のその他のユースケース →
機能
- 💊 スイスの健康保険データ向けに 6 つのツール、2 つのリソース、2 つのプロンプトを提供
- 🔍
epl_sl_suche— Spezialitaetenliste で医薬品を検索 - ⚖️
epl_rechtskontext— Fedlex へのリンク付きで法的背景を確認 - 🔓 API キー不要 — すべてのデータに公開アクセス可能
- ☁️ 2 種類のトランスポート — stdio(Claude Desktop)+ Streamable HTTP(クラウド)
- 📚 保険適用範囲の確認や学校保健に関する質問に使えるプロンプトテンプレート
前提条件
- Python 3.11+
- uv(推奨)または pip
インストール
# Clone the repository
git clone https://github.com/malkreide/bag-epl-mcp.git
cd bag-epl-mcp
# Install
pip install -e .
# or with uv:
uv pip install -e .
または uvx を使う場合(恒久的なインストールは不要です):
uvx bag-epl-mcp
クイックスタート
# stdio (for Claude Desktop) — default, opens no network ports
python -m bag_epl_mcp.server
# Streamable HTTP (cloud) — transport selected via env var
MCP_TRANSPORT=streamable-http MCP_HOST=0.0.0.0 MCP_PORT=8000 \
pip install -e ".[http]" && python -m bag_epl_mcp.server
トランスポートとホストは環境変数でのみ設定できます (
MCP_TRANSPORT、MCP_HOST、MCP_PORT)。デフォルトは何にもバインドしないstdioです。MCP_HOSTのデフォルトは127.0.0.1で、0.0.0.0に設定するのは コンテナまたはクラウド環境内に限ってください。
Claude Desktop ですぐに試せます:
「メチルフェニデート(Ritalin)は強制健康保険の対象ですか?」 「Spezialitaetenliste への収載を規制する法律は何ですか?」 「車椅子は強制保険の対象ですか?」
設定
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json(macOS)または %APPDATA%\Claude\claude_desktop_config.json(Windows)を編集します:
{
"mcpServers": {
"bag-epl": {
"command": "python",
"args": ["-m", "bag_epl_mcp.server"]
}
}
}
または uvx を使う場合:
{
"mcpServers": {
"bag-epl": {
"command": "uvx",
"args": ["bag-epl-mcp"]
}
}
}
クラウドへのデプロイ(ブラウザーアクセス向けの Streamable HTTP)
Render.com(推奨):
- リポジトリを GitHub にプッシュするか、フォークします
- render.com で、New Web Service → GitHub リポジトリに接続します
- ビルドコマンド:
pip install -e ".[http]" - 以下の環境変数を設定します:
MCP_TRANSPORT=streamable-httpMCP_HOST=0.0.0.0(コンテナが外部トラフィックを受け入れるために必須です)MCP_PORT=8000(または Render の$PORT)- (任意)
MCP_CORS_ORIGINS='["https://claude.ai"]'を設定して、ブラウザーの CORS 許可リストを拡張します - (任意) OpenTelemetry トレーシングはデフォルトで有効ですが、トレーシング関連の依存関係がインストールされていない場合は何も行いません。
pip install -e ".[http,otel]"でビルドし、OTEL_EXPORTER_OTLP_ENDPOINTにコレクターを指定します。無効にするにはMCP_OTEL_ENABLED=0を設定します。
- 起動コマンド:
python -m bag_epl_mcp.server - claude.ai の Settings → MCP Servers で、
https://your-app.onrender.com/mcpを追加します
**セキュリティに関する注意:**サーバーが公開するのは読み取り専用の公開データのみで、認証は使用しません。脅威モデル(送信先許可リスト、ホストのバインド、Lethal-Trifecta の評価)については、
docs/SECURITY.mdを参照してください。
利用可能なツール
| ツール | 説明 |
|---|---|
epl_sl_suche | Spezialitaetenliste を検索して、強制保険の対象となる医薬品を調べます |
epl_ggsl_abfrage | 先天性疾患に対する GGSL の適用範囲を確認します |
epl_migel_suche | MiGeL を検索して、医療機器や補助具を調べます |
epl_gesuchseingaenge | SL への収載申請のうち、審査中のものを一覧表示します(透明性) |
epl_rechtskontext | 適用範囲に関する質問の法的背景(WZW 基準) |
epl_server_info | サーバーの状態と API のフェーズ情報 |
使用例
| クエリ | ツール |
|---|---|
| 「リタリンは保険の対象ですか?」 | epl_sl_suche |
| 「先天性疾患 GG-313 に使われる医薬品は何ですか?」 | epl_ggsl_abfrage |
| 「車椅子は保険の対象ですか?」 | epl_migel_suche |
| 「SL を規制する法律は何ですか?」 | epl_rechtskontext |
アーキテクチャ
データフロー(フェーズ 1):
bag-epl-mcp (FastMCP)
┌────────────┐ MCP ┌───────────────────────────────┐ HTTPS GET ┌──────────────────┐
│ MCP Client │◀───────▶│ tools (read-only) │─────────────▶│ sl.bag.admin.ch │
│ (Claude │ stdio / │ ├─ epl_sl_suche │ egress │ www.bag.admin.ch │
│ Desktop, │ Stream- │ ├─ epl_ggsl_abfrage │ allow-list │ www.fedlex... │
│ claude.ai)│ able │ ├─ epl_migel_suche │◀─────────────│ (public OGD) │
│ │ HTTP │ ├─ epl_gesuchseingaenge │ (no auth) └──────────────────┘
│ │ │ ├─ epl_rechtskontext │
│ │ │ └─ epl_server_info │ structured JSON logs → stderr
└────────────┘ │ resources: epl://uebersicht …│
│ prompts: epl_kassenpflicht…│
└───────────────────────────────┘
フェーズのロードマップ(詳細は docs/ROADMAP.md を参照):
Phase 1 (current) → legal context + entry points, no data retrieval
Phase 2 (planned) → FHIR/IDMP API, once publicly accessible
Phase 3 (vision) → MiGeL + AL via ePL-FHIR
フェーズ 1 で行うこと、行わないこと。 6 つのツールのうち 5 つはネットワークリクエストを一切行いません。モジュール全体で送信される HTTP 呼び出しは、ちょうど 1 回だけです。これらのツールは法的根拠と参照先を返し、その旨を明示するようになりました。以前の「XML/XLSX のダウンロード + SL ウェブサイトへのアクセス」という表現は、実装されていない機能をうたっていました。基となる情報源が機械可読ではないため、実装するのではなく、2026-08-08 に削除されました。
この 1 回の HTTP 呼び出しは sl.bag.admin.ch/api/search に送信され、text/html の HTTP 200(51 KB の Angular シェル)を受け取ります。同じプレフィックス配下に自由に作成したパスを指定しても、バイト単位で同一の応答が返されます。そのアドレスに API はありません。以前は、発生した JSON 解析エラーを単純な except Exception で捕捉し、「SL データベース API は公開ドキュメント化されていません」という主張に置き換えていました。これは、解析エラーから BAG の公開方針について結論づけたものです。現在、このツールは実際に観測された内容を報告します。
SL のフロントエンドは、代わりに別のホスト上の https://epl.bag.admin.ch/api/sl/ を呼び出します。このホストは認証なしでは 401 を返しますが、存在しないパスに対しても 401 を返すため、特定のルートが存在することの証明にはなりません。検証可能なアクセスがない状態で追加すれば疑念に基づく許可となるため、このホストは意図的に送信先許可リストに含めていません。
MCP プロトコルのバージョン: ネイティブでは 2026-07-28、initialize ハンドシェイクの上限では 2025-11-25 です。epl_server_info は、接続ごとに実際にネゴシエートされたリビジョンを報告します。ここに改めて記載された値ではなく、リクエストから導出されます。両方の時代については、MCP プロトコルのバージョン を参照してください。SDK の更新は Dependabot を通じて毎月提案されます。mcp SDK の更新ごとにプロトコルのバージョンを見直します。バージョン管理ポリシーについては docs/ROADMAP.md を参照してください。
安全性と制限
- 読み取り専用: すべてのツールは HTTP GET リクエストのみを実行します。データの書き込み、変更、削除は行いません。
- 個人データなし: サーバーは公開されている規制リスト(SL、GGSL、MiGeL)にアクセスします。個人を特定できる情報(PII)は処理も保存もされません。
- 医療上の助言なし: このサーバーが提供するのは規制データへの情報アクセスのみです。医療上または法的な判断を行う際は、必ず BAG の公式情報源と資格を持つ専門家に相談してください。
- レート制限: SL のウェブサイト(sl.bag.admin.ch)は公開されている Angular SPA です。サーバーはリクエストごとに 30s のタイムアウトを設定しています。
limitパラメーターは控えめに使用してください。 - データの鮮度: Phase 1 のツールは BAG の最新情報源にリンクします。このサーバーはキャッシュを行いません。
- リンクは推測ではなく、検証されています: 「公式情報源」として提供されるアドレスは、架空のパスに対する対照リクエストとともに、実行のたびに
scripts/record_fixtures.pyによって再検証されます。以前に提供していた BAG のページ 2 件(.../Arzneimittel/geburtsgebrechen-spezialitaetenliste.htmlと.../Arzneimittel/gesuchseingaenge.html)は、2026-08-08 に HTTP 404 を返したため、推測した代替 URL ではなく、確実に解決されることを検証済みの入口ページに置き換えました。 - 法令参照は登録簿で検証されています: サーバーが出力するすべての SR 番号について、Fedlex SPARQL エンドポイントを使って ELI を解決します。この手順が必要なのは、Fedlex のウェブフロントエンドがシングルページアプリであり、架空のものを含む すべての ELI に対して、同じバイト数の HTTP 200 を返すためです。その結果、誤った GgV リンク(
eli/cc/1986/40_40_40、登録簿に記載なし)が見過ごされていました。正しい ELI はeli/cc/1986/46_46_46です。 - データライセンス(OGD-CH): 基盤となる BAG/Fedlex のデータはスイスのオープンガバメントデータであり、CC BY 4.0 ライセンスの対象です。ツールの出力には
source/provenanceブロック(JSON)または出典とライセンスのフッター(Markdown)が含まれるため、帰属表示が保持されます。 - 構造化出力: すべてのツールは、人が読める Markdown/JSON ブロック(
content)と、ツールごとの出力スキーマに照らして検証された型付きのstructuredContentの両方を返します。そのため、MCP クライアントは文章を解析せずに結果をプログラムから利用できます。 - 利用規約: データには、sl.bag.admin.ch、bag.admin.ch、fedlex.admin.ch の利用規約が適用されます。
- 保証なし: これはコミュニティプロジェクトであり、BAG や政府機関とは提携していません。利用可能かどうかは上流の情報源に依存します。
MCP プロトコルのバージョン
このサーバーは同じエンドポイントで2 つのプロトコル世代に対応します。接続時のクライアントの最初のリクエストによって、どちらを適用するかが決まります。もう一方の世代を後から要求しても拒否されます。
| 世代 | リビジョン | 利用するクライアント |
|---|---|---|
initialize ハンドシェイク | 2024-11-05 … 2025-11-25 | 現在のクライアントが使用するものです。サーバーは要求されたリビジョンで応答しますが、それより新しいバージョンが要求された場合は、上限である 2025-11-25 で応答します。 |
| リクエストごとのエンベロープ | 2026-07-28 | 2026-07-28 の _meta エンベロープを含むリクエストによって、モダン接続が開始されます。 |
両方のリビジョンは tests/test_protocol_version.py に固定され、インストール済み SDK と照合して検証されます。そのため、Dependabot による mcp の更新で、どちらのリビジョンも知らないうちに変わることはありません。定数の確認に加えて、同じファイルで実際の initialize と 2026-07-28 のリクエスト(server/discover、tools/call)を組み立て済みの HTTP アプリに送り、実測した応答を検証します。
SDK の LATEST_PROTOCOL_VERSION はハンドシェイク世代ではなく、モダン世代のエイリアスである点に注意してください。これだけを基準に固定すると、現在のクライアントが実際にネゴシエートする世代が、変更されても検出されない状態になります。
更新ポリシー。 ゲートに失敗した場合は、定数をむやみに編集しないでください。2 つのリビジョン間の仕様変更履歴を読み、サーバーが引き続き正常に動作することを確認してから、定数、このセクション、README.de.md、CHANGELOG.md をまとめて更新してください。
テスト
# Unit + contract tests (no network) — this is what CI runs
PYTHONPATH=src pytest tests/ -m "not live"
# Live tests against the real BAG/Fedlex sources
PYTHONPATH=src pytest tests/ -m "live"
# Re-record the measurements (writes tests/fixtures/ + PROVENANCE.md)
PYTHONPATH=src python scripts/record_fixtures.py
100 件のテスト — オフラインで 88 件、稼働中のソースに対して 12 件です。
ライブテストに加えて契約テストファイルがある理由
2026-08-08 まで、8 件のライブテストのうち 6 件は通過できませんでした。文字列とツールの戻り値を比較していたためです。
assert "BAG ePL MCP Server" in result # result is a CallToolResult
CallToolResult は Pydantic モデルです。in は (field, value) の組を反復処理するため、比較は常に false になります。誰も気づきませんでした。CI では -m live が除外されているためです。CI の外でしか実行されず、そこで常に失敗するテストは、誰にも報告されません。
また、仮に修正されていたとしても、4 件は何も証明できなかったでしょう。入力をテンプレートに書き込むツールに対する assert "313" in result や、同様の assert "Rollstuhl" in result です。これらのテストが検証していたのは、ツールが入力をそのまま返すことでした。まさに、それらのツールが行うことです。
したがって、恒久的に満たすべき要件は tests/test_quellen_vertrag.py に記録されています。このテストは、tests/fixtures/ にある記録済みの測定値を使って、CI の中で実行されます。PROVENANCE.md には、それぞれの測定値のソース、日付、選定ルール、SHA-256 が記録されています。
記録された測定値のうち 4 件は対照です。sl.bag.admin.ch/api/ 配下の架空のパス、BAG ポータル内の架空のパス、架空の ELI、架空の SR 番号です。これらがなければ、各測定値が示すのは私たちが受け取った内容だけで、ソースに実際にある内容は示せません。対照で識別できなくなった場合、ライブのエントリーポイントが停止した場合、停止していたページが再び表示された場合、または法的参照が登録簿と一致しなくなった場合、記録処理は中断されます。
変更履歴
CHANGELOG.md を参照してください。
貢献
CONTRIBUTING.md を参照してください。
セキュリティ
セキュリティに関する方針と脆弱性の報告方法については、SECURITY.md(ドイツ語)を参照してください。
ライセンス
MIT ライセンス — LICENSE を参照してください。
作者
Hayal Oezkan · malkreide
クレジットと関連プロジェクト
- BAG Spezialitaetenliste: sl.bag.admin.ch — 連邦公衆衛生局
- KVG: SR 832.10 — 医療保険法
- KLV: SR 832.112.31 — 医療給付条例
- プロトコル: Model Context Protocol — Anthropic / Linux Foundation
- 関連: fedlex-mcp — スイス連邦法
- 関連: swiss-cultural-heritage-mcp — 文化遺産データ
- ポートフォリオ: Swiss Public Data MCP Portfolio
インストール
uv の uvx を使って実行できます。クローンや手動インストールは不要です。MCP クライアントの設定に追加してください(Claude Desktop、Cursor、Windsurf では mcpServers を使用します。VS Code では .vscode/mcp.json にトップレベルの servers キーを使用してください)。
{
"mcpServers": {
"bag-epl-mcp": {
"command": "uvx",
"args": [
"bag-epl-mcp"
]
}
}
}
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。