Complete production implementation with shell+adapter architecture, 13 MCP tools, SQLite FTS5 search, and multi-source ingestion pipeline. Ingestion fetches from UCI mirror, UNODC SHERLOC PDFs, and Knesset mobile PDFs (135 provisions, 33 definitions). 3 acts with full text, 7 acts metadata-only due to gov.il/nevo.co.il access restrictions. Knesset OData API used for metadata enrichment. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3.1 KiB
3.1 KiB
Israel Law MCP Server -- Developer Guide
Git Workflow
- Never commit directly to
main. Always create a feature branch and open a Pull Request. - Branch protection requires: verified signatures, PR review, and status checks to pass.
- Use conventional commit prefixes:
feat:,fix:,chore:,docs:, etc.
Project Overview
Israel Law MCP server providing bilingual (HE/EN) Israeli legislation search via Model Context Protocol. Strategy A deployment (Vercel, bundled SQLite DB).
Architecture
- Transport: Dual-channel -- stdio (npm package) + Streamable HTTP (Vercel serverless)
- Database: SQLite + FTS5 via
@ansvar/mcp-sqlite(WASM-compatible, no WAL mode) - Entry points:
src/index.ts(stdio),api/mcp.ts(Vercel HTTP) - Tool registry:
src/tools/registry.ts-- shared between both transports - Capability gating:
src/capabilities.ts-- detects available DB tables at runtime
Key Conventions
- All database queries use parameterized statements (never string interpolation)
- FTS5 queries go through
buildFtsQueryVariants()with primary + fallback strategy - User input is sanitized via
sanitizeFtsInput()before FTS5 queries - Every tool returns
ToolResponse<T>withresults+_metadata(freshness, disclaimer) - Tool descriptions are written for LLM agents -- explain WHEN and WHY to use each tool
- Capability-gated tools only appear in
tools/listwhen their DB tables exist
Testing
- Unit tests:
tests/(vitest, in-memory SQLite fixtures) - Contract tests:
__tests__/contract/golden.test.tswithfixtures/golden-tests.json - Nightly mode:
CONTRACT_MODE=nightlyenables network assertions - Run:
npm test(unit),npm run test:contract(golden),npm run validate(both)
Database
- Schema defined inline in
scripts/build-db.ts - Journal mode: DELETE (not WAL -- required for Vercel serverless)
- Runtime: copied to
/tmp/database.dbon Vercel cold start - Metadata:
db_metadatatable stores tier, schema_version, built_at, builder
Data Pipeline
scripts/ingest.ts-> fetches from gov.il / Knesset / Nevo -> JSON seed files indata/seed/scripts/build-db.ts-> seed JSON -> SQLite database indata/database.dbscripts/drift-detect.ts-> verifies upstream content hasn't changed
Data Source
- Knesset Legislation Database (knesset.gov.il) -- The Knesset (Israeli Parliament)
- gov.il Legal Information -- Government of Israel (English translations)
- License: Government Open Data
- Languages: Hebrew (he) is authoritative; English (en) translations are unofficial
- Coverage: Primary legislation, Basic Laws, key regulations for cybersecurity and data protection
Citation Formats
- Standard: "Section N, [Law Name Year]" (e.g., "Section 1, Privacy Protection Law 1981")
- Pinpoint: "\u00a7N" (e.g., "\u00a71")
- Hebrew: "\u05e1\u05e2\u05d9\u05e3 N" (se'if N)
- Identifier pattern: Law name + year (e.g., "Privacy Protection Law 1981")
Deployment
- Vercel Strategy A: DB bundled in
data/database.db, included viavercel.jsonincludeFiles - npm package:
@ansvar/israel-law-mcpwith bin entry for stdio