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 installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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.41410ISC
- AlicenseNot gradedqualityCmaintenanceProvides 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.19MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to access official Indonesian statistical data (BPS) through MCP, providing tools for dynamic data queries, foreign trade, publications, and more.1
- AlicenseBqualityBmaintenanceCitation-first MCP server for official Indonesian financial data from IDX, BPS, and KSEI, providing tools to access company profiles, financial reports, statistical tables, and investor demographics.10MIT
Related MCP Connectors
This MCP server provides seamless access to Malaysia's government open data, including datasets, w…
Apideck Unified API MCP — 330 tools across 200+ SaaS connectors (accounting, CRM, HRIS, ATS).
One MCP for 160+ live web-data APIs — clean JSON from sites that block scrapers.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/suryast/indonesia-civic-stack'
If you have feedback or need assistance with the MCP directory API, please join our Discord server