by ilhamfp
Pasal.id - The first open, AI-native Indonesian legal platform. MCP server + REST API + web app giving AI grounded access Indonesian laws.
# Add to your Claude Code skills
git clone https://github.com/ilhamfp/pasal280 million Indonesians have no practical way to read their own laws. The official legal database (peraturan.go.id) offers only PDF downloads: no search, no structure, no API. When you ask AI about Indonesian law, you get hallucinated articles and wrong citations because no grounded data source exists.
Connect Claude to real Indonesian legal data in one command:
claude mcp add --transport http pasal-id https://pasal-mcp-server-production.up.railway.app/mcp
Then ask:
"Apa saja hak pekerja kontrak menurut UU Ketenagakerjaan?" (What are contract worker rights under the Labor Law?) "Jelaskan pasal tentang perlindungan data pribadi" (Explain articles on personal data protection) "Apakah UU Perkawinan 1974 masih berlaku?" (Is the 1974 Marriage Law still in force?)
Claude searches 40,000+ regulations and 937,000+ structured articles, cites specific Pasal (articles), and gives grounded answers. No hallucination.
Or browse the web app at pasal.id.
| | Feature | Description | |---|---|---| | Search | Full-Text Legal Search | Indonesian stemmer + 3-tier fallback across 937,000+ articles | | Read | Structured Reader | Three-column law reader with TOC, amendment timeline, and verification badges | | AI | MCP Server | 4 grounded tools giving Claude access to actual legislation with exact citations | | API | REST API | Public JSON endpoints for search, browsing, and article retrieval | | Correct | Crowd-Sourced Corrections | Anyone can submit corrections; AI verifies before applying | | | AI Verification Agent | Opus 4.6 vision compares parsed text against original PDF images | | | Amendment Chains | Full relationship tracking: amendments, revocations, cross-references | | | Bilingual UI | Indonesian + English interface via next-intl (legal content stays Indonesian) |
No comments yet. Be the first to share your thoughts!
The entire codebase, from the Next.js frontend to the MCP server to the data pipeline, was built with Claude Opus 4.6 via Claude Code during the hackathon period. But Opus 4.6 isn't just the development tool. It's embedded in the product itself, running a self-improving correction flywheel that makes the platform more accurate over time:
┌───────────────────────────────┐
│ Users submit corrections │
│ via pasal.id web app │
└──────────────┬────────────────┘
▼
┌───────────────────────────────┐
│ Opus 4.6 Verification Agent │
│ Uses VISION to compare text │
│ against original PDF images │
│ → accept / reject / correct │
└──────┬───────────────┬────────┘
│ │
≥85% conf │ │ parser_feedback
auto-apply │ │ from each review
▼ ▼
┌──────────┐ ┌───────────────────────┐
│ Database │ │ Opus 4.6 reads the │
│ updated │ │ parser source code │
│ via safe │ │ + aggregated feedback │
│ revision │ │ → creates GitHub │
│ function │ │ issues with fixes │
└──────────┘ └───────────────────────┘
Claude gets 4 tools to search real legislation, retrieve specific articles, check amendment status, and browse regulations. All returning real data with exact citations, not generated text.
When users submit corrections, Opus 4.6 uses vision to compare the parsed text against the original PDF page image. It reads the actual PDF, character by character, and makes accept/reject/correct decisions with confidence scores. (scripts/agent/opus_verify.py)
Every verification produces parser_feedback: notes on why the parser got it wrong. Opus 4.6 aggregates this feedback, fetches the parser source code from GitHub, analyzes systematic bugs, and creates GitHub issues with specific code fixes. The AI improves the pipeline that feeds it. (scripts/agent/parser_improver.py)
High-confidence corrections (≥85%) are auto-applied through a transaction-safe revision function. Below that threshold, corrections are queued for admin review. Every mutation is logged in an append-only audit trail. Nothing is silently overwritten.
The entire platform was built with Claude Code guided by 489 lines of CLAUDE.md specifications across 4 directories (root, web app, MCP server, and data pipeline), encoding architecture decisions, coding conventions, database invariants, and domain knowledge.
┌──────────────────────────────────────┐
│ Supabase (PostgreSQL) │
│ 40,143 regulations · 937,155 Pasal │
│ 49 migrations · FTS · RLS │
└─────────┬──────────────┬─────────────┘
│ │
┌────────────────┘ └────────────────┐
▼ ▼
┌─────────────────────┐ ┌───────────────────────┐
│ MCP Server (Py) │ │ Next.js 16 Web App │
│ FastMCP · Railway │ │ Vercel · pasal.id │
│ │ │ │
│ · search_laws │ │ · /search │
│ · get_pasal │ │ · /jelajahi │
│ · get_law_status │ │ · /peraturan/[type] │
│ · list_laws │ │ · /connect · /api │
└─────────┬───────────┘ └───────────────────────┘
│
▼ ┌───────────────────────┐
┌─────────────────────┐ │ Opus 4.6 Correction │
│ Claude / AI │ │ Agent · Railway │
│ Grounded answers │ │ │
│ with citations │ │ Verify · Auto-apply │
└─────────────────────┘ │ Parser improvement │
└───────────────────────┘
This isn't a weekend hack. Key engineering decisions:
websearch_to_tsquery → plainto_tsquery → ILIKE), capped candidate CTEs to prevent O(N) snippet generationapply_revision() SQL function in a single transaction (revision insert + node update + suggestion update)[^a-zA-Z0-9 ] stripped before tsquery to prevent injectionFOR UPDATE SKIP LOCKED prevents duplicate processing in the scraper pipeline| Tool | Description |
|------|-------------|
| search_laws | Full-text keyword search across all legal provisions with Indonesian stemming |
| get_pasal | Get the exact text of a specific article (Pasal) by law and number |
| get_law_status | Check if a law is in force, amended, or revoked with full amendment chain |
| list_laws | Browse available regulations with type, year, and status filters |
| Layer | Technology |
|-------|-----------|
| Frontend | Next.js 16 (App Router), React 19, TypeScript, Tailwind v4, shadcn/ui |
| Database | Supabase (PostgreSQL FTS with indonesian stemmer + pg_trgm) |
| MCP Server | Python + FastMCP