Skip to main content
Glama
suryast

indonesia-civic-stack

by suryast

🇮🇩 indonesia-civic-stack

PyPI MCP Registry CI Python License

인도네시아 정부 데이터 소스를 위한 프로덕션 준비 완료 스크래퍼, 정규화기, API 래퍼.

halalkah.id, legalkah.id의 기반이 되는 인프라 레이어이자, 인도네시아 시빅 테크 및 개발자 커뮤니티를 위한 공공재입니다.


왜 필요한가

인도네시아 공공 데이터는 명목상 공개되어 있지만 실질적으로 접근하기 어렵습니다. 시빅 도구를 만드는 모든 개발자는 동일한 스크래핑 문제를 각자 다시 해결합니다: BPOM 제품 등록, BPJPH 할랄 인증서, AHU 회사 기록. 포털이 바뀌면 스크래퍼는 몇 달 안에 낡아버립니다. 공유되고 유지 관리되는 레이어가 없습니다.

이 저장소가 바로 그 레이어입니다. pip install 한 번으로 인도네시아 정부 포털을 조회하세요 — 더 이상 맞춤형 스크래퍼는 필요 없습니다.

AI 에이전트 우선

  • 🤖 46개의 MCP 도구 — Claude, GPT 또는 MCP 호환 에이전트에 연결

  • 📋 SKILL.md — AI 에이전트 스킬 탐색 (AgentSkills 형식)

  • 🧑💻 AGENTS.md — 코딩 에이전트용 아키텍처 가이드 (Claude Code, Codex, Cursor)

  • 📝 CLAUDE.md — Claude Code 전용 지침

  • 타입화된 응답CivicStackResponse 엔벨로프, 절대 raw dict가 아님

  • 🔁 일관된 패턴 — 모든 모듈이 동일한 계약을 따름


Related MCP server: openapi-mcp-sdk

아키텍처

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

요청 흐름

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

모듈 상태

모듈

소스

데이터

프록시

상태

bpom

cekbpom.pom.go.id

식품, 의약품, 화장품 등록

🌐

✅ 활성

bpjph

cmsbl.halal.go.id

할랄 인증서 (1.98M+ 건)

🌐

✅ 활성 — REST API로 마이그레이션됨 (v1.0.0)

ahu

ahu.go.id

회사 등록부 — PT, CV, Yayasan, Koperasi

🇮🇩

⚠️ 페이지 개편됨 — 검색 입력 변경 (2026년 4월)

ojk

www.ojk.go.id/waspada-investasi

허가된 금융 기관 + Waspada 목록

🇮🇩

⚠️ 포털이 SharePoint로 마이그레이션됨 (2026년 4월) — 스크래퍼 재작성 필요

oss_nib

oss.go.id

사업자 식별 정보 (NIB)

🇮🇩

⚠️ 페이지 개편됨 — Playwright가 입력 요소를 찾지 못함 (2026년 4월)

lpse

spse.inaproc.id

정부 조달

🇮🇩

✅ 활성 — 사용 중단 해제 (v1.0.0)

kpu

infopemilu.kpu.go.id

선거 데이터 — 후보자, 결과, 자금

🌐

✅ 활성

bps

webapi.bps.go.id

통계 데이터셋 (1,000개 이상)

🌐

✅ 활성 (BPS_API_KEY 필요)

bmkg

data.bmkg.go.id

날씨, 지진, 재해 데이터

🌐

✅ 활성

simbg

simbg.pu.go.id

건축 허가 (PBG) — 다중 포털

🌐

✅ 활성

jdih

peraturan.go.id

국가 법률 데이터베이스 — UU, PP, Perpres, Permen

🇮🇩

신규 — Playwright 스크래핑

ksei

web.ksei.co.id

증권 통계 (월간 PDF 62개) + 등록 증권

🌐

신규 — HTML 스크래핑 (프록시 불필요)

djpb

data-apbn.kemenkeu.go.id

APBN 예산 테마 — 목표/실적/달성

🇮🇩

신규 — 깔끔한 REST JSON API

lhkpn

elhkpn.kpk.go.id

재산 신고 (공무원)

✅ 활성 — reCAPTCHA v3를 Playwright로 해결

🌐 = 전 세계에서 작동   🇮🇩 = 인도네시아 프록시 필요 (PROXY_URL 설정)

모든 모듈은 동일한 CivicStackResponse 엔벨로프를 반환합니다 — 애플리케이션 로직을 건드리지 않고 데이터 소스를 교체할 수 있습니다.

모듈 성숙도

모듈

스크래퍼

정규화기

MCP

테스트

포털 상태

bpom

bpjph

✅ REST API

ahu

⚠️ 페이지 개편됨

