关于 indonesia-civic-stack
indonesia-civic-stack 是面向印度尼西亚公共数据门户的 Python SDK、统一 MCP 服务和 REST 封装,为 civic-tech 开发者提供跨门户的客户端与统一响应格式,并说明各模块的范围及实时可用性限制。
主要功能
- 01访问 14 个政府门户数据
- 02提供 45 个统一 MCP 工具
- 03提供 Python SDK 和 11 个 REST 路由
- 04统一响应封装并附来源信息
- 05包含浏览器和 HTTP 抓取模块
适用场景
- 01核查产品及清真认证
- 02搜索公司、招标和选举数据
- 03获取天气、地震和统计数据
- 04将印度尼西亚公共记录接入 civic-tech 应用
MCP 相关
统一 MCP 服务向 MCP 客户端提供 14 个门户模块中的 45 个已注册工具。工具已注册并不代表门户当前可用或搜索结果完整。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx indonesia-civic-stackPROXY_URLProxy URL for accessing Indonesian government portals from outside Indonesia (e.g. Cloudflare Worker URL)BPS_API_KEY密钥BPS Statistics API key (free registration at webapi.bps.go.id)本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
🇮🇩 indonesia-civic-stack
面向印度尼西亚公共部门数据的 Python SDK、MCP 工具和 REST 封装。 1.2.1 版包含 14 个爬取模块、45 个统一的 MCP 工具,以及 11 个 REST 模块路由器。这些数量描述的是代码,不代表实时可用性。
印度尼西亚公共数据门户提供的 API、HTML 结构、浏览器要求和访问限制各不相同。 本项目提供统一的响应架构和可复用客户端,开发者无需为每个公民科技应用单独构建集成。 门户变更仍可能导致个别操作失效;在得出结论前,请核实响应内容及其来源。
模块清单与成熟度
每一行都包含一个抓取器、规范化器和模块测试文件。“有测试”表示存在模拟或回放测试,并不意味着这些测试证明了门户当前可用。
MCP 列统计 统一版 civic_stack/server.py 中的装饰器。
| 模块 | 代码中配置的数据源 | 数据 / 方法 | MCP 工具 | REST | 有测试 |
|---|---|---|---|---|---|
| bpom | cekbpom.pom.go.id | 产品注册;HTTP HTML | 3 | 是 | 是 |
| bpjph | cmsbl.halal.go.id | 清真证书;HTTP REST | 4 | 是 | 是 |
| ahu | ahu.go.id | 公司注册信息;浏览器辅助工具 | 4 | 是 | 是 |
| ojk | www.ojk.go.id / sikapiuangmu.ojk.go.id | 机构和预警;HTTP + 可选浏览器列表 | 4 | 是 | 是 |
| oss_nib | oss.go.id | NIB 身份信息;Playwright | 3 | 是 | 是 |
| lpse | spse.inaproc.id 和已配置门户 | 供应商 / 招标;多门户 HTTP | 4 | 是 | 是 |
| kpu | infopemilu.kpu.go.id / sirekap-obj-data.kpu.go.id | 候选人和 2024 年选举;HTTP JSON | 4 | 是 | 是 |
| lhkpn | elhkpn.kpk.go.id | 财产申报;Playwright 搜索,HTTP PDF | 3 | 是 | 是 |
| bps | webapi.bps.go.id | 统计数据;HTTP API,需要 BPS_API_KEY | 3 | 是 | 是 |
| bmkg | data.bmkg.go.id | 地震 / 天气;HTTP JSON/XML | 4 | 是 | 是 |
| simbg | simbg.pu.go.id 和试点门户 | 许可证;多门户 HTTP | 3 | 是 | 是 |
| jdih | peraturan.go.id | 法规;Playwright 最近列表筛选 | 2 | 否 | 是 |
| ksei | web.ksei.co.id | 证券和统计链接;HTTP HTML | 2 | 否 | 是 |
| djpb | data-apbn.kemenkeu.go.id | 预算主题;HTTP JSON | 2 | 否 | 是 |
JDIH、KSEI 和 DJPB 可通过 SDK 和统一 MCP 服务使用,但没有独立的 MCP 服务或 REST 路由器。JDIH 搜索最多检查最近列表中的 50 个链接;KSEI 证券信息获取 / 搜索只检查第 1 页。二者都不能完整搜索注册信息。LHKPN 的浏览器搜索实现并不能证明 reCAPTCHA 或上游门户在你的部署环境中可用。
此处未验证门户当前是否可用。 端点状态和地理限制中的 2026 年 3 月 / 4 月历史观察仅供排障参考,不能证明当前运行状况。HTTP 200 首页响应、本地 /health 或通过的模拟 / VCR 测试,都不等于成功查询了在线注册信息。
安装
pip install indonesia-civic-stack # Core HTTP SDK
pip install "indonesia-civic-stack[mcp]" # + unified MCP server
pip install "indonesia-civic-stack[api]" # + FastAPI and uvicorn
pip install "indonesia-civic-stack[browser]" # + Playwright and Camoufox
pip install "indonesia-civic-stack[all]" # mcp + api + browser
依赖浏览器的操作还需要二进制文件:
playwright install chromium
python -m camoufox fetch # AHU Camoufox path
AHU、OSS NIB、JDIH、LHKPN 搜索以及 OJK 的完整列表辅助工具会使用浏览器路径。BPJPH 当前的抓取器使用 HTTP REST。all 不会下载浏览器二进制文件,也不包含 LHKPN 的可选 PDF 软件包。要提取 PDF 文本,请直接安装 pdfplumber;可选的扫描文档回退方案需要 anthropic 和 ANTHROPIC_API_KEY,会将文档发送到外部 API,并可能产生费用。没有 pdf 或 playwright extras。SOCKS HTTP 传输还需要 pip install "httpx[socks]"。
Python SDK
import asyncio
from civic_stack.bpom.scraper import search
async def main():
try:
async with asyncio.timeout(120):
records = await search("paracetamol")
except Exception as exc:
print("Could not verify:", type(exc).__name__)
return
if not records:
print("No records returned; acquisition may be unverified")
for record in records:
print(record.status, record.found, record.source_url, record.fetched_at)
if record.status == "ERROR":
print("Could not verify:", record.result)
elif record.found:
print(record.result) # Check identity, period, and domain-specific status
else:
print("No match reported within the query scope; not proof of absence")
asyncio.run(main())
每个抓取器都有 fetch() 和 search(),具体签名因模块而异。专用辅助工具包括 BMKG 的 get_latest_earthquake、KPU 的 get_election_results、OJK 的 check_waspada、KSEI 的 get_statistics_links 和 DJPB 的 get_budget_summary。有关实际返回值结构、范围限制和统一工具包装器的注意事项,请参阅用法与限制。
响应解读
核心查询会返回 CivicStackResponse 或信封列表:
{
"result": {"product_name": "Example", "registration_status": "ACTIVE"},
"found": true,
"status": "ACTIVE",
"confidence": 1.0,
"source_url": "https://cekbpom.pom.go.id/example",
"fetched_at": "2026-03-14T06:30:00Z",
"last_updated": null,
"module": "bpom",
"raw": null
}
这只是示例,并非实时响应。状态值包括 ACTIVE、EXPIRED、
SUSPENDED、REVOKED、NOT_FOUND 和 ERROR。错误详情位于
result.detail,而不是顶层的 detail。部分辅助函数会返回原始列表/字典、
PDF 提取数据或 URL,而不是信封;状态快捷 MCP 工具会省略来源和时间戳。
不要假设每个工具都具有完整的架构。
读取 result 之前,请检查 status、found、source_url 和 fetched_at。
获取时间不等于发布时间;请核实来源所报告的时间段。
ERROR 不等于 NOT_FOUND。 多个模块当前的处理路径也会将
网络/浏览器故障合并为 NOT_FOUND 或 []。因此,仅凭空结果或未找到结果,
无法证明数据获取成功,也无法证明记录不存在。BPS fetch() 在缺少键时可能
引发异常;其他调用方也可能遇到意外异常。请在调用方边界捕获异常。
找到注册记录并不构成一般性的安全/法律保证。匹配警示名单是一项警告, 并非认可。不得将不完整的多门户结果和抓取器置信度值描述为全面或权威的核查结果。
统一 MCP 服务
civic-stack-mcp # stdio, 45 tools
python -m civic_stack.server # packaged equivalent
civic-stack mcp # CLI stdio entry point
python -m civic_stack.server --transport http --host 127.0.0.1 --port 8000
# Individual module server (where present):
python -m civic_stack.bpom.server
对于本地客户端,请将 civic-stack-mcp 配置为命令。仓库中的
.mcp.json 使用 .venv/bin/python -m civic_stack.server;在发现工具前,
请创建该虚拟环境并安装 [mcp]。发现工具不会安装依赖项,也无法确保门户有响应。
这里没有共用的托管服务。
统一 MCP 工具列表
| 模块 | 已注册的工具名称 |
|---|---|
| bpom | check_bpom、search_bpom、get_bpom_status |
| bpjph | check_halal_cert、lookup_halal_by_product、get_halal_status、cross_reference_halal_bpom |
| ahu | lookup_company_ahu、get_company_directors、verify_company_status、search_companies_ahu |
| ojk | check_ojk_license、search_ojk_institutions、get_ojk_status、check_ojk_waspada |
| oss_nib | lookup_nib、verify_nib、search_oss_businesses |
| lpse | lookup_vendor_lpse、search_lpse_vendors、search_lpse_tenders、get_lpse_portals |
| kpu | get_candidate、search_kpu_candidates、get_election_results_kpu、get_campaign_finance_kpu |
| lhkpn | get_lhkpn、search_lhkpn、get_lhkpn_pdf |
| bps | search_bps_datasets、get_bps_indicator、list_bps_regions |
| bmkg | get_bmkg_alerts、get_weather_forecast、get_earthquake_history、get_latest_earthquake |
| simbg | lookup_building_permit、search_permits_by_area、list_simbg_portals |
| jdih | search_jdih、get_jdih |
| ksei | search_ksei、get_ksei |
| djpb | search_djpb、get_djpb |
这些是 45 个已注册名称,并非 45 项经过独立验证的操作。部分封装器调用的是通用抓取函数, 而非工具名称所暗示的专用辅助函数;使用选举结果、竞选财务、招标、警示名单或门户列表工具前, 请先阅读封装器注意事项。
无需调用工具,即可离线验证注册情况:
python -c 'import asyncio; from civic_stack.server import mcp; print(len(asyncio.run(mcp.list_tools())))'
REST API
civic-stack api --host 127.0.0.1 --port 8000
uvicorn civic_stack.app:app --host 127.0.0.1 --port 8000
uvicorn civic_stack.bpom.app:app --host 127.0.0.1 --port 8001
统一应用挂载了 11 个路由器。JDIH、KSEI 和 DJPB 没有 REST 路由。
请打开 /docs 或 /openapi.json 查看实际路由签名。示例:
GET /bpom/search?q=paracetamol
GET /bpjph/search?q=kopi
GET /ahu/search?q=Contoh
GET /ojk/check/Bank%20BCA
GET /kpu/search?q=Contoh
GET /lhkpn/search?q=Contoh
GET /bps/search?q=inflasi
GET /bmkg/forecast/Jakarta
GET /bmkg/earthquake/latest
GET /simbg/search?q=Jakarta
/health 仅描述本地应用;它不会探测上游门户。
部署与安全
civic_client() 会读取 PROXY_URL,并根据环境变量选择 PROXY_MODE=connect
或 rewrite。*.workers.dev URL 会自动选择重写模式。浏览器代理处理方式不同:Worker 重写 URL 不是标准的 Chromium 代理;AHU 和 OSS-NIB 仅在 CONNECT 模式下回退使用 PROXY_URL;JDIH 使用其显式代理参数;LHKPN 搜索不会将其 proxy_url
参数传递给浏览器。不要以为设置环境变量就能代理所有操作。请参阅使用说明。
运行代理的人可以控制服务收到的门户响应。因此,REST 路由器以及独立的 AHU/OSS-NIB MCP 服务仅在调用方提供的 proxy_url 与 PROXY_URL 或 CIVIC_ALLOWED_PROXIES 中的某个条目完全匹配时才接受该参数(该变量以逗号分隔,包含完整代理 URL);否则将拒绝请求(返回 HTTP 400 或 ERROR 信封)。请在服务端配置代理。
访问权限可能因部署、端点和时间而异。历史区域测试不能证明当前存在地理封锁或 WAF 拦截原因。达到有限的尝试次数后应停止;不要绕过经过身份验证的访问层,也不要反复重试访问控制。
**当前统一的 REST 应用未实现 API 密钥身份验证或按客户端限流中间件。**仅设置 CIVIC_API_KEY 或 CIVIC_RATE_LIMIT 不会启用其中任何一项。CIVIC_ALLOWED_PROXIES 只用于限制调用方提供的代理;它不是 SDK 调用的 SSRF 允许列表。请在自己的身份验证、配额和网络控制后面部署。供本地使用时,请绑定到 loopback。模块获取限流器并非用于防范公共 API 滥用。
安装 Agent Skills
SKILL.md 是可移植的技能入口文件。其元数据版本为
"1.2.1";它使用 description 中的触发短语,而不使用不受支持的 frontmatter
键。安装时必须保留完整仓库,尤其是 references/usage.md 和其他捆绑的参考资料、软件包代码、清单
及许可证。安装目录必须命名为 indonesia-civic-stack。
对于支持用户选择技能目录的宿主:
# Set this to your host's configured directory; destination must not already exist.
git clone https://github.com/suryast/indonesia-civic-stack.git "$SKILLS_DIR/indonesia-civic-stack"
cd "$SKILLS_DIR/indonesia-civic-stack"
pip install -e ".[mcp]" # if running the bundled MCP code
不要只安装 SKILL.md,也不要将软件包重命名为发布工作树的后缀。宿主发现和 Python 安装是两个独立步骤。对于固定版本的安装,请明确选择经过审核的发布修订;克隆默认分支并不能固定版本。
开发与离线验证
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]"
pytest --collect-only -q # derive current collected tests; no fixed advertised total
pytest -v # mocked/VCR replay; no live portal calls intended
pytest tests/jdih/ tests/ksei/ tests/djpb/ -v
ruff check civic_stack/ tests/ scripts/ examples/ app.py server.py
ruff format --check civic_stack/ tests/ scripts/ examples/ app.py server.py
mypy civic_stack/
全部 14 个模块都有测试文件,包括 JDIH、KSEI 和 DJPB。离线测试套件通过,只能验证 fixtures/mocks,不能证明上游服务正常运行。不要在 CI 中录制实时 cassette;应先检查实际的测试隔离和录制设置。
开发前请阅读 AGENTS.md、CLAUDE.md 和 CONTRIBUTING.md。贡献指南说明了所需的完整模块契约;相比其他文档中较早的笼统清单描述,上文列出的已实现功能优先适用。
参考资料与相关项目
许可证
根目录技能/文档采用 MIT 许可证;请参阅 LICENSE。
模块许可证有所不同;请保留模块许可证文件,并查阅
LICENSES.md(其中较早的 modules/ 标签指的是当前的
civic_stack/ 软件包目录)。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。