i14y-mcp について
i14y-mcpは、スイスの全国メタデータカタログI14Y向けの読み取り専用MCPサーバーです。検索・照会ツールを通じて、データ提供者、データセット、API、ライセンス、統一概念を見つけられます。
主な機能
- 01カタログメタデータの検索
- 02データセット記録と配布情報の取得
- 03登録済みデータサービスとAPIの検索
- 04概念、コードリスト、提供者の閲覧
- 05ライブAPIを使う読み取り専用ツール
活用シーン
- 01トピックに関するデータ提供者の特定
- 02データセットのURLとライセンスの確認
- 03スイスの公式APIエンドポイントの検索
- 04統一概念とコードの照会
MCP 対応
MCPサーバーは、データセット、配布情報、サービス、概念、提供者など、I14Yカタログの検索と取得を行う13個の読み取り専用ツールを提供します。stdioとStreamable HTTPに対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Swiss Public Data MCP Portfolioの一部 — AI エージェントをスイスの公共データやオープンデータに接続する、オープンソースの MCP サーバー集です。 これは個人プロジェクトです。雇用主や公的機関とは関係がなく、いずれからも承認を受けておらず、いずれを代表して運営されているものでもありません。
i14y-mcp
I14Y相互運用性プラットフォーム向けMCPサーバー — スイスの国家メタデータカタログです。
🇩🇪 ドイツ語版
このサーバーが必要な理由
このポートフォリオのほかのサーバーが答えるのは、*「データは何を示しているか?」*です。 このサーバーが答えるのは、その前に尋ねるべき質問です。「このトピックのデータは誰が公開していて、どのインターフェースから利用でき、どのライセンスが適用されるのか?」
I14Yは、連邦統計局が管理する国家データカタログです。連邦、州、自治体のデータセット、登録済みAPI、公共サービス、調和された概念について、DCAT-AP-CHプロファイル(eCH-0200)を使って記述しています。
覚え方:「棚より先にカタログを。」 カタログがなければ、エージェントはデータソースの存在をあらかじめ知っている必要があります。カタログがあれば、見つけることができます。
🎯 デモの基準クエリ
「特別支援教育に関するデータを公開している機関はどこで、どのインターフェースから利用でき、どのライセンスが適用されていますか?」
search_catalog(query="Sonderpädagogik")
→ «Statistik der Sonderpädagogik» — Federal Statistical Office (BFS), theme: Bildung
get_dataset(dataset_id=...)
→ 2 distributions, licence: «Opendata BY ASK — attribution required,
commercial use only with permission from the data supplier»
→ contact: [email protected]
2回のツール呼び出しで、漠然としたトピックを機関名、ダウンロードURL、利用可能なライセンスへと具体化できます。get_datasetは配布情報、ライセンス、連絡先を1つのレコードに集約します。
デモ
アーキテクチャ
┌──────────────────────────────┐
│ MCP Host (Claude) │
└───────────────┬──────────────┘
│ stdio | streamable-http
┌───────────────▼──────────────┐
│ i14y-mcp │
│ ┌────────────────────────┐ │
│ │ server.py (13 tools) │ │
│ ├────────────────────────┤ │
│ │ mappers.py │ │ DCAT → flat, one language
│ ├────────────────────────┤ │
│ │ models.py (Pydantic) │ │ source + provenance envelope
│ ├────────────────────────┤ │
│ │ client.py │ │ retry 2s/4s/8s, no-retry 4xx
│ └────────────────────────┘ │
└───────────────┬──────────────┘
│ HTTPS, no auth
┌───────────────▼──────────────┐
│ api.i14y.admin.ch/api │
│ datasets · dataservices · │
│ concepts · publicservices · │
│ catalogs · agents · search │
└──────────────────────────────┘
アーキテクチャの決定
このサーバーは**アーキテクチャA(ライブAPIのみ)**を採用しています。
理由(2026-07-21にライブ環境で検証済み):
- すべての読み取りエンドポイントは認証なしで応答し、ページネーションも正しく機能します。
- カタログメタデータの一括ダウンロードは提供されておらず、その必要もありません。
- エラーレスポンスはRFC 7807に準拠しているため、障害の種類を判別できます。
結果:
- すべてのHTTP呼び出しで、一時的な障害が発生した場合は2秒/4秒/8秒の間隔で再試行します。
- 上流側がページ指定を無視するため、
search_catalogはクライアント側で結果数を制限します。 api_statusは空のレコードではなく、常に評価可能な状態を返します。
完全なプローブレポート:docs/probe-i14y.md。
プロジェクトのフェーズ
このサーバーは、ポートフォリオの「Read-only First」フェーズアーキテクチャにおける**フェーズ1(読み取り専用)**です。すべてのツールは読み取り専用で、認証も個人データもありません。フェーズモデルと、将来的に書き込み機能を追加する場合の前提条件については、docs/roadmap.mdを参照してください。
ツール
| ツール | 目的 |
|---|---|
search_catalog | カタログを全文検索します。エントリーポイントです。 |
list_datasets | ページネーションに対応したデータセット一覧です(検索とは異なり、完全な一覧を取得できます)。 |
get_dataset | 1つのデータセットの完全なメタデータレコードです。 |
get_dataset_distributions | ダウンロードURL、形式、ライセンスを取得します。 |
list_data_services | エンドポイントURL付きのスイス公式API一覧です。 |
get_data_service | 登録済みインターフェース1つの完全なレコードです。 |
list_public_services | 市民向け行政サービスの一覧です。 |
list_concepts | 調和された概念とコードリストの一覧です。 |
get_concept | 1つの概念定義を取得します。 |
search_codelist_entries | コードリスト内の個々のコードを検索します。 |
list_publishers | スイスUID付きの公開機関一覧です。 |
list_catalogs | 提供元カタログの一覧です。 |
api_status | 縮退運転に対応した到達性チェックです。 |
すべてのツールにはreadOnlyHint: trueが注釈されています。上流APIには書き込み操作もありますが、意図的に公開していません。
MCP のプリミティブ
このサーバーが公開するのはツールのみで、リソースやプロンプトはありません。これは意図的な選択であり、欠落ではありません。I14Y はフリーテキスト検索と不透明な UUID で照会するため、MCP リソースにきれいに対応付けられる、小さく安定したアドレス指定可能な URI の集合がありません。また、このサーバーには独自のプロンプトテンプレートもありません。すべてのツールは読み取り専用かつ冪等です。将来、安定したエントリーポイント(例:固定テーマリスト)が現れた場合は、リソースの候補になります。
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 の更新で、どちらかが知らないうちに変わることはありません。ハンドシェイクの上限は、定数名を参照するのではなく、組み立てられた ASGI スタックを通した実際の initialize に基づいて測定されます。
SDK の LATEST_PROTOCOL_VERSION はハンドシェイク時代ではなく、モダンな時代のエイリアスであることに注意してください。これだけに固定すると、現在のクライアントが実際にネゴシエートする時代が変更可能なままになります。
現行リビジョンでサーバーが提供するもの
2026-07-28では、ディスカバリーをinitializeハンドシェイクからserver/discoverとリクエストごとの_metaエンベロープに移し、キャッシュ可能なすべての結果に鮮度ヒントを付与します。このサーバーがこれらのインターフェースで提供する内容は、設定を読み返すのではなく、組み立てられたスタックを通じて、またstdioでは実際のサブプロセスを通じて、tests/test_spec_2026_07_28.pyで測定されます。
| インターフェース | このサーバーが返す内容 |
|---|---|
serverInfo、すべての現行リビジョンのレスポンスに付与 | 名前、表示タイトル、説明、ウェブサイト、インストール済みの配布バージョン。送信するUser-Agentに含まれるバージョンと同じです |
server/discover → instructions | ツールを呼び出す順序に加え、単一のツール説明では分からないI14Yの2つの特性 |
ttlMs / cacheScope | このサーバーが応答する、キャッシュ可能な5つすべてのメソッドで300秒、public |
tools[].title | ツールごとの表示名です。クライアントにはsearch_codelist_entriesではなく「概念のコードリストを検索」と表示されます |
鮮度ヒントは見かけだけのものではありません。何も設定しない場合、SDKはttlMs: 0, cacheScope: private、つまり「すでに期限切れで、共有不可」を返します。これは、インポート時に固定されてプロセス実行中に変更されないディレクトリに対する動作です。
どちらのトランスポートも現行リビジョンに対応しています。HTTPはストリーム可能なHTTPセッションマネージャーを介して、stdioはデフォルトであり、uvx i14y-mcpが起動するもので、同じ新旧両対応のループを介して提供されます。一方の結果をもう一方の根拠にはできないため、両方を測定します。
このサーバーが通知するものの、使用していない機能が1つあります。 2026-07-28では、listChangedフラグとresources.subscribeは、subscriptions/listenが提供されているかどうかだけで決まり、SDKはそのハンドラーを無条件に設定します。そのため、server/discoverはインポート時に固定されるツールリストに対してlistChanged: trueを報告し、空のリソースリストに対するサブスクリプション機能も報告します。変更通知が送られることはありません。これはパブリックAPIから切り替えられません。切り替えるにはserver/discoverハンドラー全体を置き換えるしかなく、そうすると自らの機能について別の事実が生じるため、取り繕わずテストで固定しています。
更新ポリシー。 ゲートに失敗した場合は、定数をむやみに編集しないでください。2つのリビジョン間の仕様変更履歴を読み、サーバーが引き続き正常に動作することを確認してから、定数、このセクション、README.de.md、CHANGELOG.mdをまとめて更新してください。
インストール
uvx i14y-mcp
または、ソースからインストールします。
git clone https://github.com/malkreide/i14y-mcp
cd i14y-mcp
pip install -e ".[dev]"
Claude Desktop
{
"mcpServers": {
"i14y": {
"command": "uvx",
"args": ["i14y-mcp"]
}
}
}
リモートデプロイ(Render、Railway)
I14Y_MCP_TRANSPORT=streamable-http HOST=0.0.0.0 PORT=8000 i14y-mcp
I14Y_MCP_TRANSPORTには、stdio(エントリーポイント自体のデフォルト)、streamable-http(httpは同義語)、またはsseを指定できます。HTTPトランスポートはHOSTにバインドします。デフォルトは127.0.0.1(ループバック)です。PaaSでポートを公開するにはHOST=0.0.0.0を設定してください(コンテナーイメージではすでに両方を設定しています)。
コネクターURL:https://<host>/mcp
Claude.aiのカスタムコネクターはストリーム可能なHTTPを使用し、このトランスポートは/mcpという1つのパスだけを提供します。sseは旧式のトランスポートで、代わりに/sseと/messagesを提供します。組み立てられたアプリで測定したところ、POST /mcpはストリーム可能なHTTPでは200を返し、こちらでは404を返します。そのため、コンテナーイメージのデフォルトはstreamable-httpです。SSEデプロイメントを指定したコネクターは404を受け取り、ハンドシェイクを完了できません。
I14Y_MCP_ALLOWED_HOSTS — パブリックデプロイで必須
サーバーへのアクセスに使用するホスト名を、カンマ区切りで指定します。 ホスト名のみを指定し、スキームとポートは含めません。
I14Y_MCP_ALLOWED_HOSTS=i14y-mcp.up.railway.app,mcp.example.ch
値は受信した Host ヘッダーと文字列どおりに照合されるため、
https://i14y-mcp.up.railway.app や末尾の :443 は一致せず、すべての
リクエストが HTTP 421 Invalid Host header で失敗します。TLS 経由ではブラウザーから
ホスト名のみが送信されます。標準以外のポートには、SDK で唯一サポートされているワイルドカード形式の
host:* が必要です。ループバックはどちらの場合も引き続きアクセス可能なため、コンテナーのヘルスチェックには影響しません。
ループバック以外にバインドした状態で未設定にしても、安全な値にフォールバックするわけではありません。 サーバーはアクセスに使われる名前を推測できず、推測したリストではすべての実際のリクエストが拒否されるため、 Host チェックを完全に無効にし、その旨をログに記録します。
dns_rebinding_protection_off
railway.json
railway.json では、デプロイ時に誤りがないように指定する必要があるビルド設定を
1 つ固定しています。
{ "build": { "builder": "DOCKERFILE", "dockerfilePath": "Dockerfile" } }
別のビルダーを使うと、Railway は Dockerfile を参照しません。起動コマンドは独自に導出され、
I14Y_MCP_TRANSPORT もどこにも設定されないため、main() は stdio 分岐に進みます。
コンテナーは実行されますが、ポートを開かず、失敗するヘルスチェックだけがその痕跡となります。
tests/test_entrypoint.py では、この設定が変更された時点でテストが失敗します。
このファイルに意図的に含めていない項目が 2 つあります。
- 環境変数は含めません。 Railway のスキーマには、どの階層にも環境変数用のキーがないため、
I14Y_MCP_ALLOWED_HOSTSとI14Y_MCP_TRANSPORTはサービス変数に設定する必要があります。注意すべきなのは、 スキーマが 値 は検証する一方で、独自に追加されたキー はそのまま通してしまうことです。"variables": { … }ブロックを追加しても検証を通過し、エディターにも警告は表示されず、Railway はその設定を無視します。 テストでは、このようなキーを拒否します。 healthcheckPathは含めません。 アプリ全体を構成した状態で確認したところ、GET に 2xx で応答するパスはありません。/と/healthは 404、/mcpはセッションがない場合は 400、別のHostの場合は 421 になります。 いずれかをヘルスチェック先に指定すると、デプロイが異常と判断されてロールバックされます。 代わりに、Dockerfile の TCP チェックが適切に機能します。サーバーに実際のヘルスチェック用ルートが追加された場合は、 このキーを設定できます。その際は、指定したパスが実際に応答することをテストで必須とします。
CORS では Mcp-Session-Id ヘッダーを公開し、ブラウザーの MCP クライアントがセッションを維持できるようにします。
サーバーへの呼び出しを許可するブラウザーオリジンは、カンマ区切りリストの I14Y_MCP_CORS_ORIGINS で指定します。
未設定の場合、ブラウザークライアントは一切許可されません。これがデフォルトです。
* も引き続き使用できますが、警告がログに記録されます。stdio などのブラウザー以外のクライアントには、どちらの場合も影響しません。
Docker
docker compose up --build # Streamable HTTP on http://localhost:8000/mcp
このイメージは、セキュリティを強化したマルチステージビルドです。非 root ユーザーとして実行され、
ビルドツールは含まず、シークレットも不要です(API は認証を必要としません)。詳細は
Dockerfile と compose.yaml を参照してください。
結合キー
I14Y はコネクター層です。2 つの識別子により、ポートフォリオの他の要素と組み合わせられます。
| キー | フィールド | 結合先 |
|---|---|---|
| スイス UID | Publisher.uid | register-mcp(Zefix) |
| エンドポイント URL | DataServiceSummary.endpoint_urls | この API をラップするポートフォリオ内の任意のサーバー |
既知の制限事項
2026-07-21 にライブで検証済みです。
- 検索インデックスがカタログのおよそ半分しか網羅していません。
search_catalogは最大 1013 件のレコードを返しますが、list_datasetsでは約 2003 件に達します。網羅性が重要な場合は、list_datasetsを使用してください。 - 検索結果はデータセットのみです。
types=["Concept"]またはtypes=["DataService"]でフィルタリングすると、これらのエンティティが存在していても 結果は 0 件になります。代わりにlist_conceptsとlist_data_servicesを使用してください。 - 上流は検索時のページ指定を無視します。 常に結果セット全体が返されます。このサーバーでは 200 件に上限を設定し、
truncated: trueを指定しています。 - ライセンスはデータセット単位ではなく、配布物ごとに異なります。 多くは
«Opendata BY ASK» で、帰属表示が必要であり、商用利用が制限されます。
再利用する前に、必ず
licenceフィールドを確認してください。 - 一部のメタデータフィールドは空欄です。 提供頻度、時間的範囲、配布形式は任意項目であり、公開者によって設定されていないことがよくあります。これはカタログのデータ品質に関する特性であり、このサーバーのバグではありません。
- エンドポイントがあるすべてのエントリに URL があるわけではありません。 URI のない
«OpenAPI Spezifikation» のみのラベルが付いたエントリは、破棄されず、
(no URI) <label>として表示されます。
テスト
PYTHONPATH=src pytest tests/ -m "not live" # offline, used in CI
PYTHONPATH=src pytest tests/ -m "live" # hits the real API
PYTHONPATH=src pytest tests/ # everything
python -m ruff check src tests
ライブテストは飾りではありません。プローブレポートの項目 4 で、言語オブジェクトを
label の下にネストしているキーワードが、ユニットテストがすでにすべて成功した後に、
ライブテストで検出されました。
コントリビューション
基本ルール(読み取り専用、単一の外部接続先、シークレットを含めない)とローカルの開発サイクルについては、CONTRIBUTING.md を参照してください。メンテナー向けに、PyPI / MCP Registry のリリースプロセスについては PUBLISHING.md を参照してください。
セキュリティ
セキュリティ対策と脆弱性の報告方法については、SECURITY.md を参照してください。
ライセンス
MIT ライセンス — LICENSE を参照してください。カタログデータには、各公開者が定めた条件が引き続き適用されます。
作者
Hayal Oezkan · github.com/malkreide
クレジットと関連プロジェクト
- データ:I14Y Interoperability Platform、Federal Statistical Office (BFS)
- 標準:eCH-0200 / DCAT-AP-CH
- ソースの発見方法は rnckp/awesome-ogd-switzerland に着想を得ています
- ポートフォリオ:swiss-public-data-mcp
- プロトコル:Model Context Protocol
ライセンス:MIT。カタログデータには、各公開者が定めた条件が引き続き適用されます。
MCP Registry
この PyPI パッケージを GitHub 名前空間に紐付けるために、MCP Registry が使用する所有権マーカー:
mcp-name: io.github.malkreide/i14y-mcp
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。