ojk

⚠️ SharePoint 마이그레이션

oss_nib

⚠️ 페이지 개편됨

lpse

🇮🇩 지역 차단

kpu

bps

bmkg

simbg

jdih

🇮🇩 Playwright

ksei

✅ (프록시 불필요)

djpb

✅ REST JSON API

lhkpn

✅ 활성 (Playwright)


빠른 시작

설치

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 서버 (AI 에이전트용)

14개 모듈 모두 Claude, GPT 또는 MCP 호환 에이전트에서 사용할 수 있는 46개의 MCP 도구를 제공합니다.

# 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 서버 클래스는 두 가지 초기화 방식을 지원합니다:

# 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

응답 엔벨로프

모든 모듈은 CivicStackResponse를 반환합니다:

{
  "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"
}

상태 값: ACTIVE, EXPIRED, SUSPENDED, REVOKED, NOT_FOUND, ERROR.

모듈이 포털에 연결할 수 없거나 구성이 누락된 경우(예: BPS_API_KEY), 크래시 대신 오류 엔벨로프를 반환합니다:

{
  "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"
}

모듈 내부

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

shared/ 레이어는 다음을 제공합니다:

  • schema.pyCivicStackResponse Pydantic 모델, 상태 열거형, 헬퍼 생성자

  • http.py — 자동 프록시, 속도 제한기, 지수 백오프 재시도, CF Worker 프록시용 URL 재작성을 지원하는 civic_client() 팩토리

  • mcp.py — MCP 서버용 CivicStackMCPBase 추상 기본 클래스


배포 참고 사항

지역 차단 및 프록시 요구 사항

대부분의 인도네시아 정부 포털(*.go.id)은 인도네시아 IP 주소의 접근을 제한합니다. 인도네시아 외부에 배포하는 경우 요청을 인도네시아 엔드포인트를 통해 라우팅하도록 PROXY_URL반드시 설정해야 합니다.

# 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

프록시가 없으면: 대부분의 모듈에서 DNS 해석 실패, 연결 시간 초과, HTTP 403/404 응답이 발생할 수 있습니다.

SDK는 환경에서 PROXY_URL을 자동으로 읽습니다 — 스크래퍼나 MCP 서버에서 코드 변경이 필요 없습니다.

프록시 모드

모드

PROXY_URL 예시

작동 방식

connect

socks5://id-proxy:1080

httpx 전송을 통한 표준 HTTP/SOCKS CONNECT 프록시

rewrite

https://x.workers.dev

URL을 ?url=<target>으로 재작성 (*.workers.dev에 대해 자동 감지)

none

(설정 안 됨)

직접 연결

자동 감지를 재정의하려면 PROXY_MODE=connect|rewrite를 사용하세요.

CF Worker 프록시

배포 준비가 된 CF Worker 프록시가 proxy/에 포함되어 있습니다. 배포 방법:

cd proxy && npx wrangler deploy

⚠️ CF Worker 제한 사항: 많은 .go.id 포털 자체가 Cloudflare 뒤에 있습니다. CF Worker가 다른 CF 보호 오리진에 fetch() 호출을 하면 403/522 오류를 받습니다. 이는 알려진 Cloudflare 제한 사항입니다.

CF Worker 프록시를 통해 검증됨:

포털

상태

비고

data.bmkg.go.id

✅ 작동

JSON API, CF 뒤에 있지 않음

cekbpom.pom.go.id

❌ 403/522

포털이 CF로 보호됨

api.ojk.go.id

❌ DNS 죽음

2026년 3월부터 NXDOMAIN

infopemilu.kpu.go.id

❌ 403

CF로 보호됨

lpse.*.go.id

❌ 403

CF로 보호됨

elhkpn.kpk.go.id

✅ 200

reCAPTCHA v3를 Playwright 헤드리스 브라우저로 해결

CF로 보호되는 포털을 프로덕션에서 사용하려면 SOCKS5/HTTP 프록시가 있는 인도네시아 VPS를 사용하고 PROXY_MODE=connect로 설정하세요.

지역 차단 테스트 결과 (2026년 3월)

어떤 포털이 지역 차단을 적용하고 어떤 포털이 WAF를 적용하는지 파악하기 위해 세 곳에서 테스트했습니다:

포털

시드니(AU)

싱가포르

자카르타(ID)

평가

ahu.go.id

지리적 차단(SEA+ OK)

elhkpn.kpk.go.id

지리적 차단(SEA+ OK)

ojk.go.id

❌ 403

❌ 403

ID 전용

jaga.id (KPK)

제한 없음

data.bmkg.go.id

제한 없음

cekbpom.pom.go.id

⚠️

⚠️

⚠️

