swiss-courts-mcp について
連邦レベルと全26州の裁判所判決を調査するMCPサーバーです。全文検索や法令条文検索、各種絞り込みに対応し、ライブの情報源が利用できない場合は、範囲を明示した部分的なオフラインデータに切り替えます。
主な機能
- 01判決全文の検索
- 02引用された法令条文による検索
- 03州、裁判所レベル、日付で絞り込み
- 04連邦最高裁判決を法廷別に検索
- 05最近の判決と裁判所一覧の閲覧
- 06出典を明示したオフラインデータへの切り替え
活用シーン
- 01スイスの特定分野の判例調査
- 02特定の法令条文を引用する判決の検索
- 03州や裁判所レベル別に最近の判決を確認
- 04ライブ情報源の停止中に連邦判決を検索
MCP 対応
読み取り専用の検索、判決取得、裁判所情報、統計のツールとプロンプトをMCPクライアントに提供します。オフラインデータでは出典と対象範囲が示されます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
🏛️ swiss-courts-mcp
スイスの裁判所判決を扱う MCP サーバー — 連邦最高裁判所(BGer)、連邦行政裁判所(BVGer)、連邦刑事裁判所(BStGer)、および entscheidsuche.ch を通じた全 26 の州裁判所
概要
単一の MCP インターフェースを通じて、あらゆる司法レベルのスイスの裁判所判決にアクセスできます。全文検索に、州、裁判所のレベル、日付範囲、法律の参照情報による構造化フィルターを組み合わせています。
🎯 デモクエリ: 「2020 年以降のデータ保護に関する連邦最高裁判所の判例(Art. 25 DSG)を検索してください。entscheidsuche.ch がダウンしている場合も、オフラインダンプから回答し、その旨を明示してください。」
| ソース | 対象範囲 | データ |
|---|---|---|
| entscheidsuche.ch(ライブ、デフォルト) | 連邦+26 州 | 約 2000 年以降の裁判所判決 |
| SCD ダンプ(オフラインフォールバック) | 連邦最高裁判所のみ、2007~2024 年 | メタデータ/判決要旨、全文なし |
fedlex-mcp との相乗効果: 法令(SR)+判例法=完全な法的調査。
可用性: entscheidsuche.ch は SLA のない非営利インフラストラクチャです。アクセスできない場合、サーバーはキャッシュされた公開ダンプに透過的にフォールバックします(オフラインフォールバックを参照)。すべての応答でデータの出所(source: "live" | "dump")を示し、ダンプからの回答には coverage_note が含まれます — このフォールバックは部分的なものであり、同等ではありません。
機能
- スイス全土の裁判所判決を対象とする全文検索
- 正規表現パーサーと Elasticsearch のブーストスコアリングを備えた、多段階の法律参照検索
- 法廷フィルターを備えた連邦最高裁判所専用検索
- 州および裁判所レベルによるフィルタリング
- 最近の判決フィード
- 裁判所の分類一覧
- 集計機能を備えた判決統計
- 3 言語対応(ドイツ語、フランス語、イタリア語)
- entscheidsuche.ch にアクセスできない場合、キャッシュされた公開ダンプにオフラインフォールバック — すべての応答でデータの出所を明示
- API キー不要
前提条件
- Python 3.11 以降
- MCP 対応クライアント(Claude Desktop、Cursor、Windsurf など)
インストール
pip install swiss-courts-mcp
または、ソースからインストールします。
git clone https://github.com/malkreide/swiss-courts-mcp.git
cd swiss-courts-mcp
pip install -e ".[dev]"
クイックスタート
# Run directly
swiss-courts-mcp
# Or via Python module
python -m swiss_courts_mcp
設定
Claude Desktop
claude_desktop_config.json に追加します。
{
"mcpServers": {
"swiss-courts": {
"command": "python",
"args": ["-m", "swiss_courts_mcp"]
}
}
}
クラウドへのデプロイ(HTTP トランスポート)
HTTP トランスポートはデフォルトで無効です。デフォルトのバインドホストは 127.0.0.1
(ループバックのみ)です。0.0.0.0 を使うには明示的に指定する必要があります(Dockerfile では指定しています)。
認証なしで HTTP を実行すると警告がログに記録されます。認証を行うリバースプロキシの背後でのみ実行してください。
# Local HTTP (loopback), no auth — development only
swiss-courts-mcp --http --port 8000
# Container (binds 0.0.0.0, auth enabled) — see Dockerfile
docker build -t swiss-courts-mcp .
docker run -p 8000:8000 -e MCP_AUTH_SECRET="$(openssl rand -hex 32)" swiss-courts-mcp
関連する環境変数(.env.exampleを参照):
| 変数 | デフォルト | 用途 |
|---|---|---|
MCP_HOST | 127.0.0.1 | バインドホストです。コンテナ内でのみ 0.0.0.0 に設定してください。 |
MCP_PORT | 8000 | バインドポートです。 |
MCP_ALLOW_PUBLIC_BIND | false | 0.0.0.0 の警告を抑制します(コンテナ)。 |
MCP_STATELESS_HTTP | true | ステートレス HTTP により、スティッキーセッションなしで水平スケーリングできます。 |
MCP_AUTH_ENABLED | false | HTTP のベアラートークン認証を有効にします。 |
MCP_AUTH_SECRET | — | HS256 署名キー(開発用)。 |
MCP_OAUTH_JWKS_URL | — | RS256 検証用の JWKS URL(本番環境)。 |
MCP_OAUTH_AUDIENCE | — | 認証を有効にする場合は必須です。 IdP がトークンに関連付けるリソース識別子(aud)です。 |
MCP_OAUTH_ISSUER | — | 認証を有効にする場合は必須です。 トークンを発行する IdP の発行者(iss)で、文字単位で比較されます。 |
MCP_RESOURCE_URL | バインドアドレス | このサーバーの公開 URL(RFC 9728 のリソース識別子)です。ループバック以外にバインドする場合は設定してください。 |
MCP_REQUIRED_SCOPES | — | 必須スコープをカンマ区切りで指定します。 |
MCP_CORS_ORIGINS | — | 許可するオリジンをカンマ区切りで指定します(本番環境ではワイルドカードを使用しないでください)。 |
認証では、JWT の sub クレームのみからユーザーの ID を検証します。ADR 0001を参照してください。
認証を有効にした場合、MCP_OAUTH_AUDIENCE は必須です。 aud クレームによって、トークンがこのサーバーに関連付けられます。この値がない場合、検証処理はオーディエンスをまったく確認せず、同じ発行者によって正しく署名されたトークンであれば、別のサービス向けに発行されたものも含めて受け入れていました(混乱した代理人)。現在、サーバーはこの値なしでは認証モードでの起動を拒否します。
同じ理由から、MCP_OAUTH_ISSUER も必須です。 iss クレームによって、トークンがサーバーの信頼する IdP に関連付けられます。これは、複数のテナントが 1 つの JWKS URL を共有する場合(ホスト型 IdP では一般的なケース)に重要です。この場合、署名はすべてのテナントで有効となり、テナントを区別できるのは iss だけです。この変数を未設定にしてオーディエンスを正しく設定した状態で測定したところ、iss: https://another-tenant.example のトークンも iss のないトークンも受け入れられました。この値は RFC 8414/9207 に従って文字どおり比較され、末尾のスラッシュも含めて正規化されません。末尾のスラッシュが削除される MCP_RESOURCE_URL とは異なります。
また、この設定はディスカバリーを機能させるためにも必要です。RFC 9728 ドキュメントの authorization_servers[0] は、SDK クライアントが認可サーバーとして採用する値です。この変数がないと、サーバーはそこに自分自身を指定します。しかし、このサーバーはリソースサーバーであり認可サーバーではないため、そのアドレスでは /.well-known/oauth-authorization-server、
/.well-known/openid-configuration、/authorize、/token、/register はすべて 404 を返します。
OAuth クライアントには MCP_RESOURCE_URL が必要です。 RFC 9728 に従って、サーバーは /.well-known/oauth-protected-resource でリソース識別子を公開し、すべての 401 の WWW-Authenticate ヘッダーにもその値を指定します。クライアントはここを参照して、トークンの取得先を確認します。この変数がないと、サーバーはバインドアドレスを公開します。コンテナにバインドした状態で測定したところ、{"resource": "http://0.0.0.0:8000", …} となっていました。クライアントが接続できないアドレスです。ループバック以外にバインドする場合は設定してください。未設定の場合、サーバーは起動時に警告を表示します。
SDK 独自の validate_token_resource は、測定に基づく理由から無効のままにしています。この機能は、トークンのリソースインジケーターを resource_server_url(ここではバインドアドレス)と文字どおり比較します。オーディエンスがその URL と完全に一致しないトークンは 401 で拒否されるため、この機能を有効にすると、上記のオーディエンスチェックが実際にサーバーを保護しているにもかかわらず、すべての実際のクライアントが締め出されます。
オフラインフォールバック(env)
| 変数 | デフォルト | 目的 |
|---|---|---|
SWISS_COURTS_FALLBACK_ENABLED | true | マスタースイッチです。0 にするとダンプフォールバックが無効になり、ライブのみになります。 |
SWISS_COURTS_FORCE_DUMP | false | ダンプ経路を強制します(ライブをスキップ)。キャッシュの事前ウォームアップやオフラインテストに使用します。 |
SWISS_COURTS_CACHE_DIR | platformdirs cache | ダウンロードしたダンプのキャッシュディレクトリを上書きします。 |
SWISS_COURTS_DUMP_RECORD | 14867950 | 使用する SCD ダンプの Zenodo レコード ID です。 |
キャッシュを事前にウォームアップします(約 120 MB の SCD CSV を一度ダウンロードするため、最初に実際の障害が発生した際にダウンロード時間がかかりません)。
SWISS_COURTS_FORCE_DUMP=1 python -m swiss_courts_mcp # then issue one search
MCP プロトコルのバージョン
このサーバーは同じエンドポイントで2 つのプロトコル時代に対応しており、クライアントの最初のリクエストによってどちらが使用されるかが決まります。
| 時代 | リビジョン | server.py 内の定数 | ハンドシェイク |
|---|---|---|---|
| レガシー | 2025-11-25 | HANDSHAKE_PROTOCOL_VERSION | initialize、セッション ID |
| モダン | 2026-07-28 | MODERN_PROTOCOL_VERSION | なし — リクエストごとの _meta エンベロープ |
両方のリビジョンを固定し、インストール済み SDK との乖離を防ぐガードを設けています。そのため、プロトコルの更新は意識的な変更(定数 + CHANGELOG + このセクション)になります。SDK の更新は Dependabot により毎月取り込まれます。
仕様 2026-07-28 は、SDK 独自のクライアントが選択する時代です。 mcp.Client は server/discover を試し、それが拒否された場合にのみハンドシェイクにフォールバックします。このサーバーではフォールバックしません。定数名からの推測ではなく、tests/test_modern_era.py で組み立てられた ASGI スタックを通じて測定しています。
モダン時代で異なる点は次のとおりです。
initializeもセッション ID もありません。 すべての POST は自己完結しており、プロトコルバージョンとクライアント機能を含むparams._metaに加えて、ルーティングヘッダーMCP-Protocol-Version、Mcp-Method、および(tools/call、prompts/get、resources/readの場合)Mcp-Nameを含みます。server/discoverが機能検出のハンドシェイクに代わり、subscriptions/listenが変更通知に代わります。ping、logging/setLevel、およびresources/subscribeの組み合わせは廃止されています。 この時代ではサーバーはこれらに-32601で応答しますが、レガシー時代では引き続き利用できます。ttlMs/cacheScopeは一覧表示メソッドで使用されます(SEP-2549)。CACHE_HINTSを参照してください。serverInfoはすべての応答の_metaに付与されます。 一度だけ情報を伝えるハンドシェイクがないためです。ここにはビルドバージョン、表示タイトル、プロジェクト URL が含まれます。目的の説明文はinstructionsに保持され、server/discoverとともに一度送信されます。
2026-07-28 を求める initialize にも、応答として 2025-11-25 が返されます。ハンドシェイクはモダン時代に入る方法ではなく、この応答からサーバーがモダン時代に対応しているかどうかは分かりません。
プロジェクトのフェーズ
フェーズ 1 — 読み取り専用(ROADMAP.md を参照)。すべてのツールは readOnlyHint: true であり、書き込み操作や破壊的な操作はありません。フェーズ 2(書き込み)への移行には、再監査を問題なく完了し、ロードマップに記載されたゲートを満たす必要があります。
利用可能なツール
裁判所判決の検索
| ツール | 説明 |
|---|---|
search_court_decisions | カントン、裁判所のレベル、日付で絞り込んで、すべての裁判所判決を全文検索します |
get_court_decision | 一意の署名を指定して、単一の判決を取得します |
search_bger_decisions | 任意の法廷フィルターを指定して、連邦最高裁判所の判決を検索します |
search_by_law_reference | 特定の法律条文(例:「Art. 8 BV」)を引用する判決を検索します |
裁判所情報
| ツール | 説明 |
|---|---|
list_courts | インデックス登録済みのすべての裁判所を一覧表示します。カントンで絞り込むこともできます |
get_recent_decisions | 最新の判決を表示します。カントンと裁判所のレベルで絞り込めます |
get_decision_statistics | カントンと年別のインデックス登録済み判決の統計情報を表示します |
get_fallback_status | オフラインダンプのキャッシュ状態、対象範囲、バージョン、事前ウォームアップの状態を表示します(読み取り専用) |
ツールのアノテーション
8つのツールすべてに、読み取り専用、冪等、非破壊的で、外部システムにアクセスするという同じヒントが設定されています。
| アノテーション | 値 |
|---|---|
readOnlyHint | true |
destructiveHint | false |
idempotentHint | true |
openWorldHint | true |
rechtsrecherche プロンプトも提供されています(ツールと並ぶ、2つ目のMCPプリミティブです)。
ユースケースの例
| ユースケース | ツールチェーン |
|---|---|
| データ保護に関する判例を調査する | search_court_decisions("Datenschutz") |
| 憲法上の権利に関する判例を見つける | search_by_law_reference("Art. 8 BV") |
| 連邦最高裁判所の最新判決 | search_bger_decisions("Arbeitsrecht", date_from="2024-01-01") |
| 組み合わせ:法令の条文+判例 | fedlex_search_laws("DSG") の後に search_by_law_reference("Art. 25 DSG") |
アーキテクチャ
┌─────────────────────────────────────┐
│ MCP Client (LLM) │
│ Claude / Cursor / Windsurf │
└──────────────┬──────────────────────┘
│ MCP Protocol
┌──────────────▼──────────────────────────────┐
│ swiss-courts-mcp │
│ 8 tools · Pydantic validation │
│ Elasticsearch query builder │
│ Provenance envelope: source = live | dump │
└───────┬──────────────────────────────┬──────┘
│ ① live (default) │ ② fallback
│ HTTPS POST/GET │ on bot-block / 5xx / 429 /
│ │ timeout, or SWISS_COURTS_FORCE_DUMP=1
┌───────▼──────────────────┐ ┌───────▼───────────────────────────────┐
│ entscheidsuche.ch │ │ SCD dump — Zenodo 14867950 (CC BY) │
│ Elasticsearch backend │ │ lazy download → platformdirs cache │
│ Federal + 26 cantons │ │ → local SQLite search │
│ no auth · no SLA │ │ BGer only · 2007–2024 · no full text │
└──────────────────────────┘ └───────────────────────────────────────┘
常にライブデータを優先します。オフラインダンプが使われるのは、利用可能性に問題がある場合(ボットによるブロック、HTTP 5xx/429、タイムアウト)または強制された場合のみです。これは既存のツールの動作であり、独立した検索ツールではありません。全文検索ではなくこのデータソースを使う理由についてはADR 0002を、対応範囲と非対応範囲については既知の制限を参照してください。get_fallback_status を使えば、いつでもキャッシュを確認できます。
安全性と制限
| 項目 | 詳細 |
|---|---|
| アクセス | 読み取り専用(readOnlyHint: true)— サーバーはデータを変更または削除できません |
| 個人データ | 個人データはありません。すべての判決は公開されている裁判所の判決です |
| レート制限 | クエリごとの上限を組み込み済み(検索結果は最大50件、集計バケットは最大50件) |
| タイムアウト | API呼び出しごとに30秒 |
| データソースの認証 | APIキーは不要です。entscheidsuche.ch は一般公開されています |
| HTTPトランスポートの認証 | ベアラートークン認証は任意です(JWT、sub クレームによるID識別)。ADR 0001を参照してください |
| 外部通信 | コード層で許可リストを設定しています(ライブデータは entscheidsuche.ch、オフラインダンプは zenodo.org)。HTTPSを強制しています。外部通信ポリシーを参照してください |
| エラーのマスキング | 内部例外はサーバー側のログにのみ記録され、クライアントには分かりやすいメッセージが返されます |
| シークレット | コードやログにシークレットは含まれません。.env はGitの追跡対象外で、PRではGitleaksを実行します。シークレット管理を参照してください |
| ライセンス | スイス法では、裁判所の判決はパブリックドメインです(BGG Art. 27) |
| 利用規約 | entscheidsuche.ch の利用規約が適用されます。サーバーに負荷をかけないようご配慮ください |
既知の制限事項
- 検索対象は entscheidsuche.ch にインデックスされている判決に限られます(すべての判決が公開されているわけではありません)。
- 全文書の内容は返されません。メタデータ、タイトル、要旨のみが返されます。
- 統計情報は、バックエンドの Elasticsearch 集計サポートに依存します。
Facetten_alle.jsonの裁判所の分類体系は変更される場合があります。
オフライン時のフォールバック(対象範囲は限定的です — こちらをお読みください): フォールバックは可用性を確保するための安全策であり、稼働中の情報源と同等のミラーではありません。
- 裁判所の対象範囲: 連邦最高裁判所のみ(BGer/BGE)。連邦行政裁判所、連邦刑事裁判所、および26 の州裁判所すべては対象外です。
- 対象期間: 2007 年~2024 年 12 月(SCD ダンプの範囲)。この期間外の判決はダンプに含まれません。
- 内容: メタデータ/判決要旨のみ — オフラインでは全文を取得できません。
- 更新の遅延: SCD ダンプは Zenodo でおよそ四半期ごとに更新されるため、オフラインデータは稼働中のインデックスより古くなります。
get_fallback_statusではキャッシュされたバージョンを確認でき、Zenodo に新しいバージョンがあるかどうかも確認できます。 - 法令参照の検索は、オフラインでは判決の論点/要旨(
topic/issue)に記載された参照のみが対象です。オフラインの引用法令インデックスはありません。 get_court_decisionのオフラインでの結果はベストエフォートです: SCD の事件 ID(docref、例:1C_517/2016)は entscheidsuche の判例識別子と異なるため、一部の検索結果は正直に解決不能と報告されます。- 応答では常に
source(live/dump)とcoverage_noteによって情報源が明示されます。サーバーが対象範囲を黙って狭めることはありません。対象外のクエリには、結果を黙って空にするのではなく、「対象外」と明示して回答します。
テスト
ユニットテストでは respx を使用してすべての HTTP 通信をモックします。プロジェクトのルートから実行してください。CI で実行される 5 つのゲートについては、check_gate_docs.py が ci.yml と照合するため、いつの間にか古くなることはありません。
PYTHONPATH=src pytest tests/ -m "not live"
python scripts/check_ruff_pin.py
ruff check src/ tests/ scripts/
ruff format --check src/ tests/ scripts/
python scripts/check_version_sync.py
python scripts/check_gate_docs.py
ライブテストはゲートではありません。実際の情報源にアクセスし、プルリクエストではなく、スケジュールに従って実行されます(live.yml)。
PYTHONPATH=src pytest tests/ -v -m live
live.yml の編集には特別な注意が必要です。GitHub が schedule を認識するのはデフォルトブランチのみであるため、変更が反映されるのはマージ後です。それより前にテストするには、手動で(workflow_dispatch により)実行してください。
オフラインフォールバックのテストでは、Zenodo からのダウンロードを respx でモックし、コミット済みの小さなフィクスチャを使用します。約 120 MB のダンプが CI でダウンロードされることはありません。
変更履歴
CHANGELOG.md を参照してください。
貢献
CONTRIBUTING.md を参照してください。
セキュリティ
セキュリティ方針と脆弱性の報告方法については、SECURITY.md を参照してください。
ライセンス
作者
Hayal Oezkan · malkreide
クレジットと関連プロジェクト
- entscheidsuche.ch — スイスの裁判所判決検索エンジン(稼働中の情報源)
- Swiss Federal Supreme Court Dataset (SCD) — オフライン時のフォールバック情報源、CC BY 4.0: Geering, F. & Merane, J. (2025). Swiss Federal Supreme Court Dataset (SCD), Version 2024-3. Zenodo. https://doi.org/10.5281/zenodo.14867950
- fedlex-mcp — スイス連邦法の MCP サーバー(法令との連携)
- zurich-opendata-mcp — チューリッヒのオープンデータ用 MCP サーバー
- Model Context Protocol — AI ツール連携のためのオープンプロトコル
インストール
uv の uvx で実行できます。クローンや手動インストールは不要です。MCP クライアントの設定に追加してください(Claude Desktop、Cursor、Windsurf では mcpServers を使用します。VS Code では .vscode/mcp.json のトップレベルにある servers キーを使用してください):
{
"mcpServers": {
"swiss-courts-mcp": {
"command": "uvx",
"args": [
"swiss-courts-mcp"
]
}
}
}
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。