Skip to main content
Glama
suryast

indonesia-civic-stack

by suryast

🇮🇩 indonesia-civic-stack

PyPI MCP Registry CI Python License

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 AntwortenCivicStackResponse-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 --> P11

Anfrageablauf

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: CivicStackResponse

Modulstatus

Modul

Quelle

Daten

Proxy

Status

bpom

cekbpom.pom.go.id

Lebensmittel-, Arzneimittel- und Kosmetikregistrierungen

🌐

✅ Aktiv

bpjph

cmsbl.halal.go.id

Halal-Zertifikate (über 1,98 Mio. Datensätze)

🌐

✅ Aktiv – zu REST-API migriert (v1.0.0)

ahu

ahu.go.id

Unternehmensregister – PT, CV, Yayasan, Koperasi

🇮🇩

⚠️ Seite umstrukturiert – Sucheingabe geändert (Apr. 2026)

ojk

www.ojk.go.id/waspada-investasi

Zugelassene Finanzinstitute + Waspada-Liste

🇮🇩

⚠️ Portal zu SharePoint migriert (Apr. 2026) – Scraper muss neu geschrieben werden

oss_nib

oss.go.id

Unternehmensidentität (NIB)

🇮🇩

⚠️ Seite umstrukturiert – Playwright findet keine Eingabefelder (Apr. 2026)

lpse

spse.inaproc.id

Öffentliches Beschaffungswesen

🇮🇩

✅ Aktiv – nicht mehr veraltet (v1.0.0)

kpu

infopemilu.kpu.go.id

Wahldaten – Kandidaten, Ergebnisse, Finanzen

🌐

✅ Aktiv

bps

webapi.bps.go.id

Statistische Datensätze (über 1.000)

🌐

✅ Aktiv (erfordert BPS_API_KEY)

bmkg

data.bmkg.go.id

Wetter-, Erdbeben- und Katastrophendaten

🌐

✅ Aktiv

simbg

simbg.pu.go.id

Baugenehmigungen (PBG) – Multi-Portal

🌐

✅ Aktiv

jdih

peraturan.go.id

Nationale Rechtsdatenbank – UU, PP, Perpres, Permen

🇮🇩

Neu – Playwright-Scraping

ksei

web.ksei.co.id

Wertpapierstatistiken (62 monatliche PDFs) + registrierte Wertpapiere

🌐

Neu – HTML-Scraping (kein Proxy erforderlich)

djpb

data-apbn.kemenkeu.go.id

APBN-Haushaltsthemen – Ziel/Realisierung/Erreichung

🇮🇩

Neu – saubere REST-JSON-API

lhkpn

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]"   # Everything

Python 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 below

MCP-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+Selatan

Antwort-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.md

Die shared/-Ebene bietet:

  • schema.pyCivicStackResponse-Pydantic-Modell, Status-Enum, Hilfskonstruktoren

  • http.pycivic_client()-Factory mit Auto-Proxy, Ratenbegrenzer, exponentiellem Backoff-Retry, URL-Umschreibung für CF-Worker-Proxys

  • mcp.pyCivicStackMCPBase-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.dev

Ohne 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

PROXY_URL-Beispiel

Funktionsweise

connect

socks5://id-proxy:1080

Standard-HTTP/SOCKS-CONNECT-Proxy über httpx-Transport

rewrite

https://x.workers.dev

Schreibt URLs zu ?url=<target> um (automatisch erkannt für *.workers.dev)

none

