indonesia-civic-stack
🇮🇩 indonesia-civic-stack
Produktionsreife Scraper, Normalisierer und API-Wrapper für indonesische Regierungsdatenquellen.
Die Infrastrukturebene hinter halalkah.id, legalkah.id und ein öffentliches Gut für die indonesische Civic-Tech- und Entwickler-Community.
Warum
Indonesische öffentliche Daten sind nominell offen, aber praktisch unzugänglich. Jeder Entwickler, der zivile Werkzeuge baut, löst dieselben Scraping-Probleme unabhängig voneinander: BPOM-Produktregistrierungen, BPJPH-Halal-Zertifikate, AHU-Unternehmensregister. Scraper veralten innerhalb von Monaten, wenn sich Portale ändern. Es gibt keine gemeinsame, gepflegte Schicht.
Dieses Repository ist diese Schicht. Ein pip install, um indonesische Regierungsportale abzufragen – keine maßgeschneiderten Scraper mehr.
KI-Agent zuerst
Dieses SDK ist sowohl für Menschen als auch für KI-Agenten konzipiert:
🤖 46 MCP-Tools – in Claude, GPT oder einen beliebigen MCP-kompatiblen Agenten einbinden
📋 SKILL.md – KI-Agenten-Fähigkeitenermittlung (AgentSkills-Format)
🧑💻 AGENTS.md – Architekturleitfaden für Codierungsagenten (Claude Code, Codex, Cursor)
📝 CLAUDE.md – Claude-Code-spezifische Anweisungen
✅ Typisierte Antworten –
CivicStackResponse-Envelope, niemals rohe Dictionaries🔁 Konsistente Muster – jedes Modul folgt demselben Vertrag
Related MCP server: openapi-mcp-sdk
Architektur
graph TB
subgraph "Your App"
A[halalkah.id]
B[legalkah.id]
C[Your Project]
end
subgraph "civic-stack"
SDK[Python SDK]
MCP[MCP Servers]
API[REST API]
subgraph "Shared Layer"
SC[shared/schema.py<br/>CivicStackResponse]
HC[shared/http.py<br/>Rate limiting · Retries · Proxy]
end
subgraph "Phase 1"
BPOM[bpom<br/>Food & Drug]
BPJPH[bpjph<br/>Halal Certs]
AHU[ahu<br/>Company Registry]
end
subgraph "Phase 2"
OJK[ojk<br/>Financial Licenses]
OSS[oss_nib<br/>Business ID]
LPSE[lpse<br/>Procurement]
KPU[kpu<br/>Elections]
end
subgraph "Phase 3"
LHKPN[lhkpn<br/>Wealth Declarations]
BPS[bps<br/>Statistics]
BMKG[bmkg<br/>Weather & Disasters]
SIMBG[simbg<br/>Building Permits]
end
end
subgraph "Government Portals"
P1[cekbpom.pom.go.id]
P2[sertifikasi.halal.go.id]
P3[ahu.go.id]
P4[ojk.go.id]
P5[oss.go.id]
P6[lpse.*.go.id]
P7[infopemilu.kpu.go.id]
P8[elhkpn.kpk.go.id]
P9[webapi.bps.go.id]
P10[data.bmkg.go.id]
P11[simbg.pu.go.id]
end
A & B & C --> SDK & MCP & API
SDK & MCP & API --> SC
SC --> BPOM & BPJPH & AHU & OJK & OSS & LPSE & KPU & LHKPN & BPS & BMKG & SIMBG
BPOM & BPJPH & AHU & OJK & OSS & LPSE & KPU & LHKPN & BPS & BMKG & SIMBG --> HC
BPOM --> P1
BPJPH --> P2
AHU --> P3
OJK --> P4
OSS --> P5
LPSE --> P6
KPU --> P7
LHKPN --> P8
BPS --> P9
BMKG --> P10
SIMBG --> P11Anfrageablauf
sequenceDiagram
participant App as Your App
participant SDK as Civic SDK
participant HTTP as shared/http.py
participant Proxy as Proxy (optional)
participant Portal as Gov Portal
App->>SDK: search("paracetamol")
SDK->>HTTP: civic_client(proxy_url)
Note over HTTP: Auto-reads PROXY_URL<br/>from environment
alt rewrite mode (CF Worker)
HTTP->>Proxy: GET ?url=encoded_target
Proxy->>Portal: Forwarded request
Portal-->>Proxy: HTML/JSON response
Proxy-->>HTTP: Response
else connect mode (SOCKS/HTTP)
HTTP->>Proxy: CONNECT tunnel
Proxy->>Portal: Proxied request
Portal-->>HTTP: Response
else no proxy
HTTP->>Portal: Direct request
Portal-->>HTTP: Response
end
HTTP-->>SDK: httpx.Response
SDK->>SDK: Parse + Normalize
SDK-->>App: CivicStackResponseModulstatus
Modul | Quelle | Daten | Proxy | Status |
cekbpom.pom.go.id | Lebensmittel-, Arzneimittel- und Kosmetikregistrierungen | 🌐 | ✅ Aktiv | |
cmsbl.halal.go.id | Halal-Zertifikate (über 1,98 Mio. Datensätze) | 🌐 | ✅ Aktiv – zu REST-API migriert (v1.0.0) | |
ahu.go.id | Unternehmensregister – PT, CV, Yayasan, Koperasi | 🇮🇩 | ⚠️ Seite umstrukturiert – Sucheingabe geändert (Apr. 2026) | |
Zugelassene Finanzinstitute + Waspada-Liste | 🇮🇩 | ⚠️ Portal zu SharePoint migriert (Apr. 2026) – Scraper muss neu geschrieben werden | ||
oss.go.id | Unternehmensidentität (NIB) | 🇮🇩 | ⚠️ Seite umstrukturiert – Playwright findet keine Eingabefelder (Apr. 2026) | |
spse.inaproc.id | Öffentliches Beschaffungswesen | 🇮🇩 | ✅ Aktiv – nicht mehr veraltet (v1.0.0) | |
infopemilu.kpu.go.id | Wahldaten – Kandidaten, Ergebnisse, Finanzen | 🌐 | ✅ Aktiv | |
webapi.bps.go.id | Statistische Datensätze (über 1.000) | 🌐 | ✅ Aktiv (erfordert | |
data.bmkg.go.id | Wetter-, Erdbeben- und Katastrophendaten | 🌐 | ✅ Aktiv | |
simbg.pu.go.id | Baugenehmigungen (PBG) – Multi-Portal | 🌐 | ✅ Aktiv | |
peraturan.go.id | Nationale Rechtsdatenbank – UU, PP, Perpres, Permen | 🇮🇩 | ✅ Neu – Playwright-Scraping | |
web.ksei.co.id | Wertpapierstatistiken (62 monatliche PDFs) + registrierte Wertpapiere | 🌐 | ✅ Neu – HTML-Scraping (kein Proxy erforderlich) | |
data-apbn.kemenkeu.go.id | APBN-Haushaltsthemen – Ziel/Realisierung/Erreichung | 🇮🇩 | ✅ Neu – saubere REST-JSON-API | |
elhkpn.kpk.go.id | Vermögenserklärungen (Beamte) | — | ✅ Aktiv – reCAPTCHA v3 über Playwright gelöst |
🌐 = funktioniert weltweit 🇮🇩 = erfordert indonesischen Proxy (PROXY_URL setzen)
Jedes Modul gibt denselben CivicStackResponse-Envelope zurück – Datenquellen wechseln, ohne die Anwendungslogik anzufassen.
Modulreife
Modul | Scraper | Normalisierer | MCP | Tests | Portalstatus |
bpom | ✅ | ✅ | ✅ | ✅ | ✅ |
bpjph | ✅ | ✅ | ✅ | ✅ | ✅ REST-API |
ahu | ✅ | ✅ | ✅ | ✅ | ⚠️ Seite umstrukturiert |
ojk | ✅ | ✅ | ✅ | ✅ | ⚠️ SharePoint-Migration |
oss_nib | ✅ | ✅ | ✅ | ✅ | ⚠️ Seite umstrukturiert |
lpse | ✅ | ✅ | ✅ | ✅ | 🇮🇩 geoblockt |
kpu | ✅ | ✅ | ✅ | ✅ | ✅ |
bps | ✅ | ✅ | ✅ | ✅ | ✅ |
bmkg | ✅ | ✅ | ✅ | ✅ | ✅ |
simbg | ✅ | ✅ | ✅ | ✅ | ✅ |
jdih | ✅ | ✅ | ❌ | ❌ | 🇮🇩 Playwright |
ksei | ✅ | ✅ | ❌ | ❌ | ✅ (kein Proxy erforderlich) |
djpb | ✅ | ✅ | ❌ | ❌ | ✅ REST-JSON-API |
lhkpn | ✅ | ✅ | ✅ | ✅ | ✅ Aktiv (Playwright) |
Schnellstart
Installation
pip install indonesia-civic-stack # Core SDK
pip install "indonesia-civic-stack[mcp]" # + MCP server (40 tools)
pip install "indonesia-civic-stack[api]" # + REST API (FastAPI + uvicorn)
pip install "indonesia-civic-stack[all]" # EverythingPython SDK
import asyncio
from civic_stack.bpom.scraper import search as bpom_search
from civic_stack.bmkg.scraper import get_latest_earthquake
async def main():
# Search BPOM product registry
results = await bpom_search("paracetamol")
for r in results:
if r.found:
print(r.result)
# Get latest earthquake
eq = await get_latest_earthquake()
print(eq.result) # {'date': '...', 'magnitude': '5.2', ...}
asyncio.run(main())MCP-Server (für KI-Agenten)
Alle 14 Module stellen 46 MCP-Tools für die Verwendung mit Claude, GPT oder einem beliebigen MCP-kompatiblen Agenten bereit.
# Install locally:
pip install "indonesia-civic-stack[mcp]"
claude mcp add civic-stack -- civic-stack-mcp
# Or deploy your own remote server (Railway one-click):
# See "Self-Hosted MCP Server" section belowMCP-Serverklassen unterstützen zwei Initialisierungsstile:
# Style 1: Explicit init
class BpomMCPServer(CivicStackMCPBase):
def __init__(self):
super().__init__("bpom")
# Style 2: Class attribute
class BmkgMCPServer(CivicStackMCPBase):
module_name = "bmkg"REST API
# Run all modules
uvicorn app:app --port 8000
# With API key auth (recommended)
CIVIC_API_KEY=your-secret-key uvicorn app:app --port 8000
# Individual module
uvicorn modules.bpom.app:app --port 8001
# With proxy
PROXY_URL=socks5://id-proxy:1080 uvicorn app:app --port 8000# Endpoints
GET /bpom/check/MD123456789012
GET /bpom/search?q=paracetamol
GET /bpjph/check/BPJPH-12345
GET /ahu/search?q=PT+Contoh+Indonesia
GET /ojk/check?name=Bank+BCA
GET /kpu/candidate/search?q=Joko
GET /lhkpn/search?q=Anies # ✅ reCAPTCHA v3 solved via Playwright
GET /bps/search?q=inflasi # Requires BPS_API_KEY
GET /bmkg/weather?city=jakarta
GET /simbg/search?q=Jakarta+SelatanAntwort-Envelope
Jedes Modul gibt CivicStackResponse zurück:
{
"result": {"product_name": "...", "registration_status": "ACTIVE"},
"found": true,
"status": "ACTIVE",
"confidence": 1.0,
"source_url": "https://cekbpom.pom.go.id/...",
"fetched_at": "2026-03-14T06:30:00Z",
"module": "bpom"
}Statuswerte: ACTIVE, EXPIRED, SUSPENDED, REVOKED, NOT_FOUND, ERROR.
Wenn ein Modul sein Portal nicht erreichen kann oder eine Konfiguration fehlt (z. B. BPS_API_KEY), gibt es einen Fehler-Envelope zurück, anstatt abzustürzen:
{
"result": null,
"found": false,
"status": "ERROR",
"confidence": 0.0,
"source_url": "https://webapi.bps.go.id",
"module": "bps",
"detail": "BPS_API_KEY not set. Register at https://webapi.bps.go.id/developer/register"
}Modul-Interna
civic_stack/bpom/
├── __init__.py
├── app.py # FastAPI application
├── normalizer.py # Raw HTML/JSON → structured dict
├── router.py # FastAPI routes
├── scraper.py # fetch() + search() — core logic
├── server.py # FastMCP MCP server
├── Dockerfile
└── README.mdDie shared/-Ebene bietet:
schema.py–CivicStackResponse-Pydantic-Modell, Status-Enum, Hilfskonstruktorenhttp.py–civic_client()-Factory mit Auto-Proxy, Ratenbegrenzer, exponentiellem Backoff-Retry, URL-Umschreibung für CF-Worker-Proxysmcp.py–CivicStackMCPBase-Abstrakte Basisklasse für MCP-Server
Bereitstellungshinweise
Geoblocking- und Proxy-Anforderungen
Die meisten indonesischen Regierungsportale (*.go.id) beschränken den Zugriff auf indonesische IP-Adressen. Wenn Sie außerhalb Indonesiens bereitstellen, müssen Sie PROXY_URL setzen, um Anfragen über einen indonesischen Endpunkt zu leiten.
# Option 1: Indonesian VPS/SOCKS proxy (recommended for production)
export PROXY_URL="socks5://id-proxy.example.com:1080"
export PROXY_MODE="connect"
# Option 2: CF Worker proxy (free, but limited — see below)
export PROXY_URL="https://your-proxy.workers.dev"
# PROXY_MODE auto-detects "rewrite" for *.workers.devOhne Proxy ist zu erwarten: DNS-Auflösungsfehler, Verbindungszeitüberschreitungen oder HTTP-403/404-Antworten der meisten Module.
Das SDK liest PROXY_URL automatisch aus der Umgebung – keine Codeänderungen in Scrapern oder MCP-Servern erforderlich.
Proxy-Modi
Modus |
| Funktionsweise |
|
| Standard-HTTP/SOCKS-CONNECT-Proxy über httpx-Transport |
|
| Schreibt URLs zu |
| (unset) | Direktverbindung |
Automatische Erkennung mit PROXY_MODE=connect|rewrite überschreiben.
CF Worker Proxy
Ein einsatzbereiter CF-Worker-Proxy ist in proxy/ enthalten. Bereitstellen mit:
cd proxy && npx wrangler deploy⚠️ CF-Worker-Einschränkung: Viele
.go.id-Portale befinden sich selbst hinter Cloudflare. CF-Worker, diefetch()-Aufrufe an andere CF-geschützte Ursprünge durchführen, erhalten 403/522-Fehler. Dies ist eine bekannte Cloudflare-Einschränkung.
Über CF-Worker-Proxy verifiziert:
Portal | Status | Hinweise |
data.bmkg.go.id | ✅ Funktioniert | JSON-API, nicht hinter CF |
cekbpom.pom.go.id | ❌ 403/522 | Portal ist CF-geschützt |
api.ojk.go.id | ❌ DNS tot | NXDOMAIN seit März 2026 |
infopemilu.kpu.go.id | ❌ 403 | CF-geschützt |
lpse.*.go.id | ❌ 403 | CF-geschützt |
elhkpn.kpk.go.id | ✅ 200 | reCAPTCHA v3 über Playwright-Headless-Browser gelöst |
Für die Produktion mit CF-geschützten Portalen verwenden Sie einen indonesischen VPS mit einem SOCKS5/HTTP-Proxy und setzen Sie PROXY_MODE=connect.
Testergebnisse zur Geobeschränkung (März 2026)
Getestet von drei Standorten aus, um zu ermitteln, welche Portale Geoblocking vs. WAF durchsetzen:
Portal | Sydney (AU) | Singapur | Jakarta (ID) | Bewertung |
ahu.go.id | ❌ | ✅ | ✅ | Geoblockiert (SEA+ OK) |
elhkpn.kpk.go.id | ❌ | ✅ | ✅ | Geoblockiert (SEA+ OK) |
ojk.go.id | ❌ 403 | ❌ 403 | ✅ | Nur Indonesien |
jaga.id (KPK) | ✅ | ✅ | ✅ | Keine Einschränkung |
data.bmkg.go.id | ✅ | ✅ | ✅ | Keine Einschränkung |
cekbpom.pom.go.id | ⚠️ | ⚠️ | ⚠️ | CF-geschützt (alle Standorte) |
webapi.bps.go.id | ❌ 403 | ❌ 403 | ❌ 403 | WAF, nicht geobasiert (API-Schlüssel erforderlich) |
lpse.lkpp.go.id | ❌ | ❌ | ❌ | Unzuverlässig (alle Standorte) |
coretaxdjp.pajak.go.id | ❌ | ❌ | ❌ | Unzuverlässig (alle Standorte) |
Fazit: Ein indonesischer Proxy (z. B. CloudKilat Jakarta) entsperrt OJK – das wichtigste geoblockierte Portal. Singapur entsperrt AHU + LHKPN. BPS- und LPSE-Fehler sind nicht geobezogen.
VPS-Härtungslektion
⚠️ Deaktiviere niemals die Passwort-Authentifizierung und starte sshd in einem einzigen automatisierten Skript auf einem frischen VPS neu. Wenn der SSH-Schlüssel nicht korrekt kopiert wurde, bist du ausgesperrt und hast keinen Wiederherstellungsweg außer einer Web-Konsole. Immer: (1) Schlüssel kopieren, (2) prüfen, dass der Schlüssel-Login in einer separaten Sitzung funktioniert, (3) dann die Passwort-Authentifizierung deaktivieren.
Stabilität der Portal-URLs
Indonesische Regierungsportale ändern ihre URL-Struktur häufig ohne Vorankündigung. Bekannte Änderungen Stand März 2026:
Modul | Alte URL | Neue URL | Status |
BPOM |
|
| ✅ Aktualisiert |
KPU |
|
| ✅ Aktualisiert |
BMKG |
|
| ✅ Aktualisiert |
LHKPN |
| reCAPTCHA v3 (Playwright) | 🟢 Aktiv |
Module, die 60 Tage lang ausfallen, werden als DEGRADED markiert und können archiviert werden.
Browserbasierte Module
Einige Portale erfordern einen echten Browser (JavaScript-Rendering, Anti-Bot-Schutz):
Modul | Browser | Anti-Bot |
bpjph | Playwright (Chromium) | Standard |
ahu | Playwright + Camoufox | Bot-Management (Datacenter-IP-Blockierung) |
oss_nib | Playwright (Chromium) | Standard |
Browser-Abhängigkeiten installieren:
pip install ".[playwright]"
playwright install chromium
# For AHU (optional, improves success rate):
pip install camoufox && python -m camoufox fetchAPI-Schlüssel
Modul | Schlüssel erforderlich | Env-Variable | Registrierung |
BPS | Ja |
| webapi.bps.go.id/developer/register (kostenlos) |
Alle anderen | Nein | — | — |
Ohne BPS_API_KEY gibt das BPS-Modul ein Fehler-Envelope zurück (kein Absturz):
{"status": "ERROR", "detail": "BPS_API_KEY not set. Register at ..."}MCP-Tool-Inventar
Alle 11 Module stellen insgesamt 40 MCP-Tools bereit:
Modul | Tools | Anzahl |
bpom |
| 3 |
bpjph |
| 4 |
ahu |
| 4 |
ojk |
| 4 |
oss_nib |
| 3 |
lpse |
| 4 |
kpu |
| 4 |
lhkpn |
| 4 |
bps |
| 3 |
bmkg |
| 4 |
simbg |
| 3 |
KI-Agenten-Integration
Dieses Repository ist für KI-Agenten als erstklassige Nutzer konzipiert.
Für KI-Coding-Agenten
Datei | Zweck | Agent |
Architektur, Muster, kritische Regeln, Stolperfallen | Alle Coding-Agenten | |
Befehle, Do's/Don'ts-Regeln, Styleguide | Claude Code | |
Projektregeln für Cursor | Cursor | |
Anweisungen für Copilot | GitHub Copilot | |
Modulvertrag + PR-Checkliste | Alle | |
Skill-Erkennung (AgentSkills-Format) | Skill-bewusste Agenten | |
Beispiel-Prompts + interaktive Artefakt-Rezepte | Alle KI-Agenten |
MCP-Tools verbinden (eine Option wählen)
Option A – Selbst gehosteter Remote-Server (eigene Bereitstellung):
# After deploying to Railway/Fly/Render, add to Claude Code:
claude mcp add civic-stack --transport http https://your-deployment.up.railway.app/mcp
# Or Claude Desktop — add to claude_desktop_config.json:{
"mcpServers": {
"civic-stack": {
"transport": "streamable-http",
"url": "https://your-deployment.up.railway.app/mcp"
}
}
}Hinweis: Es gibt keinen gemeinsamen gehosteten Server. Jeder Nutzer stellt seine eigene Instanz bereit, um Proxy-Einstellungen, Ratenbegrenzungen und API-Schlüssel zu kontrollieren.
Option B – Lokale Installation über pip:
pip install "indonesia-civic-stack[mcp]"
claude mcp add civic-stack -- civic-stack-mcpOption C – Repository klonen (Auto-Erkennung):
git clone https://github.com/suryast/indonesia-civic-stack.git
cd indonesia-civic-stack
pip install -e ".[mcp]"
claude # Claude Code auto-detects .mcp.json — 40 tools available immediatelyAlle drei Optionen bieten dir dieselben 40 Tools. Dann frag:
„Prüfe, ob die BPOM-Registrierung MD 123456789 noch aktiv ist" „Suche nach Unternehmen namens ‚Maju Bersama' im AHU-Register" „Was war das letzte Erdbeben in Indonesien?"
Weitere Beispiel-Prompts und interaktive Artefakt-Rezepte findest du in PROMPTS.md.
REST-API
pip install "indonesia-civic-stack[api]"
civic-stack api --port 8000
# GET http://localhost:8000/bpom/search?q=paracetamolBeispiel-Prompts
Sobald die MCP-Tools verbunden sind, probiere diese mit deinem KI-Agenten aus:
Lebensmittelsicherheit „Prüfe, ob die BPOM-Registrierungsnummer
MD 123456789noch aktiv ist" „Suche nach allen bei BPOM registrierten Paracetamol-Produkten"
Halal-Verifizierung „Ist Produkt XYZ halal-zertifiziert? Gleiche mit der BPOM-Registrierung ab" „Finde alle Halal-Zertifikate, die an PT Indofood ausgestellt wurden"
Unternehmens-Due-Diligence „Schlage PT Maju Bersama im AHU-Unternehmensregister nach und prüfe, wer die Geschäftsführer sind" „Ist dieses Unternehmen OJK-lizenziert? Prüfe sowohl das Lizenzregister als auch die Waspada-Liste (Warnliste)"
Öffentliche Finanzen „Suche LHKPN-Vermögenserklärungen für Beamte in Jakarta" „Finde öffentliche Vergabeausschreibungen für Straßenbau auf LPSE"
Katastrophen & Wetter „Was war das letzte Erdbeben in Indonesien?" „Hole die Wettervorhersage für DKI Jakarta von BMKG"
Statistiken „Finde BPS-Datensätze zu Armutsquoten nach Provinz" „Hole den Inflationsindikator für die letzten 5 Jahre"
Multi-Quellen-Abfragen „Ich möchte ein Lebensmittelunternehmen verifizieren: Prüfe AHU auf Registrierung, OJK auf Finanzlizenz, BPOM auf Produktregistrierungen und BPJPH auf Halal-Zertifikate" „Vergleiche die LHKPN-Vermögenserklärungen dieser beiden Beamten über die letzten 3 Berichtszeiträume"
Design-Entscheidungen für KI-Agenten
Einheitliches Antwort-Envelope – jedes Tool gibt
CivicStackResponsemit denselben Feldern zurück. Agenten benötigen keine modulspezifische Parsing-Logik.Fehler-Envelopes statt Ausnahmen – Agenten erhalten strukturierte Fehlerinformationen, mit denen sie arbeiten können, keine Stacktraces.
Selbstdokumentierende Tools – MCP-Toolbeschreibungen enthalten Parametertypen, erwartete Werte und Antwortformat.
Deterministische Benennung –
check_<module>,search_<module>,get_<module>_status-Muster über alle Module.
Sicherheit
Funktion | Konfiguration | Standard |
API-Schlüssel-Authentifizierung |
| Deaktiviert (offen) |
Ratenbegrenzung |
| 60 Anfragen/min pro IP |
Proxy-Allowlist |
| Jede nicht-private IP |
SSRF-Schutz | Integriert | Blockiert RFC 1918 + localhost |
Container-Benutzer | Dockerfile | Nicht-Root ( |
# Production deployment
export CIVIC_API_KEY="your-secret-key"
export CIVIC_RATE_LIMIT=30 # 30 req/min
export CIVIC_ALLOWED_PROXIES="proxy.example.com" # optional proxy allowlist
export PROXY_URL="socks5://id-proxy:1080" # Indonesian proxy
uvicorn app:app --host 0.0.0.0 --port 8000Docker
docker compose up # All modules
docker build -t civic-bpom civic_stack/bpom/ # Individual
docker run -p 8001:8000 -e CIVIC_API_KEY=secret -e PROXY_URL=socks5://proxy:1080 civic-bpomEntwicklung
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]"
playwright install chromium
pytest -v # VCR replay — no live portal calls
ruff check . # Lint
ruff format --check . # Format check
mypy shared/ # Type checkTests
pytest -v # 89 tests, VCR replay (no live calls)
pytest tests/bpom/ -v # Single module
pytest --tb=short -q # Quick summarypie title Test Coverage (89 tests)
"BPOM" : 7
"BPJPH" : 8
"AHU" : 12
"OJK" : 4
"KPU" : 5
"LPSE" : 9
"OSS-NIB" : 6
"LHKPN" : 10
"BPS" : 7
"BMKG" : 8
"SIMBG" : 7
"Schema" : 6Mitwirken
Siehe CONTRIBUTING.md. Jeder Modul-PR muss Folgendes enthalten:
fetch()undsearch(), dieCivicStackResponsezurückgebenFastAPI-Router + FastMCP-Server
3+ VCR-Test-Fixtures
Modul-README
Ein Modul, das 60 Tage lang ausfällt, wird als DEGRADED markiert und archiviert.
Verwendet von
halalkah.id – Halal-Produktverifizierung (9,57 Mio. Produkte)
legalkah.id – Prüfer für die Legalität von Finanzinstituten
datarakyat.id – Landingpage & Dokumentation
Beispielarchitekturen
Einfach: Halal-Produktprüfer
Eine Single-Page-App, die prüft, ob ein Produkt halal-zertifiziert ist. Ein Modul, kein Proxy für indonesische Nutzer erforderlich.
graph LR
subgraph Client
A[Mobile App / Web]
end
subgraph Your Server
B[FastAPI]
C[bpjph module]
end
subgraph Government Portal
D[sertifikasi.halal.go.id]
end
A -->|POST /check| B
B --> C
C -->|scrape| D
D -->|HTML| C
C -->|CivicStackResponse| B
B -->|JSON| A
style A fill:#f9f9f9,stroke:#333
style B fill:#e8f5e9,stroke:#2e7d32
style C fill:#e8f5e9,stroke:#2e7d32
style D fill:#fff3e0,stroke:#e65100# app.py — 15 lines, production-ready
from fastapi import FastAPI
from civic_stack.bpjph.scraper import fetch
app = FastAPI()
@app.get("/check/{product_id}")
async def check_halal(product_id: str):
result = await fetch(product_id)
return {"halal": result.found, "data": result.result}Mittel: Multi-Quellen-Due-Diligence-API
Ein Compliance-Tool, das ein Unternehmen über mehrere Regierungsdatenbanken hinweg abgleicht. Läuft hinter einem Proxy für den Einsatz im Ausland.
graph TB
subgraph Client
A[Compliance Dashboard]
end
subgraph Your Infrastructure
B[API Gateway]
C[Due Diligence Service]
D[ahu module]
E[ojk module]
F[bpom module]
G[oss_nib module]
H[(Redis Cache)]
end
subgraph Proxy Layer
I[CF Worker Proxy]
end
subgraph Government Portals
J[ahu.go.id]
K[www.ojk.go.id]
L[cekbpom.pom.go.id]
M[oss.go.id]
end
A -->|GET /company/:name| B
B --> C
C --> H
C --> D & E & F & G
D & E & F & G -->|via PROXY_URL| I
I --> J & K & L & M
style A fill:#f9f9f9,stroke:#333
style B fill:#e3f2fd,stroke:#1565c0
style C fill:#e8f5e9,stroke:#2e7d32
style D fill:#e8f5e9,stroke:#2e7d32
style E fill:#e8f5e9,stroke:#2e7d32
style F fill:#e8f5e9,stroke:#2e7d32
style G fill:#e8f5e9,stroke:#2e7d32
style H fill:#fce4ec,stroke:#c62828
style I fill:#fff8e1,stroke:#f57f17
style J fill:#fff3e0,stroke:#e65100
style K fill:#fff3e0,stroke:#e65100
style L fill:#fff3e0,stroke:#e65100
style M fill:#fff3e0,stroke:#e65100# due_diligence.py — parallel checks across 4 portals
import asyncio
from civic_stack.ahu.scraper import search as ahu_search
from civic_stack.ojk.scraper import search as ojk_search
from civic_stack.bpom.scraper import search as bpom_search
from civic_stack.oss_nib.scraper import search as nib_search
async def check_company(name: str) -> dict:
ahu, ojk, bpom, nib = await asyncio.gather(
ahu_search(name),
ojk_search(name),
bpom_search(name),
nib_search(name),
)
return {
"company": name,
"registered": any(r.found for r in ahu),
"ojk_licensed": any(r.found for r in ojk),
"bpom_products": len([r for r in bpom if r.found]),
"nib_valid": any(r.found for r in nib),
"risk_flags": _assess_risk(ahu, ojk, bpom, nib),
}Fortgeschritten: KI-Agent mit MCP-Tools
Ein KI-Assistent, der Fragen in natürlicher Sprache zu indonesischen Bürgerdaten mithilfe von MCP-Tools beantwortet. Der Agent entscheidet, welche Portale abgefragt werden sollen.
sequenceDiagram
participant User
participant Agent as AI Agent (Claude/GPT)
participant MCP as MCP Server
participant SDK as civic-stack modules
participant Proxy as CF Worker Proxy
participant Gov as Government Portals
User->>Agent: "Is PT Maju Bersama a legitimate company<br/>with halal certification?"
Note over Agent: Agent reasons: need AHU (company)<br/>+ BPJPH (halal) + OJK (finance)
Agent->>MCP: search_companies_ahu("PT Maju Bersama")
MCP->>SDK: ahu.search()
SDK->>Proxy: GET ahu.go.id/...
Proxy->>Gov: Forward request
Gov-->>Proxy: HTML response
Proxy-->>SDK: Response
SDK-->>MCP: CivicStackResponse
MCP-->>Agent: {found: true, status: "ACTIVE", ...}
Agent->>MCP: check_halal_cert("PT Maju Bersama")
MCP->>SDK: bpjph.fetch()
SDK->>Proxy: GET sertifikasi.halal.go.id/...
Proxy-->>SDK: Response
SDK-->>MCP: CivicStackResponse
MCP-->>Agent: {found: true, status: "ACTIVE", ...}
Agent->>MCP: check_ojk_license("PT Maju Bersama")
MCP->>SDK: ojk.fetch()
SDK-->>MCP: {found: false, status: "NOT_FOUND"}
Note over Agent: Agent synthesizes results
Agent->>User: "PT Maju Bersama is a registered company (AHU ✅)<br/>with active halal certification (BPJPH ✅).<br/>No OJK financial license found — this is normal<br/>for non-financial companies."# Connect MCP servers to Claude Desktop — one command per module
claude mcp add civic-ahu -- python -m civic_stack.ahu.server
claude mcp add civic-bpjph -- python -m civic_stack.bpjph.server
claude mcp add civic-ojk -- python -m civic_stack.ojk.server
# Or run unified REST API for HTTP-based agents
PROXY_URL=https://your-proxy.workers.dev uvicorn app:appVerwandt
indonesia-civic-signal-monitor – Anomalie-Erkennungs-Engine auf Basis dieses SDK, überwacht 11 Regierungsdatenquellen auf berichtenswerte Änderungen
indonesia-gov-apis – Referenzdokumentation für 50+ indonesische Regierungs-APIs
datarakyat.id – Projekt-Startseite mit vollständiger Moduldokumentation
Lizenz
MIT – siehe LICENSE
This server cannot be deployed
Maintenance
Related MCP Connectors
Official public & government APIs, dozens of countries: registers, statistics, open data. Keyless.
This MCP server provides seamless access to Malaysia's government open data, including datasets, w…
APIs and MCP for structured public data, web research, CAPTCHA, and source-bound data cleanup.
All HasData scraping tools in one MCP server: Google, TikTok, Instagram, maps, e-commerce and more.
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides seamless access to Malaysia's official government data catalogue, enabling developers to discover, explore, and fetch datasets from the Malaysian government's open data platform through a simple, unified interface.47 npm12ISC
- AlicenseNot gradedqualityBmaintenanceProvides a ready-to-run MCP server and Python SDK for securely interacting with Openapi.com APIs, enabling businesses to retrieve official documents and data through natural language.22MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to access official Indonesian statistical data (BPS) through MCP, providing tools for dynamic data queries, foreign trade, publications, and more.2-
- AlicenseNot gradedqualityDmaintenanceProvides a single MCP endpoint for 90+ tools across 42 backend servers (search, legal, domain, etc.) with per-call credit billing and a single API key.1MIT