indonesia-civic-stack
🇮🇩 indonesia-civic-stack
인도네시아 정부 데이터 소스를 위한 프로덕션 준비 완료 스크래퍼, 정규화기, 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모듈 상태
모듈 | 소스 | 데이터 | 프록시 | 상태 |
cekbpom.pom.go.id | 식품, 의약품, 화장품 등록 | 🌐 | ✅ 활성 | |
cmsbl.halal.go.id | 할랄 인증서 (1.98M+ 건) | 🌐 | ✅ 활성 — REST API로 마이그레이션됨 (v1.0.0) | |
ahu.go.id | 회사 등록부 — PT, CV, Yayasan, Koperasi | 🇮🇩 | ⚠️ 페이지 개편됨 — 검색 입력 변경 (2026년 4월) | |
허가된 금융 기관 + Waspada 목록 | 🇮🇩 | ⚠️ 포털이 SharePoint로 마이그레이션됨 (2026년 4월) — 스크래퍼 재작성 필요 | ||
oss.go.id | 사업자 식별 정보 (NIB) | 🇮🇩 | ⚠️ 페이지 개편됨 — Playwright가 입력 요소를 찾지 못함 (2026년 4월) | |
spse.inaproc.id | 정부 조달 | 🇮🇩 | ✅ 활성 — 사용 중단 해제 (v1.0.0) | |
infopemilu.kpu.go.id | 선거 데이터 — 후보자, 결과, 자금 | 🌐 | ✅ 활성 | |
webapi.bps.go.id | 통계 데이터셋 (1,000개 이상) | 🌐 | ✅ 활성 ( | |
data.bmkg.go.id | 날씨, 지진, 재해 데이터 | 🌐 | ✅ 활성 | |
simbg.pu.go.id | 건축 허가 (PBG) — 다중 포털 | 🌐 | ✅ 활성 | |
peraturan.go.id | 국가 법률 데이터베이스 — UU, PP, Perpres, Permen | 🇮🇩 | ✅ 신규 — Playwright 스크래핑 | |
web.ksei.co.id | 증권 통계 (월간 PDF 62개) + 등록 증권 | 🌐 | ✅ 신규 — HTML 스크래핑 (프록시 불필요) | |
data-apbn.kemenkeu.go.id | APBN 예산 테마 — 목표/실적/달성 | 🇮🇩 | ✅ 신규 — 깔끔한 REST JSON API | |
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]" # 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 서버 (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 belowMCP 서버 클래스는 두 가지 초기화 방식을 지원합니다:
# 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.mdshared/ 레이어는 다음을 제공합니다:
schema.py—CivicStackResponsePydantic 모델, 상태 열거형, 헬퍼 생성자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 서버에서 코드 변경이 필요 없습니다.
프록시 모드
모드 |
| 작동 방식 |
|
| httpx 전송을 통한 표준 HTTP/SOCKS CONNECT 프록시 |
|
| URL을 |
| (설정 안 됨) | 직접 연결 |
자동 감지를 재정의하려면 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 |
|
| ✅ 업데이트됨 |
KPU |
|
| ✅ 업데이트됨 |
BMKG |
|
| ✅ 업데이트됨 |
LHKPN |
| 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 fetchAPI 키
모듈 | 키 필요 | 환경 변수 | 등록 |
BPS | 예 |
| |
기타 모든 모듈 | 아니요 | — | — |
BPS_API_KEY가 없으면 BPS 모듈은 오류 봉투(충돌이 아님)를 반환합니다:
{"status": "ERROR", "detail": "BPS_API_KEY not set. Register at ..."}MCP 도구 목록
11개 모듈 모두 40개의 MCP 도구를 노출합니다:
모듈 | 도구 | 개수 |
bpom |
| 3 |
bpjph |
| 4 |
ahu |
| 4 |
ojk |
| 4 |
oss_nib |
| 3 |
lpse |
| 4 |
kpu |
| 4 |
lhkpn |
| 4 |
bps |
| 3 |
bmkg |
| 4 |
simbg |
| 3 |
AI 에이전트 통합
이 저장소는 AI 에이전트를 일급 소비자로 하여 구축되었습니다.
AI 코딩 에이전트용
파일 | 목적 | 에이전트 |
아키텍처, 패턴, 핵심 규칙, 함정 | 모든 코딩 에이전트 | |
명령, 지침/금지 규칙, 스타일 가이드 | Claude Code | |
Cursor용 프로젝트 규칙 | Cursor | |
Copilot용 지침 | GitHub Copilot | |
모듈 계약 + PR 체크리스트 | 모든 에이전트 | |
스킬 검색(AgentSkills 형식) | 스킬 인식 에이전트 | |
예제 프롬프트 + 대화형 아티팩트 레시피 | 모든 AI 에이전트 |
MCP 도구 연결(하나 선택)
옵션 A — 자체 호스팅 원격 서버(직접 배포):
# 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 에이전트를 위한 설계 결정
통일된 응답 봉투 — 모든 도구는 동일한 필드를 가진
CivicStackResponse를 반환합니다. 에이전트는 모듈별 파싱 로직이 필요 없습니다.예외가 아닌 오류 봉투 — 에이전트는 스택 트레이스가 아닌, 추론할 수 있는 구조화된 오류 정보를 받습니다.
자체 문서화 도구 — MCP 도구 설명에는 매개변수 유형, 예상 값, 응답 형식이 포함됩니다.
결정적 명명 규칙 — 모든 모듈에서
check_<module>,search_<module>,get_<module>_status패턴을 사용합니다.
보안
기능 | 구성 | 기본값 |
API 키 인증 |
| 비활성화(공개) |
속도 제한 |
| IP당 분당 60회 요청 |
프록시 허용 목록 |
| 비사설 IP |
SSRF 방지 | 내장 | RFC 1918 + localhost 차단 |
컨테이너 사용자 | Dockerfile | 비루트( |
# 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-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 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" : 6기여
CONTRIBUTING.md를 참조하세요. 모든 모듈 PR에는 다음이 포함되어야 합니다:
CivicStackResponse를 반환하는fetch()및search()FastAPI 라우터 + FastMCP 서버
3개 이상의 VCR 테스트 픽스처
모듈 README
60일 동안 중단된 모듈은 DEGRADED로 표시되고 보관됩니다.
사용처
halalkah.id — 할랄 제품 검증(957만 제품)
legalkah.id — 금융 기관 합법성 검사기
datarakyat.id — 랜딩 페이지 및 문서
샘플 아키텍처
단순: 할랄 제품 검사기
제품이 할랄 인증을 받았는지 확인하는 단일 페이지 앱입니다. 인도네시아 사용자에게는 프록시가 필요 없는 단일 모듈입니다.
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 참조
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