CF 보호(모든 위치)

webapi.bps.go.id

❌ 403

❌ 403

❌ 403

WAF, 지리적 차단 아님(API 키 필요)

lpse.lkpp.go.id

불안정(모든 위치)

coretaxdjp.pajak.go.id

불안정(모든 위치)

결론: 인도네시아 프록시(예: CloudKilat Jakarta)를 사용하면 가장 중요한 지리적 차단 포털인 OJK에 접근할 수 있습니다. 싱가포르는 AHU + LHKPN을 잠금 해제합니다. BPS와 LPSE의 실패는 지리적 문제가 아닙니다.

VPS 강화 교훈

⚠️ 새 VPS에서 비밀번호 인증을 비활성화하고 sshd를 재시작하는 것을 하나의 자동화 스크립트로 절대 수행하지 마세요. SSH 키가 올바르게 복사되지 않았다면 웹 콘솔 외에는 복구 경로가 없어 잠겨버립니다. 항상: (1) 키 복사, (2) 별도 세션에서 키 로그인 확인, (3) 그 다음에 비밀번호 인증 비활성화.

포털 URL 안정성

인도네시아 정부 포털은 사전 공지 없이 URL 구조를 자주 변경합니다. 2026년 3월 기준으로 알려진 변경 사항:

모듈

이전 URL

새 URL

상태

BPOM

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

/all-produk?q={keyword}

✅ 업데이트됨

KPU

/Pemilu/caleg/list

/Pemilu/Peserta_pemilu

✅ 업데이트됨

BMKG

/DataMKG/MEWS/Warning/cuacasignifikan.json

/DataMKG/TEWS/gempadirasakan.json

✅ 업데이트됨

LHKPN

/portal/user/check_search_announ

reCAPTCHA v3 (Playwright)

🟢 활성

60일 동안 실패하는 모듈은 DEGRADED로 표시되고 보관될 수 있습니다.

브라우저 기반 모듈

일부 포털은 실제 브라우저(JavaScript 렌더링, 안티봇 보호)가 필요합니다:

모듈

브라우저

안티봇

bpjph

Playwright (Chromium)

표준

ahu

Playwright + Camoufox

봇 관리(데이터센터 IP 차단)

oss_nib

Playwright (Chromium)

표준

브라우저 종속성 설치:

pip install ".[playwright]"
playwright install chromium

# For AHU (optional, improves success rate):
pip install camoufox && python -m camoufox fetch

API 키

모듈

키 필요

환경 변수

등록

BPS

BPS_API_KEY

webapi.bps.go.id/developer/register (무료)

기타 모든 모듈

아니요

BPS_API_KEY가 없으면 BPS 모듈은 오류 봉투(충돌이 아님)를 반환합니다:

{"status": "ERROR", "detail": "BPS_API_KEY not set. Register at ..."}

MCP 도구 목록

11개 모듈 모두 40개의 MCP 도구를 노출합니다:

모듈

도구

개수

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


AI 에이전트 통합

이 저장소는 AI 에이전트를 일급 소비자로 하여 구축되었습니다.

AI 코딩 에이전트용

파일

목적

에이전트

AGENTS.md

아키텍처, 패턴, 핵심 규칙, 함정

모든 코딩 에이전트

CLAUDE.md

명령, 지침/금지 규칙, 스타일 가이드

Claude Code

.cursorrules

Cursor용 프로젝트 규칙

Cursor

.github/copilot-instructions.md

Copilot용 지침

GitHub Copilot

CONTRIBUTING.md

모듈 계약 + PR 체크리스트

모든 에이전트

SKILL.md

스킬 검색(AgentSkills 형식)

스킬 인식 에이전트

PROMPTS.md

예제 프롬프트 + 대화형 아티팩트 레시피

모든 AI 에이전트

MCP 도구 연결(하나 선택)

옵션 A — 자체 호스팅 원격 서버(직접 배포):

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"
    }
  }
}

참고: 공유 호스팅 서버는 없습니다. 각 사용자는 프록시 설정, 속도 제한, API 키를 제어하기 위해 자체 인스턴스를 배포합니다.

옵션 B — pip를 통한 로컬 설치:

pip install "indonesia-civic-stack[mcp]"
claude mcp add civic-stack -- civic-stack-mcp

옵션 C — 저장소 복제(자동 검색):

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

세 가지 옵션 모두 동일한 40개의 도구를 제공합니다. 그런 다음 다음과 같이 질문하세요:

"BPOM 등록 번호 MD 123456789가 여전히 활성 상태인지 확인해줘" "AHU 등록부에서 'Maju Bersama'라는 회사를 검색해줘" "인도네시아에서 가장 최근 지진은 무엇이었나?"