(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, die fetch()-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

/index.php/home/produk/1/{keyword}/...

/all-produk?q={keyword}

✅ Aktualisiert

KPU

/Pemilu/caleg/list

/Pemilu/Peserta_pemilu

✅ Aktualisiert

BMKG

/DataMKG/MEWS/Warning/cuacasignifikan.json

/DataMKG/TEWS/gempadirasakan.json

✅ Aktualisiert

LHKPN

/portal/user/check_search_announ

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 fetch

API-Schlüssel

Modul

Schlüssel erforderlich

Env-Variable

Registrierung

BPS

Ja

BPS_API_KEY

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

check_bpom, search_bpom, get_bpom_status

3

bpjph

check_halal_cert, lookup_halal_by_product, get_halal_status, cross_reference_halal_bpom

4

ahu

lookup_company_ahu, get_company_directors, verify_company_status, search_companies_ahu

4

ojk

check_ojk_license, search_ojk_institutions, get_ojk_status, check_ojk_waspada

4

oss_nib

lookup_nib, verify_nib, search_oss_businesses

3

lpse

lookup_vendor_lpse, search_lpse_vendors, search_lpse_tenders, get_lpse_portals

4

kpu

get_candidate, search_kpu_candidates, get_election_results_kpu, get_campaign_finance_kpu

4

lhkpn

get_lhkpn, search_lhkpn, compare_lhkpn, get_lhkpn_pdf

4

bps

search_bps_datasets, get_bps_indicator, list_bps_regions

3

bmkg

get_bmkg_alerts, get_weather_forecast, get_earthquake_history, get_latest_earthquake

4

simbg

lookup_building_permit, search_permits_by_area, list_simbg_portals

3


KI-Agenten-Integration

Dieses Repository ist für KI-Agenten als erstklassige Nutzer konzipiert.

Für KI-Coding-Agenten

Datei

Zweck

Agent

AGENTS.md

Architektur, Muster, kritische Regeln, Stolperfallen

Alle Coding-Agenten

CLAUDE.md

Befehle, Do's/Don'ts-Regeln, Styleguide

Claude Code

.cursorrules

Projektregeln für Cursor

Cursor

.github/copilot-instructions.md

Anweisungen für Copilot

GitHub Copilot

CONTRIBUTING.md

Modulvertrag + PR-Checkliste

Alle

SKILL.md

Skill-Erkennung (AgentSkills-Format)

Skill-bewusste Agenten

PROMPTS.md

Beispiel-Prompts + interaktive Artefakt-Rezepte

Alle KI-Agenten

MCP-Tools verbinden (eine Option wählen)

Option A – Selbst gehosteter Remote-Server (eigene Bereitstellung):

Deploy on Railway

# 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-mcp

Option 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 immediately

Alle 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=paracetamol

Beispiel-Prompts

Sobald die MCP-Tools verbunden sind, probiere diese mit deinem KI-Agenten aus:

Lebensmittelsicherheit „Prüfe, ob die BPOM-Registrierungsnummer MD 123456789 noch 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

  1. Einheitliches Antwort-Envelope – jedes Tool gibt CivicStackResponse mit denselben Feldern zurück. Agenten benötigen keine modulspezifische Parsing-Logik.

  2. Fehler-Envelopes statt Ausnahmen – Agenten erhalten strukturierte Fehlerinformationen, mit denen sie arbeiten können, keine Stacktraces.

  3. Selbstdokumentierende Tools – MCP-Toolbeschreibungen enthalten Parametertypen, erwartete Werte und Antwortformat.

  4. Deterministische Benennungcheck_<module>, search_<module>, get_<module>_status-Muster über alle Module.


Sicherheit

Funktion

Konfiguration

Standard

API-Schlüssel-Authentifizierung

CIVIC_API_KEY Env-Variable

Deaktiviert (offen)

Ratenbegrenzung

CIVIC_RATE_LIMIT Env-Variable

60 Anfragen/min pro IP

Proxy-Allowlist

CIVIC_ALLOWED_PROXIES Env-Variable

Jede nicht-private IP

SSRF-Schutz

Integriert

Blockiert RFC 1918 + localhost

Container-Benutzer

Dockerfile

Nicht-Root (civicapp, uid 1000)

# 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 8000

Docker

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-bpom

Entwicklung

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 check

Tests

pytest -v                       # 89 tests, VCR replay (no live calls)
pytest tests/bpom/ -v           # Single module
pytest --tb=short -q            # Quick summary
pie 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" : 6

Mitwirken

Siehe CONTRIBUTING.md. Jeder Modul-PR muss Folgendes enthalten:

  • fetch() und search(), die CivicStackResponse zurückgeben

  • FastAPI-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

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:app

Verwandt

  • 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

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
16dResponse time
3dRelease cycle
5Releases (12mo)
Commit activity
Issues opened vs closed

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

  • A
    license
    A
    quality
    D
    maintenance
    Provides 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.
    4
    14
    10
    ISC
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides 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.
    19
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Citation-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.
    10
    MIT

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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