zh-education-mcp について
zh-education-mcpは、教育データを扱う分析者向けのMCPサーバーで、チューリッヒ州のBISTA公開APIに接続します。APIキー不要で、学区、学校種別、国籍、居住地別の集計統計を提供します。
主な機能
- 01学区別の生徒数推移
- 02州全体の学習者統計
- 03中等学校の生徒構成
- 04学校コミュニティ別の国籍構成
- 05自治体別の卒業率
- 06stdioとHTTPのトランスポート
活用シーン
- 01Letziなどの学区間で生徒数推移を比較
- 02Sek A・B・Cの人数を確認
- 03学校コミュニティ別の国籍構成を調査
- 04チューリッヒ市の卒業率を確認
MCP 対応
MCPサーバーとして、BISTA公開APIに基づく8つの読み取り専用教育統計ツールを公開します。stdioとStreamable HTTPに対応しています。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
🇨🇭 スイス公共データ MCP ポートフォリオの一部です
📊 zh-education-mcp
チューリッヒ州およびチューリッヒ市の教育統計(BISTA)向け MCP サーバー
概要
zh-education-mcp は、AI アシスタントを**チューリッヒ州教育統計(Bildungsstatistik Kanton Zürich、BISTA)**に接続します。これはチューリッヒ州の公式教育統計です。生徒数、学区の推移、中等教育機関のプロフィール、国籍別の内訳、ギムナジウム卒業率に構造化された形でアクセスできます。
| データソース | データ | API |
|---|---|---|
| BISTA Kanton Zürich | 学習者統計(Volksschule、Mittelschulen、Maturität) | REST/CSV |
すべてのデータはBISTA 公開 API(bista.zh.ch/basicapi/ogd/)から取得します。API キーは不要です。データは毎年 9 月 15 日(基準日)に更新されます。
デモの質問例: 「過去 5 年間で、学区 Letzi の生徒数はどのように推移しましたか?」
デモ
特徴
- 📊 8 個のツールですべての学校段階の教育データを取得
- 🔍 学区の推移 — 2000 年から現在までのすべての Schulkreise(Letzi、Glattal、Schwamendingen、Oerlikon、Uto、Waidberg、Zürichberg)の生徒数
- 🏫 中等教育機関のプロフィール — 要件の種類別(Sek A/B/C、Mittelschule、特別学級)の内訳
- 🌐 国籍の構成 — 各学校区で生徒数の多い上位の国籍
- 🎓 ギムナジウム卒業率 — 市町村、地区、州別の Maturitätsquote
- 📈 州全体の概要 — 学校段階、種類、性別、国籍別のすべての学習者
- 🏠 居住地に基づく推移 — 居住地(Bezirk / Gemeinde)別の生徒数
- 🏛️ Mittelschulen — ギムナジウム、FMS、HMS の統計
- 🔓 API キー不要 — すべてのデータは CC BY 4.0 ライセンス
- ☁️ 2 種類のトランスポート — stdio(Claude Desktop)と Streamable HTTP(クラウド)
前提条件
- Python 3.11+
- uv(推奨)または pip
インストール
# Clone the repository
git clone https://github.com/malkreide/zh-education-mcp.git
cd zh-education-mcp
# Install
pip install -e .
# or with uv:
uv pip install -e .
または uvx を使います(永続的なインストールは不要です)。
uvx zh-education-mcp
クイックスタート
# stdio (for Claude Desktop)
python -m zh_education_mcp.server
# Streamable HTTP (port 8000)
python -m zh_education_mcp.server --http --port 8000
Claude Desktop ですぐに試せます。
「Wie hat sich die Lernendenzahl im Schulkreis Letzi entwickelt?」 「Zeige die Maturitätsquote der Stadt Zürich」 「Welche Nationalitäten sind in Adliswil am häufigsten?」
→ 対象別のその他のユースケース →
設定
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json(macOS)または %APPDATA%\Claude\claude_desktop_config.json(Windows)を編集します。
{
"mcpServers": {
"zh-education": {
"command": "python",
"args": ["-m", "zh_education_mcp.server"]
}
}
}
または uvx を使います。
{
"mcpServers": {
"zh-education": {
"command": "uvx",
"args": ["zh-education-mcp"]
}
}
}
設定ファイルの場所:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
クラウドへのデプロイ(ブラウザーアクセス向けの Streamable HTTP)
ブラウザー版の claude.ai で使用する場合(ローカルソフトウェアがない管理対象ワークステーションなど):
Render.com(推奨):
- リポジトリを GitHub にプッシュするか、フォークします
- render.com で、New Web Service → ランタイムに Docker を選択します(提供されている
Dockerfileを使用します) - 環境変数を設定します:
MCP_TRANSPORT=streamable-http、MCP_HOST=0.0.0.0、MCP_PORT=8000、MCP_CORS_ORIGINS=https://claude.ai - claude.ai の Settings → MCP Servers で、
https://your-app.onrender.com/mcpを追加します
💡 「開発者のノート PC では stdio、ブラウザーでは Streamable HTTP を使用します。」
ヘルスプローブ:GET /health。デプロイの完全なガイド(コンテナー、負荷分散、CORS、
リソース制限):docs/deployment.md。
利用可能なツール
| ツール | 説明 |
|---|---|
zh_edu_list_schulgemeinden | チューリッヒ州のすべての学校コミュニティ/Schulkreis の一覧 |
zh_edu_schulkreis_trend | Schulkreis 別の児童・生徒数の推移(2000 年〜現在) |
zh_edu_overview | 学校段階別の州全体の学習者の概要 |
zh_edu_sek1_profil | 前期中等教育 I のプロフィール(Sek A/B/C の内訳) |
zh_edu_staatsangehoerigkeiten | 学校コミュニティごとの児童・生徒の国籍構成 |
zh_edu_maturitaetsquote | 自治体/地区別のギムナジウム卒業率 |
zh_edu_wohnort_trend | 居住地に基づく学習者数の推移(Bezirk / Gemeinde) |
zh_edu_mittelschulen | 中等学校の統計(Gymnasium、FMS、HMS) |
使用例
| クエリ | ツール |
|---|---|
| 「チューリッヒのすべての Schulkreis を一覧表示して」 | zh_edu_list_schulgemeinden |
| 「Letzi の 5 年間の児童・生徒数の推移」 | zh_edu_schulkreis_trend |
| 「Winterthur では Sek A と Sek B の生徒はそれぞれ何人?」 | zh_edu_sek1_profil |
| 「Zürich-Letzi で多い国籍」 | zh_edu_staatsangehoerigkeiten |
| 「Stadt Zürich の Maturitätsquote」 | zh_edu_maturitaetsquote |
アーキテクチャ
┌─────────────────┐ ┌──────────────────────────────┐ ┌──────────────────────────┐
│ Claude / AI │────▶│ zh-education-mcp │────▶│ BISTA Kanton Zürich │
│ (MCP Host) │◀────│ (MCP Server) │◀────│ REST/CSV (Public API) │
└─────────────────┘ │ │ └──────────────────────────┘
│ 8 Tools │
│ Stdio | Streamable HTTP │
│ 24h Cache │
│ No authentication required │
└──────────────────────────────┘
データソースの特性
| ソース | プロトコル | 対象範囲 | 認証 | 更新 |
|---|---|---|---|---|
| BISTA Kanton ZH | REST/CSV | 学習者の統計、2000 年〜現在 | なし | 年次(9 月 15 日) |
プロジェクト構成
zh-education-mcp/
├── src/zh_education_mcp/
│ ├── __init__.py # Package
│ ├── config.py # ENV settings (MCP_*)
│ ├── constants.py # API base, endpoints, timeouts
│ ├── logging_setup.py # structured stderr logging
│ ├── identity.py # server identity for `_meta` / `server/discover`
│ ├── provenance.py # response envelope, license attribution
│ ├── http_client.py # egress guard, connection pool, lifespan
│ ├── data.py # cache, CSV fetch, filters, error handling
│ ├── models.py # Pydantic input models
│ ├── tools.py # FastMCP instance, 8 tools, 2 resources
│ └── server.py # thin composition layer + entrypoint
├── tests/
│ └── test_server.py # Unit tests (mocked HTTP with respx)
├── docs/ # deployment, security, egress, roadmap, …
├── Dockerfile # multi-stage, non-root, healthcheck
├── docker-compose.yml # resource limits, read-only rootfs
├── .github/workflows/ci.yml # GitHub Actions (Python 3.11/3.12/3.13)
├── .github/dependabot.yml # monthly dependency updates
├── pyproject.toml
├── CHANGELOG.md
├── CONTRIBUTING.md # + CONTRIBUTING.de.md
├── SECURITY.md # + SECURITY.de.md
├── LICENSE
├── README.md # This file (English)
└── README.de.md # German version
既知の制限事項
- 年次更新のみ: BISTA データは年に 1 回更新されます(基準日:9 月 15 日)。24 時間のインメモリーキャッシュはこの更新サイクルに合わせています。
- CSV ベースの API: BISTA API は CSV データを返します。大規模なデータセットは解析に少し時間がかかる場合があります。
- 学校コミュニティ名: 名前は完全一致する必要があります。有効な名前を確認するには
zh_edu_list_schulgemeindenを使用してください。
安全性と制限
| 項目 | 詳細 |
|---|---|
| 個人データなし | BISTA の統計は集計データであり、個々の児童・生徒のデータが公開またはアクセス可能になることはありません。すべての数値は学校コミュニティ単位で匿名化されています。 |
| 読み取り専用 | すべてのツールは読み取り専用です(readOnlyHint: true)。サーバーはデータの変更、削除、書き込みを行えません。 |
| 認証なし | BISTA API は完全に公開されています。API キー、トークン、認証情報が保存または送信されることはありません。 |
| レート制限 | BISTA API に文書化されたレート制限はありませんが、サーバーはリクエストを最小限に抑えるため、24 時間のインメモリーキャッシュを使用します。責任を持ってご利用ください。 |
| データライセンス | すべてのデータは、チューリッヒ州により CC BY 4.0 の下で公開されています。クレジット表記:Bildungsstatistik Kanton Zürich (BISTA)。 |
| 利用規約 | 利用には BISTA の利用規約が適用されます。この MCP サーバーは独立したオープンソースプロジェクトであり、チューリッヒ州とは提携していません。 |
| AI 出力に関する免責事項 | 統計データは BISTA API からそのまま渡されます。AI が生成した解釈や要約は、BISTA 公式ポータルで確認してください。 |
テスト
# Unit tests (no API calls)
PYTHONPATH=src pytest tests/ -m "not live"
# Integration tests (live API calls)
pytest tests/ -m "live"
ライブテストスイートはスケジュール実行も行います。毎週月曜日 05:23 UTC に実行されるほか、オンデマンドでも実行できます(live-tests.yml)。失敗すると upstream ラベル付きの issue が作成され、成功するとその issue がクローズされます。-m "not live" はテストの実行場所ではなく、BISTA に関する誤った前提と矛盾する可能性があるテストは、ここにあるこの 3 つだけです。詳しくは
CONTRIBUTING をご覧ください。
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 はハンドシェイク時代ではなく、モダン時代の別名である点に注意してください。これだけを基準に固定すると、現在のクライアントが実際にネゴシエートする時代が変更される余地を残してしまいます。
モダン時代にサーバー自体が提供するもの
リビジョンへの対応は SDK の役目です。サーバーが提供しなければならないものを以下に示します。定数ではなく、組み立て済みの ASGI スタックを通した実際のリクエストに対して
tests/test_modern_protocol.py で測定しています。
2026-07-28 が要求するもの | このサーバーでの提供方法 |
|---|---|
すべての結果に付与する serverInfo スタンプ(spec #3002) | 名前、タイトル、バージョン、説明、ウェブサイトをパッケージメタデータから取得します。詳しくは identity.py をご覧ください。 |
server/discover(「サーバーは必ず実装しなければならない」) | supportedVersions、capabilities、instructions を返します。 |
モデル向けの instructions | 基準日、非表示にする少数の件数、出典表示の義務、読み取り専用の範囲を指定します。意図的に、どのツールの説明にも含まれていない情報を記載しています。 |
すべての結果の resultType | SDK によって設定され、ここでワイヤ上の値を検証します。 |
エンベロープとヘッダーの検証(Mcp-Method、Mcp-Name、Mcp-Protocol-Version) | 矛盾するヘッダーは -32020 で拒否され、エンベロープがない場合は -32602 で拒否されます。 |
| 鮮度ヒント(SEP-2549) | キャッシュ可能なすべての一覧表示メソッドに ttlMs 300,000/cacheScope public を設定します。resources/read には意図的に設定しません。 |
アイデンティティは src/ で管理されていません。バージョン、説明、ウェブサイトは配布メタデータ、すなわち check_version_sync.py が許可する唯一の情報源である pyproject.toml から取得されます。このリビジョンより前は、サーバーはモダン時代のすべての結果に version: "" をスタンプしていました。
更新ポリシー。 ゲートに失敗した場合は、定数をむやみに編集しないでください。2 つのリビジョン間の仕様変更履歴を確認し、サーバーが引き続き正常に動作することを検証してから、定数、このセクション、README.de.md、CHANGELOG.md をまとめて更新してください。
プロジェクトのフェーズ: フェーズ 1 — 読み取り専用(すべてのツールで readOnlyHint: true)。docs/roadmap.md をご覧ください。
リリース
公開は GitHub リリース(release: published →
publish.yml)によって実行されます:ビルド → ゲートチェック → PyPI → MCP Registry。
ゲートチェック(check_release_artifacts.py)はアップロード前に実行され、ソースではなくビルド済みの wheel を検査します。
- wheel の METADATA に
mcp-name:マーカー(HTML コメント。このファイルの末尾を参照)がちょうど 1 つあること。MCP Registry はこれによって PyPI の所有権を確認します。また、server.jsonのnameと一致している必要があります server.jsonのdescriptionが 100 文字以下であること。超えている場合、Registry は422を返しますが、その時点では PyPI へのアップロードはすでに成功していますserver.jsonのバージョンがpyproject.tomlのバージョンと一致し、git タグが実際にビルドされたバージョンと一致していること
ゲートチェックをアップロードの前に行うのは、アップロード後には修正できないためです。PyPI のバージョンは変更できないため、修正するにはバージョンを上げる必要があります。
**この README を編集する場合:**最下部のマーカーはパッケージの説明の一部として配布されます(pyproject.toml の readme = "README.md")。削除するとゲートチェックに失敗します。README.de.md にはマーカーがなく、公開されません。上記のバージョンバッジは、すべてのプルリクエストで check_version_sync.py によって pyproject.toml および server.json と照合されます。
変更履歴
CHANGELOG.md を参照してください
コントリビューション
CONTRIBUTING.md · 🇩🇪 貢献する を参照してください
セキュリティ
SECURITY.md · 🇩🇪 セキュリティ を参照してください
ライセンス
MIT License — LICENSE を参照してください
作者
Hayal Oezkan · malkreide
クレジットと関連プロジェクト
- BISTA: pub.bista.zh.ch — チューリッヒ州教育統計(CC BY 4.0)
- プロトコル: Model Context Protocol — Anthropic / Linux Foundation
- 関連: zurich-opendata-mcp — チューリッヒ市のオープンデータ(駐車場、天気、議会)
- 関連: swiss-cultural-heritage-mcp — スイスの文化遺産データ
- 関連: fedlex-mcp — スイス連邦法
- ポートフォリオ: Swiss Public Data MCP Portfolio
インストール
uv の uvx を使って実行できます。クローンや手動インストールは不要です。MCP クライアントの設定に追加してください(Claude Desktop、Cursor、Windsurf では mcpServers を使用します。VS Code の場合は .vscode/mcp.json でトップレベルの servers キーを使用します)。
{
"mcpServers": {
"zh-education-mcp": {
"command": "uvx",
"args": [
"zh-education-mcp"
]
}
}
}
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。