indonesia-civic-stack について
indonesia-civic-stackは、インドネシアの公共データポータル向けPython SDK、統合MCPサーバー、RESTラッパーです。civic-tech開発者に共通のクライアントとレスポンス形式を提供し、各モジュールの範囲や稼働状況の制約も明記しています。
主な機能
- 0114の政府ポータルのデータ取得
- 02統合MCPツール45種
- 03Python SDKとRESTルーター11種
- 04出典情報付きの共通レスポンス形式
- 05ブラウザーとHTTPによるスクレーパー
活用シーン
- 01製品登録とハラール認証の確認
- 02企業、入札、選挙データの検索
- 03気象、地震、統計データの取得
- 04インドネシアの公共記録をcivic-techアプリに統合
MCP 対応
統合MCPサーバーは、14のポータルモジュールに対応する45の登録済みツールをMCPクライアントに公開します。ツールの登録は、ポータルの稼働や検索結果の網羅性を保証しません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx indonesia-civic-stackPROXY_URLProxy URL for accessing Indonesian government portals from outside Indonesia (e.g. Cloudflare Worker URL)BPS_API_KEYシークレットBPS Statistics API key (free registration at webapi.bps.go.id)ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
🇮🇩 indonesia-civic-stack
インドネシアの公共部門データ向けの Python SDK、MCP ツール、REST ラッパーです。 リリース 1.2.1 には 14 個のスクレイパーモジュール、45 個の統合 MCP ツール、11 個の REST モジュールルーターが含まれています。これらの数はコードを示すものであり、現在の利用可能性を示すものではありません。
インドネシアの公共データポータルでは、API、HTML 構造、ブラウザー要件、アクセス制限がそれぞれ異なります。このプロジェクトは、すべてのシビックテックアプリが独自の連携機能を構築する必要がないよう、共通のレスポンススキーマと再利用可能なクライアントを提供します。ポータルの変更によって個々の操作が引き続き動作しなくなる場合があります。結論を導く前に、レスポンスとその出所を確認してください。
モジュール一覧と成熟度
各行にはスクレイパー、正規化処理、モジュールのテストファイルがあります。「テストあり」は、モックまたは再生テストが存在することを意味し、ポータルが現在稼働していることを証明するものではありません。MCP 列は、統合版 civic_stack/server.py 内のデコレーター数を示します。
| モジュール | コードで設定されているソース | データ/方式 | MCP ツール | REST | テストあり |
|---|---|---|---|---|---|
| bpom | cekbpom.pom.go.id | 製品登録情報;HTTP HTML | 3 | Yes | Yes |
| bpjph | cmsbl.halal.go.id | ハラール認証;HTTP REST | 4 | Yes | Yes |
| ahu | ahu.go.id | 企業登記;ブラウザーヘルパー | 4 | Yes | Yes |
| ojk | www.ojk.go.id / sikapiuangmu.ojk.go.id | 機関情報と警告;HTTP + オプションのブラウザー一覧 | 4 | Yes | Yes |
| oss_nib | oss.go.id | NIB 識別情報;Playwright | 3 | Yes | Yes |
| lpse | spse.inaproc.id および設定済みポータル | ベンダー/入札;複数ポータル対応の HTTP | 4 | Yes | Yes |
| kpu | infopemilu.kpu.go.id / sirekap-obj-data.kpu.go.id | 候補者情報と2024年の選挙;HTTP JSON | 4 | Yes | Yes |
| lhkpn | elhkpn.kpk.go.id | 資産申告;Playwright 検索、HTTP PDF | 3 | Yes | Yes |
| bps | webapi.bps.go.id | 統計;HTTP API、BPS_API_KEY が必要 | 3 | Yes | Yes |
| bmkg | data.bmkg.go.id | 地震/天気;HTTP JSON/XML | 4 | Yes | Yes |
| simbg | simbg.pu.go.id およびパイロットポータル | 許可;複数ポータル対応の HTTP | 3 | Yes | Yes |
| jdih | peraturan.go.id | 法令;Playwright による新着一覧の絞り込み | 2 | No | Yes |
| ksei | web.ksei.co.id | 有価証券と統計リンク;HTTP HTML | 2 | No | Yes |
| djpb | data-apbn.kemenkeu.go.id | 予算テーマ;HTTP JSON | 2 | No | Yes |
JDIH、KSEI、DJPB は SDK と統合 MCP サーバーから利用できますが、個別の MCP サーバーや REST ルーターはありません。JDIH の検索では、新着一覧のリンクを最大50件確認します。KSEI の有価証券取得/検索では1ページ目のみを確認します。どちらも完全な登記検索ではありません。LHKPN のブラウザー検索実装があるからといって、デプロイ環境で reCAPTCHA や上流ポータルが機能するとは限りません。
現在のポータルの稼働状況は、ここでは確認されていません。 エンドポイントの状態と地域制限に記載されている、2026年3月/4月の過去の観測結果は、トラブルシューティングの参考情報であり、現在の稼働を示す証拠ではありません。HTTP 200 を返すホームページ、ローカルの /health、または成功したモック/VCR テストは、実際の登記情報の検索に成功したことを意味しません。
インストール
pip install indonesia-civic-stack # Core HTTP SDK
pip install "indonesia-civic-stack[mcp]" # + unified MCP server
pip install "indonesia-civic-stack[api]" # + FastAPI and uvicorn
pip install "indonesia-civic-stack[browser]" # + Playwright and Camoufox
pip install "indonesia-civic-stack[all]" # mcp + api + browser
ブラウザーを使う操作には、バイナリーも必要です。
playwright install chromium
python -m camoufox fetch # AHU Camoufox path
AHU、OSS NIB、JDIH、LHKPN の検索、OJK の全件一覧ヘルパーはブラウザーパスを使用します。BPJPH の現在のスクレイパーは HTTP REST を使用します。all はブラウザーのバイナリーをダウンロードせず、LHKPN のオプションの PDF パッケージも含みません。PDF からテキストを抽出するには pdfplumber を直接インストールしてください。スキャン文書用のオプションのフォールバックには anthropic と ANTHROPIC_API_KEY が必要です。このフォールバックは文書を外部 API に送信し、費用が発生する場合があります。pdf または playwright の extras はありません。SOCKS HTTP トランスポートには、追加で pip install "httpx[socks]" が必要です。
Python SDK
import asyncio
from civic_stack.bpom.scraper import search
async def main():
try:
async with asyncio.timeout(120):
records = await search("paracetamol")
except Exception as exc:
print("Could not verify:", type(exc).__name__)
return
if not records:
print("No records returned; acquisition may be unverified")
for record in records:
print(record.status, record.found, record.source_url, record.fetched_at)
if record.status == "ERROR":
print("Could not verify:", record.result)
elif record.found:
print(record.result) # Check identity, period, and domain-specific status
else:
print("No match reported within the query scope; not proof of absence")
asyncio.run(main())
すべてのスクレイパーには、モジュール固有のシグネチャを持つ fetch() と search() があります。専用ヘルパーには、BMKG の get_latest_earthquake、KPU の get_election_results、OJK の check_waspada、KSEI の get_statistics_links、DJPB の get_budget_summary があります。実際の戻り値の形式、対象範囲の制限、統合ツールラッパーに関する注意点については、使用方法と制限事項を参照してください。
応答の解釈
主要な検索では、CivicStackResponse またはエンベロープのリストが返されます。
{
"result": {"product_name": "Example", "registration_status": "ACTIVE"},
"found": true,
"status": "ACTIVE",
"confidence": 1.0,
"source_url": "https://cekbpom.pom.go.id/example",
"fetched_at": "2026-03-14T06:30:00Z",
"last_updated": null,
"module": "bpom",
"raw": null
}
これは説明用であり、実際の応答ではありません。ステータス値は ACTIVE、EXPIRED、
SUSPENDED、REVOKED、NOT_FOUND、ERROR です。エラーの詳細はトップレベルの
detail ではなく、result.detail に含まれます。一部のヘルパーはエンベロープではなく、
生のリスト/辞書、PDF 抽出データ、または URL を返します。また、ステータス用のショートカット MCP ツールには、
ソースとタイムスタンプが含まれません。すべてのツールが完全なスキーマを備えているとは限りません。
result を読み取る前に、status、found、source_url、fetched_at を確認してください。
取得時刻は公開時刻ではありません。ソースの対象期間を確認してください。
ERROR は NOT_FOUND ではありません。 現在、一部モジュールの処理では、
ネットワーク/ブラウザーのエラーも NOT_FOUND または [] にまとめられます。
そのため、結果が空、または見つからない場合でも、それだけでは取得に成功したことや
レコードが存在しないことの証明にはなりません。BPS の fetch() はキーが見つからない場合に例外を送出することがあり、
ほかの呼び出し側でも予期しない例外が発生する可能性があります。呼び出し側の境界で例外を捕捉してください。
登録が見つかっても、一般的な安全性や法的な保証にはなりません。警告リストとの一致は警告であり、推奨を意味するものではありません。 複数ポータルからの部分的な結果やスクレイパーの信頼度の値を、網羅的または権威ある確認結果として示してはいけません。
統合 MCP サーバー
civic-stack-mcp # stdio, 45 tools
python -m civic_stack.server # packaged equivalent
civic-stack mcp # CLI stdio entry point
python -m civic_stack.server --transport http --host 127.0.0.1 --port 8000
# Individual module server (where present):
python -m civic_stack.bpom.server
ローカルクライアントでは、コマンドとして civic-stack-mcp を設定してください。リポジトリの
.mcp.json では .venv/bin/python -m civic_stack.server を使用します。検出を行う前に、
その仮想環境を作成し、[mcp] をインストールしてください。検出によって依存関係がインストールされたり、
ポータルが応答することが保証されたりするわけではありません。共通のホスト型サーバーはありません。
統合 MCP ツールの一覧
| モジュール | 登録済みツール名 |
|---|---|
| bpom | check_bpom、search_bpom、get_bpom_status |
| bpjph | check_halal_cert、lookup_halal_by_product、get_halal_status、cross_reference_halal_bpom |
| ahu | lookup_company_ahu、get_company_directors、verify_company_status、search_companies_ahu |
| ojk | check_ojk_license、search_ojk_institutions、get_ojk_status、check_ojk_waspada |
| oss_nib | lookup_nib、verify_nib、search_oss_businesses |
| lpse | lookup_vendor_lpse、search_lpse_vendors、search_lpse_tenders、get_lpse_portals |
| kpu | get_candidate、search_kpu_candidates、get_election_results_kpu、get_campaign_finance_kpu |
| lhkpn | get_lhkpn、search_lhkpn、get_lhkpn_pdf |
| bps | search_bps_datasets、get_bps_indicator、list_bps_regions |
| bmkg | get_bmkg_alerts、get_weather_forecast、get_earthquake_history、get_latest_earthquake |
| simbg | lookup_building_permit、search_permits_by_area、list_simbg_portals |
| jdih | search_jdih、get_jdih |
| ksei | search_ksei、get_ksei |
| djpb | search_djpb、get_djpb |
これは登録済みの名前が45個あるという意味であり、個別に検証済みの処理が45個あるという意味ではありません。 一部のラッパーは、ツール名から想定される専用ヘルパーではなく、汎用スクレイパー関数を呼び出します。 選挙結果、選挙資金、入札、警告リスト、ポータル一覧のツールを使う前に、 ラッパーに関する注意事項をお読みください。
ツールを呼び出さずに、オフラインで登録状況を確認します。
python -c 'import asyncio; from civic_stack.server import mcp; print(len(asyncio.run(mcp.list_tools())))'
REST API
civic-stack api --host 127.0.0.1 --port 8000
uvicorn civic_stack.app:app --host 127.0.0.1 --port 8000
uvicorn civic_stack.bpom.app:app --host 127.0.0.1 --port 8001
統合アプリには11個のルーターがマウントされています。JDIH、KSEI、DJPB には REST ルートがありません。
実際のルートシグネチャは /docs または /openapi.json を開いて確認してください。例:
GET /bpom/search?q=paracetamol
GET /bpjph/search?q=kopi
GET /ahu/search?q=Contoh
GET /ojk/check/Bank%20BCA
GET /kpu/search?q=Contoh
GET /lhkpn/search?q=Contoh
GET /bps/search?q=inflasi
GET /bmkg/forecast/Jakarta
GET /bmkg/earthquake/latest
GET /simbg/search?q=Jakarta
/health が示すのはローカルアプリの状態のみであり、上流ポータルの状態は確認しません。
デプロイとセキュリティ
civic_client() は PROXY_URL を読み取り、環境変数に基づいて PROXY_MODE=connect
または rewrite を選択します。*.workers.dev URL は自動的にリライト方式を選択します。ブラウザーの
プロキシ処理は別個です。Worker のリライト URL は標準的な Chromium
プロキシではありません。AHU と OSS-NIB は CONNECT モードの場合に限り PROXY_URL にフォールバックし、JDIH は
明示的なプロキシ引数を使用し、LHKPN の検索では proxy_url
引数をブラウザーに渡しません。環境変数を設定すればすべての操作がプロキシ経由になるとは考えないでください。使用方法を参照してください。
プロキシを実行する者は、サーバーが受け取るポータルの応答を制御できます。そのため REST ルーターとスタンドアロンの AHU/OSS-NIB MCP サーバーは、呼び出し元が指定した proxy_url が PROXY_URL または CIVIC_ALLOWED_PROXIES のエントリー(カンマ区切りの完全なプロキシ URL)と完全に一致する場合に限り受け付けます。それ以外は拒否されます(HTTP 400 または ERROR エンベロープ)。プロキシはサーバー側で設定してください。
アクセスの可否は、デプロイ環境、エンドポイント、時間によって異なることがあります。過去の地域別テストから、現在のジオブロックや WAF の原因を特定することはできません。試行回数に上限を設け、認証が必要な階層を回避したり、アクセス制御に対して繰り返し再試行したりしないでください。
現在の統合 REST アプリには、API キー認証もクライアントごとのレート制限ミドルウェアも実装されていません。 CIVIC_API_KEY または CIVIC_RATE_LIMIT を設定するだけでは、どちらも有効になりません。CIVIC_ALLOWED_PROXIES は呼び出し元が指定するプロキシを制限するものであり、SDK 呼び出し用の SSRF 許可リストではありません。独自の認証、クォータ、ネットワーク制御の背後にデプロイしてください。ローカルで使用する場合はループバックにバインドしてください。モジュールの取得時に使われるレート制限機能は、公開 API の不正利用を防ぐものではありません。
Agent Skills のインストール
SKILL.md は、移植可能なスキルのエントリーポイントです。メタデータのバージョンは
"1.2.1" です。サポートされていないフロントマターキーではなく、description 内のトリガーフレーズを使用します。インストール時にはリポジトリ全体を保持する必要があります。特に
references/usage.md や同梱されたその他のリファレンス、パッケージコード、マニフェスト、
ライセンスを保持してください。インストール先のディレクトリ名は indonesia-civic-stack にしてください。
ユーザーが選択したスキルディレクトリに対応しているホストの場合:
# Set this to your host's configured directory; destination must not already exist.
git clone https://github.com/suryast/indonesia-civic-stack.git "$SKILLS_DIR/indonesia-civic-stack"
cd "$SKILLS_DIR/indonesia-civic-stack"
pip install -e ".[mcp]" # if running the bundled MCP code
SKILL.md だけをインストールしたり、パッケージ名をリリース用ワークツリーのサフィックスに変更したりしないでください。ホストによる検出と Python のインストールは別の手順です。特定のバージョンに固定してインストールする場合は、レビュー済みのリリースリビジョンを明示的に選択してください。デフォルトブランチのクローンはバージョン固定ではありません。
開発とオフライン検証
git clone https://github.com/suryast/indonesia-civic-stack.git
cd indonesia-civic-stack
python -m venv .venv && source .venv/bin/activate
pip install -e ".[all,dev]"
pytest --collect-only -q # derive current collected tests; no fixed advertised total
pytest -v # mocked/VCR replay; no live portal calls intended
pytest tests/jdih/ tests/ksei/ tests/djpb/ -v
ruff check civic_stack/ tests/ scripts/ examples/ app.py server.py
ruff format --check civic_stack/ tests/ scripts/ examples/ app.py server.py
mypy civic_stack/
JDIH、KSEI、DJPB を含む全 14 モジュールにテストファイルがあります。オフラインテストスイートの合格が検証するのは、フィクスチャ/モックであり、上流の動作ではありません。CI で実際の通信記録を保存しないでください。まずテストの分離と記録設定を実際に確認してください。
開発を始める前に AGENTS.md、CLAUDE.md、CONTRIBUTING.md を読んでください。コントリビューションガイドには、望ましい完全なモジュールの契約が記載されています。実装済みの機能範囲は、他のドキュメントにある古い一括のインベントリ記述より優先されます。
リファレンスと関連プロジェクト
- 使用方法と実装上の制限
- 過去のエンドポイントに関する所見
- 過去の地域別アクセスに関する所見
- ポータルのパターン
- プロキシの運用
- プロンプトの例
- indonesia-civic-signal-monitor
- indonesia-gov-apis
ライセンス
ルートのスキル/ドキュメントのライセンスは MIT です。LICENSE を参照してください。
モジュールごとにライセンスは異なります。モジュールのライセンスファイルを保持し、
LICENSES.md を確認してください(そこに記載された古い modules/ という名称は、現在の
civic_stack/ パッケージディレクトリを指します)。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。