더 많은 예제 프롬프트와 대화형 아티팩트 레시피는 PROMPTS.md를 참조하세요.

REST API

pip install "indonesia-civic-stack[api]"
civic-stack api --port 8000
# GET http://localhost:8000/bpom/search?q=paracetamol

예제 프롬프트

MCP 도구가 연결되면 AI 에이전트와 함께 다음을 시도해 보세요:

식품 안전 "BPOM 등록 번호 MD 123456789가 여전히 활성 상태인지 확인해줘" "BPOM에 등록된 모든 파라세타몰 제품을 검색해줘"

할랄 인증 "제품 XYZ가 할랄 인증을 받았나? BPOM 등록과 교차 확인해줘" "PT Indofood에 발급된 모든 할랄 인증서를 찾아줘"

기업 실사 "AHU 기업 등록부에서 PT Maju Bersama를 조회하고 대표이사가 누구인지 확인해줘" "이 회사가 OJK 라이선스를 보유하고 있나? 라이선스 등록부와 waspada(경고) 목록을 모두 확인해줘"

공공 재정 "자카르타 공무원의 LHKPN 재산 신고를 검색해줘" "LPSE에서 도로 건설에 대한 정부 조달 입찰을 찾아줘"

재난 및 날씨 "인도네시아에서 가장 최근 지진은 무엇이었나?" "BMKG에서 DKI 자카르타의 날씨 예보를 가져와줘"

통계 "지방별 빈곤율에 대한 BPS 데이터셋을 찾아줘" "지난 5년간 인플레이션 지표를 가져와줘"

다중 소스 쿼리 "식품 회사를 검증하고 싶어: AHU에서 등록, OJK에서 금융 라이선스, BPOM에서 제품 등록, BPJPH에서 할랄 인증서를 확인해줘" "지난 3개 보고 기간 동안 이 두 공무원의 LHKPN 재산 신고를 비교해줘"

AI 에이전트를 위한 설계 결정

  1. 통일된 응답 봉투 — 모든 도구는 동일한 필드를 가진 CivicStackResponse를 반환합니다. 에이전트는 모듈별 파싱 로직이 필요 없습니다.

  2. 예외가 아닌 오류 봉투 — 에이전트는 스택 트레이스가 아닌, 추론할 수 있는 구조화된 오류 정보를 받습니다.

  3. 자체 문서화 도구 — MCP 도구 설명에는 매개변수 유형, 예상 값, 응답 형식이 포함됩니다.

  4. 결정적 명명 규칙 — 모든 모듈에서 check_<module>, search_<module>, get_<module>_status 패턴을 사용합니다.


보안

기능

구성

기본값

API 키 인증

CIVIC_API_KEY 환경 변수

비활성화(공개)

속도 제한

CIVIC_RATE_LIMIT 환경 변수

IP당 분당 60회 요청

프록시 허용 목록

CIVIC_ALLOWED_PROXIES 환경 변수

비사설 IP

SSRF 방지

내장

RFC 1918 + localhost 차단

컨테이너 사용자

Dockerfile

비루트(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

개발

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

테스트

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

기여

CONTRIBUTING.md를 참조하세요. 모든 모듈 PR에는 다음이 포함되어야 합니다:

  • CivicStackResponse를 반환하는 fetch()search()

  • FastAPI 라우터 + FastMCP 서버

  • 3개 이상의 VCR 테스트 픽스처

  • 모듈 README

60일 동안 중단된 모듈은 DEGRADED로 표시되고 보관됩니다.


사용처

샘플 아키텍처

단순: 할랄 제품 검사기

제품이 할랄 인증을 받았는지 확인하는 단일 페이지 앱입니다. 인도네시아 사용자에게는 프록시가 필요 없는 단일 모듈입니다.

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}

중간: 다중 소스 실사 API

여러 정부 데이터베이스에서 회사를 교차 확인하는 규정 준수 도구입니다. 해외 배포를 위해 프록시 뒤에서 실행됩니다.

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),
    }

고급: MCP 도구를 갖춘 AI 에이전트

MCP 도구를 사용하여 인도네시아 시민 데이터에 대한 자연어 질문에 답하는 AI 어시스턴트입니다. 에이전트는 어떤 포털을 쿼리할지 추론합니다.

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

관련

  • indonesia-civic-signal-monitor — 이 SDK 기반 이상 감지 엔진, 뉴스 가치가 있는 변경 사항을 위해 11개 정부 데이터 소스 모니터링

  • indonesia-gov-apis — 50개 이상의 인도네시아 정부 API 참조 문서

  • datarakyat.id — 전체 모듈 문서가 있는 프로젝트 홈페이지

라이선스

MIT — 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